add Cowy util trait
This commit is contained in:
parent
2fc015fb89
commit
0425bf2cf3
|
@ -3,6 +3,7 @@ use std::fmt;
|
|||
|
||||
use itertools::Itertools;
|
||||
use crate::types::URIReference;
|
||||
use crate::util::Cowy;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Document {
|
||||
|
@ -42,7 +43,7 @@ impl Document {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_link<'a, U>(&mut self, uri: U, label: impl AsRef<str> + Into<String>) -> &mut Self
|
||||
pub fn add_link<'a, U>(&mut self, uri: U, label: impl Cowy<str>) -> &mut Self
|
||||
where
|
||||
U: TryInto<URIReference<'a>>,
|
||||
{
|
||||
|
@ -92,7 +93,7 @@ impl Document {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_heading(&mut self, level: HeadingLevel, text: impl AsRef<str> + Into<String>) -> &mut Self {
|
||||
pub fn add_heading(&mut self, level: HeadingLevel, text: impl Cowy<str>) -> &mut Self {
|
||||
let text = HeadingText::new_lossy(text);
|
||||
let heading = Heading {
|
||||
level,
|
||||
|
@ -182,7 +183,7 @@ impl Text {
|
|||
Self::default()
|
||||
}
|
||||
|
||||
pub fn new_lossy(line: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn new_lossy(line: impl Cowy<str>) -> Self {
|
||||
Self(lossy_escaped_line(line, SPECIAL_STARTS))
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +196,7 @@ pub struct Link {
|
|||
pub struct LinkLabel(String);
|
||||
|
||||
impl LinkLabel {
|
||||
pub fn from_lossy(line: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn from_lossy(line: impl Cowy<str>) -> Self {
|
||||
let line = strip_newlines(line);
|
||||
|
||||
LinkLabel(line)
|
||||
|
@ -210,7 +211,7 @@ pub struct Preformatted {
|
|||
pub struct PreformattedText(String);
|
||||
|
||||
impl PreformattedText {
|
||||
pub fn new_lossy(line: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn new_lossy(line: impl Cowy<str>) -> Self {
|
||||
Self(lossy_escaped_line(line, &[PREFORMATTED_TOGGLE_START]))
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +249,7 @@ impl Heading {
|
|||
pub struct HeadingText(String);
|
||||
|
||||
impl HeadingText {
|
||||
pub fn new_lossy(line: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn new_lossy(line: impl Cowy<str>) -> Self {
|
||||
let line = strip_newlines(line);
|
||||
|
||||
Self(lossy_escaped_line(line, &[HEADING_START]))
|
||||
|
@ -298,7 +299,7 @@ fn starts_with_any(s: &str, starts: &[&str]) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
fn lossy_escaped_line(line: impl AsRef<str> + Into<String>, escape_starts: &[&str]) -> String {
|
||||
fn lossy_escaped_line(line: impl Cowy<str>, escape_starts: &[&str]) -> String {
|
||||
let line_ref = line.as_ref();
|
||||
let contains_newline = line_ref.contains('\n');
|
||||
let has_special_start = starts_with_any(line_ref, escape_starts);
|
||||
|
@ -320,7 +321,7 @@ fn lossy_escaped_line(line: impl AsRef<str> + Into<String>, escape_starts: &[&st
|
|||
line
|
||||
}
|
||||
|
||||
fn strip_newlines(text: impl AsRef<str> + Into<String>) -> String {
|
||||
fn strip_newlines(text: impl Cowy<str>) -> String {
|
||||
if !text.as_ref().contains(&['\r', '\n'][..]) {
|
||||
return text.into();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use anyhow::*;
|
||||
use mime::Mime;
|
||||
use crate::Mime;
|
||||
use crate::util::Cowy;
|
||||
|
||||
|
||||
#[derive(Debug,Clone,PartialEq,Eq,Default)]
|
||||
pub struct Meta(String);
|
||||
|
@ -9,7 +11,7 @@ impl Meta {
|
|||
|
||||
/// Creates a new "Meta" string.
|
||||
/// Fails if `meta` contains `\n`.
|
||||
pub fn new(meta: impl AsRef<str> + Into<String>) -> Result<Self> {
|
||||
pub fn new(meta: impl Cowy<str>) -> Result<Self> {
|
||||
ensure!(!meta.as_ref().contains("\n"), "Meta must not contain newlines");
|
||||
ensure!(meta.as_ref().len() <= Self::MAX_LEN, "Meta must not exceed {} bytes", Self::MAX_LEN);
|
||||
|
||||
|
@ -20,7 +22,7 @@ impl Meta {
|
|||
/// Truncates `meta` to before:
|
||||
/// - the first occurrence of `\n`
|
||||
/// - the character that makes `meta` exceed `Meta::MAX_LEN`
|
||||
pub fn new_lossy(meta: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn new_lossy(meta: impl Cowy<str>) -> Self {
|
||||
let meta = meta.as_ref();
|
||||
let truncate_pos = meta.char_indices().position(|(i, ch)| {
|
||||
let is_newline = ch == '\n';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use anyhow::*;
|
||||
use crate::types::{ResponseHeader, Body, Mime, Document};
|
||||
use crate::util::Cowy;
|
||||
use crate::GEMINI_MIME;
|
||||
|
||||
pub struct Response {
|
||||
|
@ -19,12 +20,12 @@ impl Response {
|
|||
Self::success(&GEMINI_MIME).with_body(document)
|
||||
}
|
||||
|
||||
pub fn input(prompt: impl AsRef<str> + Into<String>) -> Result<Self> {
|
||||
pub fn input(prompt: impl Cowy<str>) -> Result<Self> {
|
||||
let header = ResponseHeader::input(prompt)?;
|
||||
Ok(Self::new(header))
|
||||
}
|
||||
|
||||
pub fn input_lossy(prompt: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn input_lossy(prompt: impl Cowy<str>) -> Self {
|
||||
let header = ResponseHeader::input_lossy(prompt);
|
||||
Self::new(header)
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ impl Response {
|
|||
Self::new(header)
|
||||
}
|
||||
|
||||
pub fn server_error(reason: impl AsRef<str> + Into<String>) -> Result<Self> {
|
||||
pub fn server_error(reason: impl Cowy<str>) -> Result<Self> {
|
||||
let header = ResponseHeader::server_error(reason)?;
|
||||
Ok(Self::new(header))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use anyhow::*;
|
||||
use mime::Mime;
|
||||
use crate::Mime;
|
||||
use crate::util::Cowy;
|
||||
use crate::types::{Status, Meta};
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
|
@ -9,14 +10,14 @@ pub struct ResponseHeader {
|
|||
}
|
||||
|
||||
impl ResponseHeader {
|
||||
pub fn input(prompt: impl AsRef<str> + Into<String>) -> Result<Self> {
|
||||
pub fn input(prompt: impl Cowy<str>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
status: Status::INPUT,
|
||||
meta: Meta::new(prompt).context("Invalid input prompt")?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn input_lossy(prompt: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn input_lossy(prompt: impl Cowy<str>) -> Self {
|
||||
Self {
|
||||
status: Status::INPUT,
|
||||
meta: Meta::new_lossy(prompt),
|
||||
|
@ -30,14 +31,14 @@ impl ResponseHeader {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn server_error(reason: impl AsRef<str> + Into<String>) -> Result<Self> {
|
||||
pub fn server_error(reason: impl Cowy<str>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
status: Status::PERMANENT_FAILURE,
|
||||
meta: Meta::new(reason).context("Invalid server error reason")?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn server_error_lossy(reason: impl AsRef<str> + Into<String>) -> Self {
|
||||
pub fn server_error_lossy(reason: impl Cowy<str>) -> Self {
|
||||
Self {
|
||||
status: Status::PERMANENT_FAILURE,
|
||||
meta: Meta::new_lossy(reason),
|
||||
|
|
16
src/util.rs
16
src/util.rs
|
@ -102,3 +102,19 @@ pub fn guess_mime_from_path<P: AsRef<Path>>(path: P) -> Mime {
|
|||
|
||||
mime.parse::<Mime>().unwrap_or(mime::APPLICATION_OCTET_STREAM)
|
||||
}
|
||||
|
||||
/// A convenience trait alias for `AsRef<T> + Into<T::Owned>`,
|
||||
/// most commonly used to accept `&str` or `String`:
|
||||
///
|
||||
/// `Cowy<str>` ⇔ `AsRef<str> + Into<String>`
|
||||
pub trait Cowy<T>
|
||||
where
|
||||
Self: AsRef<T> + Into<T::Owned>,
|
||||
T: ToOwned + ?Sized,
|
||||
{}
|
||||
|
||||
impl<C, T> Cowy<T> for C
|
||||
where
|
||||
C: AsRef<T> + Into<T::Owned>,
|
||||
T: ToOwned + ?Sized,
|
||||
{}
|
||||
|
|
Loading…
Reference in a new issue