use std::collections::BTreeMap;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct RangeMode {
pub(crate) direct: bool,
pub(crate) json_decoded: bool,
pub(crate) destructured: bool,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct RangeModes {
modes: BTreeMap<String, RangeMode>,
}
impl RangeModes {
pub(crate) fn mode(&self, path: &str) -> RangeMode {
self.modes.get(path).copied().unwrap_or_default()
}
pub(crate) fn mark_direct(&mut self, path: &str) {
self.entry(path, |mode| mode.direct = true);
}
pub(crate) fn mark_json_decoded(&mut self, path: &str) {
self.entry(path, |mode| mode.json_decoded = true);
}
pub(crate) fn mark_destructured(&mut self, path: &str) {
self.entry(path, |mode| mode.destructured = true);
}
pub(crate) fn merge(&mut self, other: &RangeModes) {
for (path, mode) in &other.modes {
let merged = self.modes.entry(path.clone()).or_default();
merged.direct |= mode.direct;
merged.json_decoded |= mode.json_decoded;
merged.destructured |= mode.destructured;
}
}
pub(crate) fn iter(&self) -> impl Iterator<Item = (&str, RangeMode)> {
self.modes.iter().map(|(path, mode)| (path.as_str(), *mode))
}
pub(crate) fn map_value_paths<F>(&mut self, map: &mut F)
where
F: FnMut(&str) -> String,
{
let mut mapped = RangeModes::default();
for (path, mode) in &self.modes {
let target = map(path);
let merged = mapped.modes.entry(target).or_default();
merged.direct |= mode.direct;
merged.json_decoded |= mode.json_decoded;
merged.destructured |= mode.destructured;
}
*self = mapped;
}
fn entry(&mut self, path: &str, set: impl FnOnce(&mut RangeMode)) {
if path.trim().is_empty() {
return;
}
set(self.modes.entry(path.to_string()).or_default());
}
}