use egui::{CollapsingResponse, Response, Ui};
pub enum DisplayResponse {
CollapsingResponse(CollapsingResponse<()>),
GenericResponse(Response),
}
#[derive(Debug)]
pub struct PathPart {
uri: String,
is_dir: bool,
childs: Vec<PathPart>,
is_root: bool,
}
impl PathPart {
pub fn is_directory(&self) -> bool {
self.is_dir
}
pub fn new_root(uri: impl ToString) -> Self {
let mut out = Self::new(uri, false);
out.is_root = true;
out
}
pub fn new(uri: impl ToString, is_endpoint: bool) -> Self {
Self {
uri: uri.to_string(),
is_dir: !is_endpoint,
childs: vec![],
is_root: false,
}
}
pub fn add_child(&mut self, child: PathPart) {
self.childs.push(child);
}
pub fn merge(&mut self, tree: PathPart) {
if let Some(c) = self.childs.iter_mut().find(|x| x.uri == tree.uri) {
for nchild in tree.childs {
c.merge(nchild);
}
} else {
self.childs.push(tree)
}
}
fn ui(&self, ui: &mut Ui) -> DisplayResponse {
let heading = if self.uri.is_empty() { "/" } else { &self.uri };
if self.is_directory() {
DisplayResponse::CollapsingResponse(ui.collapsing(heading.to_string(), |ui| {
for child in &self.childs {
child.ui(ui);
}
}))
} else {
DisplayResponse::GenericResponse(ui.label(heading))
}
}
}
#[derive(Debug)]
pub struct Paths {
inner: PathPart,
}
impl Paths {
pub fn new() -> Self {
Self {
inner: PathPart::new_root("History"),
}
}
pub fn merge(&mut self, ntree: PathPart) {
if ntree.uri.is_empty() {
for child in ntree.childs {
self.merge(child);
}
} else {
self.inner.merge(ntree);
}
}
pub fn sort(&mut self) {
self.inner.childs.sort_by_key(|x| x.uri.to_string());
}
pub fn _childs(&self) -> &Vec<PathPart> {
&self.inner.childs
}
pub fn ui(&self, ui: &mut Ui) -> DisplayResponse {
self.inner.ui(ui)
}
}
pub fn new_tree_from_uri(uri: &str) -> PathPart {
let mut nodes = vec![];
let parts = uri.split('/').collect::<Vec<&str>>();
for (idx, part) in parts.iter().enumerate() {
let node = PathPart::new(part, idx == (parts.len() - 1));
nodes.push(node);
}
let mut parent;
let mut child;
while nodes.len() > 1 {
child = nodes.pop().unwrap();
parent = nodes.pop().unwrap();
parent.add_child(child);
nodes.push(parent)
}
parent = nodes.pop().unwrap();
parent
}