use crate::segment::Segment;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Variable<'a> {
field: &'a str,
sub: &'a str,
}
impl<'a> Variable<'a> {
pub(crate) fn new(field: &'a str, sub: &'a str) -> Self {
Self { field, sub }
}
#[must_use]
pub fn field_path(&self) -> &'a str {
self.field
}
#[must_use]
pub fn segments(&self) -> SegmentIter<'a> {
SegmentIter { rest: Some(self.sub) }
}
pub(crate) fn sub(&self) -> &'a str {
self.sub
}
}
#[derive(Debug, Clone)]
pub struct SegmentIter<'a> {
rest: Option<&'a str>,
}
impl<'a> Iterator for SegmentIter<'a> {
type Item = Segment<'a>;
fn next(&mut self) -> Option<Self::Item> {
let rest = self.rest?;
let seg = if let Some(idx) = rest.as_bytes().iter().position(|&b| b == b'/') {
let (seg, after) = rest.split_at(idx);
self.rest = Some(&after[1..]);
seg
} else {
self.rest = None;
rest
};
Some(match seg {
"*" => Segment::Single,
"**" => Segment::Rest,
other => Segment::Literal(other),
})
}
}