mod ordered_map;
use crate::BraceConfig;
use ordered_map::OrderedMap;
#[derive(Debug)]
pub struct Node {
pub label: String,
pub children: OrderedMap<(String, usize), usize>,
pub is_leaf: bool,
pub is_trailing_sep: bool,
pub depth: usize,
}
pub fn build_trie(paths: &[String], sep: &str, config: &BraceConfig) -> (Vec<Node>, usize) {
let mut nodes = vec![Node {
label: String::new(),
children: OrderedMap::new(),
is_leaf: false,
is_trailing_sep: false,
depth: 0,
}];
let mut next_id = 0;
for path in paths {
let comps: Vec<String> = if config.allow_segment_split && !sep.is_empty() {
path.split(sep).map(|s| s.to_string()).collect()
} else {
let cur_path = path.as_str();
let mut components = Vec::new();
if !sep.is_empty() && cur_path.contains(sep) {
let parts: Vec<&str> = cur_path.split(sep).collect();
if parts.len() > 1 {
components.push(parts[0].to_string());
components.push(parts[1..].join(sep));
} else {
components.push(cur_path.to_string());
}
} else {
components.push(cur_path.to_string());
}
components
};
let mut cur = 0;
for (i, comp) in comps.iter().enumerate() {
let is_last = i + 1 == comps.len();
let key = if !config.deduplicate_inputs && is_last {
let id = next_id;
next_id += 1;
(comp.clone(), id)
} else {
(comp.clone(), 0) };
let child_idx = if let Some(&idx) = nodes[cur].children.get(&key) {
idx
} else {
let idx = nodes.len();
nodes[cur].children.insert(key, idx);
nodes.push(Node {
label: comp.clone(),
children: OrderedMap::new(),
is_leaf: false,
is_trailing_sep: false,
depth: nodes[cur].depth + 1,
});
idx
};
cur = child_idx;
if is_last {
nodes[cur].is_leaf = true;
nodes[cur].is_trailing_sep = comp.is_empty() && path.ends_with(sep);
}
}
}
(nodes, 0)
}