use std::borrow::Cow;
use http::Method;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Methods<'a> {
Any,
Only(&'a [Method]),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum OwnedMethods {
One(Method),
Set(Cow<'static, [Method]>),
Any,
}
impl OwnedMethods {
#[must_use]
pub fn as_methods(&self) -> Methods<'_> {
match self {
Self::One(method) => Methods::Only(std::slice::from_ref(method)),
Self::Set(methods) => Methods::Only(methods),
Self::Any => Methods::Any,
}
}
}
impl From<Method> for OwnedMethods {
fn from(method: Method) -> Self {
Self::One(method)
}
}
impl From<&'static [Method]> for OwnedMethods {
fn from(methods: &'static [Method]) -> Self {
Self::Set(Cow::Borrowed(methods))
}
}
impl<const N: usize> From<&'static [Method; N]> for OwnedMethods {
fn from(methods: &'static [Method; N]) -> Self {
Self::Set(Cow::Borrowed(methods))
}
}
impl From<Vec<Method>> for OwnedMethods {
fn from(methods: Vec<Method>) -> Self {
Self::Set(Cow::Owned(methods))
}
}
impl From<Cow<'static, [Method]>> for OwnedMethods {
fn from(methods: Cow<'static, [Method]>) -> Self {
Self::Set(methods)
}
}
impl From<Methods<'static>> for OwnedMethods {
fn from(methods: Methods<'static>) -> Self {
match methods {
Methods::Any => Self::Any,
Methods::Only(methods) => Self::Set(Cow::Borrowed(methods)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_single_method_converts_without_allocating() {
let methods = OwnedMethods::from(Method::GET);
assert_eq!(methods, OwnedMethods::One(Method::GET));
assert_eq!(methods.as_methods(), Methods::Only(&[Method::GET]));
}
#[test]
fn slices_arrays_and_vectors_convert_to_sets() {
let expected = Methods::Only(&[Method::GET, Method::POST][..]);
let slice: &'static [Method] = &[Method::GET, Method::POST];
assert_eq!(OwnedMethods::from(slice).as_methods(), expected);
assert_eq!(
OwnedMethods::from(&[Method::GET, Method::POST]).as_methods(),
expected
);
assert_eq!(
OwnedMethods::from(vec![Method::GET, Method::POST]).as_methods(),
expected
);
}
#[test]
fn methods_values_convert_losslessly() {
assert_eq!(OwnedMethods::from(Methods::Any), OwnedMethods::Any);
assert_eq!(OwnedMethods::Any.as_methods(), Methods::Any);
assert_eq!(
OwnedMethods::from(Methods::Only(&[Method::PUT])).as_methods(),
Methods::Only(&[Method::PUT])
);
}
}