use super::{super::normal::*, path::*, segment::*};
use {
depiction::*,
kutil::std::{immutable::*, iter::*},
std::{
fmt::{self, Write},
io,
},
};
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct PathRepresentation {
pub segments: Vec<PathSegment<ByteString>>,
}
impl PathRepresentation {
pub fn find<'own, AnnotatedT>(
ancestor: &'own Variant<AnnotatedT>,
descendent: &'own Variant<AnnotatedT>,
) -> Option<Self>
where
AnnotatedT: Default,
{
let route = Path::find(ancestor, descendent)?;
let path = route.into_representation();
if !path.segments.is_empty() { Some(path) } else { None }
}
pub fn push_list_index(&mut self, index: usize) {
self.segments.push(PathSegment::ListIndex(index));
}
pub fn push_map_key(&mut self, key: ByteString) {
self.segments.push(PathSegment::MapKey(key));
}
pub fn extend(&mut self, other: PathRepresentation) {
self.segments.extend(other.segments);
}
}
impl Depict for PathRepresentation {
fn depict<WriteT>(&self, writer: &mut WriteT, context: &DepictionContext) -> io::Result<()>
where
WriteT: io::Write,
{
for (segment, first) in IterateWithFirst::new(&self.segments) {
if !first && matches!(segment, PathSegment::MapKey(_)) {
context.theme.write_delimiter(writer, '.')?;
}
segment.depict(writer, context)?;
}
Ok(())
}
}
impl fmt::Display for PathRepresentation {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
for (segment, first) in IterateWithFirst::new(&self.segments) {
if !first && matches!(segment, PathSegment::MapKey(_)) {
formatter.write_char('.')?;
}
fmt::Display::fmt(segment, formatter)?;
}
Ok(())
}
}