use crate::header::{Header, HeaderValue, HeaderName}; use crate::error::HTTPError; use crate::method::Method; use crate::status::Status; use crate::uri::{QueryMap, QueryFragment, Authority, Path, Scheme, URI}; use crate::version::Version; use crate::response::Response; use crate::request::Request; use std::convert::{From, TryFrom}; use std::str::FromStr; use std::borrow::Cow; pub trait Parse where Self: Sized { fn parse(s: impl Into) -> Self; } pub trait TryParse where Self: Sized { fn try_parse(s: impl Into) -> Result; } macro_rules! try_into { ($type:ty, $struct:ty) => { impl TryFrom<$type> for $struct { type Error = HTTPError; fn try_from(value: $type) -> Result { Self::try_parse(value) } } }; } macro_rules! try_into_struct { ($struct:ty) => { impl From<$struct> for String { fn from(value: $struct) -> Self { value.to_string() } } try_into!(String, $struct); try_into!(&String, $struct); try_into!(&str, $struct); try_into!(Cow<'_, str>, $struct); }; } try_into_struct!(Header); try_into_struct!(HeaderName); try_into_struct!(QueryMap); try_into_struct!(QueryFragment); try_into_struct!(Authority); try_into_struct!(Path); try_into_struct!(URI); try_into_struct!(Status); macro_rules! try_into_res { ($type:ty, $struct:ty) => { impl TryFrom<$type> for $struct { type Error = HTTPError; fn try_from(value: $type) -> Result { Self::try_parse(value) } } }; } macro_rules! try_into_struct_res { ($struct:ty) => { impl From<$struct> for String { fn from(value: $struct) -> Self { value.to_string() } } try_into_res!(String, $struct); try_into_res!(&String, $struct); try_into_res!(&str, $struct); try_into_res!(Cow<'_, str>, $struct); }; } try_into_struct_res!(Request); try_into_struct_res!(Response); macro_rules! into_struct { ($struct:ty) => { impl From for $struct where T: Into { fn from(value: T) -> Self { Self::parse(value) } } }; } into_struct!(Scheme); into_struct!(HeaderValue); into_struct!(Method); into_struct!(Version);