use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub struct PatternParts {
parts: Vec<String>,
}
impl fmt::Display for PatternParts {
fn fmt(
&self,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
match self.parts.len() {
1 => write!(f, "{}", &self.parts[0]),
2 => write!(f, "{}/{}", &self.parts[0], &self.parts[1]),
_ => write!(
f,
"{}/{}/{}",
&self.parts[0], &self.parts[1], &self.parts[2]
),
}
}
}
impl Default for PatternParts {
fn default() -> Self {
Self {
parts: vec![String::new()],
}
}
}
#[cfg(test)]
impl TryFrom<&[&str]> for PatternParts {
type Error = &'static str;
fn try_from(a: &[&str]) -> Result<Self, Self::Error> {
if a.is_empty() {
return Err("invalid empty parts array");
}
let parts = a.iter().map(|s| (*s).into()).collect();
Ok(Self { parts })
}
}
impl PatternParts {
pub fn push(
&mut self,
c: char,
) {
self.parts.last_mut().unwrap().push(c);
}
pub fn is_between_slashes(&self) -> bool {
self.parts.len() == 2
}
pub fn add_part(&mut self) {
self.parts.push(String::new());
}
pub fn is_empty(&self) -> bool {
self.core().is_empty()
}
pub fn core(&self) -> &str {
if self.parts.len() > 1 {
&self.parts[1]
} else {
&self.parts[0]
}
}
pub fn mode(&self) -> Option<&String> {
if self.parts.len() > 1 {
self.parts.first()
} else {
None
}
}
pub fn flags(&self) -> Option<&str> {
if self.parts.len() > 2 {
self.parts.get(2).map(|s| s.as_str())
} else {
None
}
}
}