use http::HeaderValue;
use smallvec::SmallVec;
pub mod method_allow_list {
use http::Method;
use super::MethodAllowList;
pub struct IntoIter {
methods: smallvec::IntoIter<[Method; 5]>,
}
impl Iterator for IntoIter {
type Item = Method;
fn next(&mut self) -> Option<Self::Item> {
self.methods.next()
}
}
impl IntoIterator for MethodAllowList {
type Item = Method;
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
methods: self.methods.into_iter(),
}
}
}
}
use crate::http::Method;
#[derive(Debug, Clone)]
pub enum AllowedMethods {
Some(MethodAllowList),
All,
}
impl AllowedMethods {
pub fn allow_header_value(&self) -> Option<HeaderValue> {
match self {
AllowedMethods::Some(m) => m.allow_header_value(),
AllowedMethods::All => None,
}
}
}
#[derive(Debug, Clone)]
pub struct MethodAllowList {
methods: SmallVec<[Method; 5]>,
}
impl FromIterator<Method> for MethodAllowList {
fn from_iter<I: IntoIterator<Item = Method>>(iter: I) -> Self {
Self {
methods: SmallVec::from_iter(iter),
}
}
}
impl MethodAllowList {
pub fn iter(&self) -> impl Iterator<Item = &Method> {
self.methods.iter()
}
pub fn len(&self) -> usize {
self.methods.len()
}
pub fn is_empty(&self) -> bool {
self.methods.is_empty()
}
pub fn allow_header_value(&self) -> Option<HeaderValue> {
if self.methods.is_empty() {
None
} else {
let allow_header = join(&mut self.methods.iter().map(|method| method.as_str()), ",");
Some(
HeaderValue::from_str(&allow_header)
.expect("Failed to assemble `Allow` header value"),
)
}
}
}
fn join<'a, I>(iter: &mut I, separator: &str) -> String
where
I: Iterator<Item = &'a str>,
{
use std::fmt::Write;
match iter.next() {
None => String::new(),
Some(first_elt) => {
let mut result = String::with_capacity(separator.len() * iter.size_hint().0);
write!(&mut result, "{}", first_elt).unwrap();
iter.for_each(|element| {
result.push_str(separator);
write!(&mut result, "{}", element).unwrap();
});
result
}
}
}
impl From<MethodAllowList> for AllowedMethods {
fn from(methods: MethodAllowList) -> Self {
Self::Some(methods)
}
}