use std::borrow::Cow;
use matchit::{Params, ParamsIter};
use percent_encoding::percent_decode_str;
use crate::request::path::errors::DecodeError;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct RawPathParams<'server, 'request>(Params<'server, 'request>);
impl<'server, 'request> RawPathParams<'server, 'request> {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn get(&self, key: impl AsRef<str>) -> Option<&'request str> {
self.0.get(key)
}
pub fn iter(&self) -> RawPathParamsIter<'_, 'server, 'request> {
RawPathParamsIter(self.0.iter())
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl<'k, 'v> From<Params<'k, 'v>> for RawPathParams<'k, 'v> {
fn from(value: Params<'k, 'v>) -> Self {
Self(value)
}
}
pub struct RawPathParamsIter<'extractor, 'server, 'request>(
ParamsIter<'extractor, 'server, 'request>,
);
impl<'extractor, 'server, 'request> Iterator for RawPathParamsIter<'extractor, 'server, 'request> {
type Item = (&'server str, EncodedParamValue<'request>);
fn next(&mut self) -> Option<Self::Item> {
self.0
.next()
.map(|(key, value)| (key, EncodedParamValue::new(value)))
}
}
#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub struct EncodedParamValue<'request>(&'request str);
impl<'request> EncodedParamValue<'request> {
fn new(s: &'request str) -> Self {
Self(s)
}
pub fn decode(&self) -> Result<Cow<'request, str>, DecodeError> {
percent_decode_str(self.0)
.decode_utf8()
.map_err(|e| DecodeError {
invalid_raw_segment: self.0.to_owned(),
source: e,
})
}
pub fn as_str(&self) -> &'request str {
self.0
}
}