use std::{iter::FusedIterator, mem::take};
#[derive(Debug)]
pub struct RemainingPath(pub(crate) Option<String>);
impl RemainingPath {
pub fn peek(&self) -> Option<String> {
let Some((next_element, _)) = self.0.as_ref()?.split_once('/') else {
return Some(self.0.clone().unwrap());
};
Some(next_element.to_string())
}
pub fn peek_back(&self) -> Option<String> {
let Some((_, next_element)) = self.0.as_ref()?.rsplit_once('/') else {
return Some(self.0.clone().unwrap());
};
Some(next_element.to_string())
}
}
impl Iterator for RemainingPath {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
let Some((next_element, remaining_path)) = self.0.as_ref()?.split_once('/') else {
return take(&mut self.0);
};
let remaining_path = remaining_path.to_string();
let next_element = next_element.to_string();
self.0 = if next_element.is_empty() {
None
} else {
Some(remaining_path.to_string())
};
Some(next_element)
}
}
impl FusedIterator for RemainingPath {}
impl DoubleEndedIterator for RemainingPath {
fn next_back(&mut self) -> Option<Self::Item> {
let Some((remaining_path, next_element)) = self.0.as_ref()?.rsplit_once('/') else {
return take(&mut self.0);
};
let remaining_path = remaining_path.to_string();
let next_element = next_element.to_string();
self.0 = if next_element.is_empty() {
None
} else {
Some(remaining_path.to_string())
};
Some(next_element)
}
}