use std::ops::Bound;
use super::Index;
use crate::paths::ObjectPath;
impl Index {
pub fn all_paths(&self) -> impl Iterator<Item = ObjectPath<'_>> {
self.objects.keys().map(|path| path.as_str())
}
pub fn paths_starting_with<'a>(
&'a self,
path: ObjectPath<'a>,
) -> impl Iterator<Item = ObjectPath<'a>> + 'a {
self.objects
.range::<String, _>((Bound::Included(path.to_string()), Bound::Unbounded))
.map(|(path, _)| path.as_str())
.take_while(move |p| p.starts_with(path))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::PropertyValue;
use crate::meta_data::MetaData;
use crate::meta_data::ObjectMetaData;
use crate::meta_data::RawDataIndex;
use crate::meta_data::Segment;
use crate::meta_data::ToC;
fn generate_test_index() -> Index {
let mut index = Index::new();
let segment = Segment {
toc: ToC::from_u32(0x2),
next_segment_offset: 20000,
raw_data_offset: 20,
meta_data: Some(MetaData {
objects: vec![
ObjectMetaData {
path: "/'group'".to_string(),
properties: vec![("Prop".to_string(), PropertyValue::I32(-51))],
raw_data_index: RawDataIndex::None,
},
ObjectMetaData {
path: "/'group'/'ch1'".to_string(),
properties: vec![("Prop1".to_string(), PropertyValue::I32(-1))],
raw_data_index: RawDataIndex::None,
},
ObjectMetaData {
path: "/'group'/'ch2'".to_string(),
properties: vec![("Prop2".to_string(), PropertyValue::I32(-2))],
raw_data_index: RawDataIndex::None,
},
],
}),
};
index.add_segment(segment).unwrap();
let segment = Segment {
toc: ToC::from_u32(0x2),
next_segment_offset: 20000,
raw_data_offset: 20,
meta_data: Some(MetaData {
objects: vec![
ObjectMetaData {
path: "/'group2'".to_string(),
properties: vec![("Prop".to_string(), PropertyValue::I32(-51))],
raw_data_index: RawDataIndex::None,
},
ObjectMetaData {
path: "/'group2'/'ch1'".to_string(),
properties: vec![("Prop1".to_string(), PropertyValue::I32(-1))],
raw_data_index: RawDataIndex::None,
},
ObjectMetaData {
path: "/'group2'/'ch2'".to_string(),
properties: vec![("Prop2".to_string(), PropertyValue::I32(-2))],
raw_data_index: RawDataIndex::None,
},
ObjectMetaData {
path: "/'group3'".to_string(),
properties: vec![("Prop".to_string(), PropertyValue::I32(-51))],
raw_data_index: RawDataIndex::None,
},
],
}),
};
index.add_segment(segment).unwrap();
index
}
#[test]
fn test_all_paths() {
let index = generate_test_index();
let paths: Vec<_> = index.all_paths().collect();
assert_eq!(
paths,
vec![
ObjectPath::from("/'group'"),
ObjectPath::from("/'group'/'ch1'"),
ObjectPath::from("/'group'/'ch2'"),
ObjectPath::from("/'group2'"),
ObjectPath::from("/'group2'/'ch1'"),
ObjectPath::from("/'group2'/'ch2'"),
ObjectPath::from("/'group3'"),
]
);
}
#[test]
fn test_paths_starting_with() {
let index = generate_test_index();
let paths: Vec<_> = index
.paths_starting_with(&ObjectPath::from("/'group2'"))
.collect();
assert_eq!(
paths,
vec![
ObjectPath::from("/'group2'"),
ObjectPath::from("/'group2'/'ch1'"),
ObjectPath::from("/'group2'/'ch2'"),
]
);
}
#[test]
fn test_paths_starting_with_no_match() {
let index = generate_test_index();
let paths: Vec<_> = index
.paths_starting_with(&ObjectPath::from("/'group4'"))
.collect();
assert!(paths.is_empty());
}
}