use std::fmt;
pub trait ViewPatternParams: Sized + Send + 'static {
const PATTERN: &'static str;
#[doc(hidden)]
fn from_decoded_match(decoded_match: DecodedMatch) -> Result<Self, MissingParamError>;
#[doc(hidden)]
fn into_decoded_match(self) -> DecodedMatch;
}
pub trait ApiPatternParams: Sized + Send + 'static {
const PATTERN: &'static str;
#[doc(hidden)]
fn from_decoded_match(decoded_match: DecodedMatch) -> Result<Self, MissingParamError>;
#[doc(hidden)]
fn into_decoded_match(self) -> DecodedMatch;
}
#[doc(hidden)]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DecodedMatch {
pub(crate) params: Vec<(String, String)>,
pub(crate) splat_values: Vec<String>,
}
impl DecodedMatch {
pub fn new(params: Vec<(String, String)>, splat_values: Vec<String>) -> Self {
Self {
params,
splat_values,
}
}
pub fn take_param(&mut self, name: &'static str) -> Result<String, MissingParamError> {
let index = self
.params
.iter()
.position(|(param_name, _)| param_name == name)
.ok_or(MissingParamError { name })?;
Ok(self.params.swap_remove(index).1)
}
pub fn take_splat_values(&mut self) -> Vec<String> {
std::mem::take(&mut self.splat_values)
}
}
#[doc(hidden)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MissingParamError {
name: &'static str,
}
impl fmt::Display for MissingParamError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"the matched pattern has no {:?} param",
self.name
)
}
}
impl std::error::Error for MissingParamError {}