use std::str::FromStr;
use headers::Header;
use iri_string::types::{UriReferenceStr, UriReferenceString};
use crate::field::rules::flat_csv::{Comma, FlatCsv};
mod rel;
mod relation_type;
mod target;
mod value;
pub use rel::*;
pub use relation_type::*;
pub use target::*;
pub use value::*;
#[derive(Debug, Clone)]
pub struct Link<TargetUriRef = UriReferenceString> {
pub values: Vec<LinkValue<TargetUriRef>>,
}
impl<TargetUriRef> Default for Link<TargetUriRef> {
#[inline]
fn default() -> Self {
Self { values: vec![] }
}
}
impl<TargetUriRef> Header for Link<TargetUriRef>
where
TargetUriRef: for<'a> TryFrom<&'a str> + AsRef<UriReferenceStr>,
{
fn name() -> &'static headers::HeaderName {
&http::header::LINK
}
fn decode<'i, I>(values: &mut I) -> Result<Self, headers::Error>
where
Self: Sized,
I: Iterator<Item = &'i headers::HeaderValue>,
{
let link_values = values
.flat_map(|value| FlatCsv::<Comma>::from(value).iter())
.map(LinkValue::<TargetUriRef>::from_str)
.collect::<Result<Vec<LinkValue<TargetUriRef>>, _>>()
.map_err(|_| headers::Error::invalid())?;
Ok(Self {
values: link_values,
})
}
#[inline]
fn encode<E: Extend<headers::HeaderValue>>(&self, values: &mut E) {
values.extend(self.values.iter().map(|v| v.into()));
}
}