Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions lib/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,17 @@ impl Node {
}

pub fn create_hierarchy(&mut self, path: &str) -> &mut Node {
self.create_hierarchy_from_iter(path.split("."))
}

pub(crate) fn create_hierarchy_from_iter<S, I>(&mut self, path: I) -> &mut Node
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
let mut ptr = self;
for name in path.split('.') {
for name in path {
let name = name.as_ref();
if ptr.get(name).is_none() {
ptr.add(Node::section(name));
}
Expand All @@ -218,19 +227,6 @@ impl Node {
ptr
}

pub fn create_record_hierarchy(&mut self, path: &str) -> &mut Node {
match path.split_once(".") {
Some((record, hierarchy)) => {
if self.get(record).is_none() {
self.add(Node::record(record));
}
let record_node = self.get_mut(record).expect("Record node should be present");
record_node.create_hierarchy(hierarchy)
}
None => self.create_hierarchy(path),
}
}

/// Returns an iterator over the node's children. The children nodes are sorted alphabetically.
///
/// # Examples
Expand Down
30 changes: 28 additions & 2 deletions lib/src/record/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::header::record_types;
use crate::node::Node;
use crate::node::NodeType;
#[cfg(not(feature = "std"))]
use alloc::{str, string::String, vec::Vec};
use alloc::{borrow::ToOwned, str, string::String, vec::Vec};
use log::debug;
#[cfg(feature = "std")]
use std::str;
Expand Down Expand Up @@ -60,6 +60,7 @@ impl Record {

let csv = str::from_utf8(layout)?;
let mut columns = Vec::new();
let mut current_path = Vec::new();

for (i, line) in csv.lines().enumerate() {
if i == 0 {
Expand All @@ -85,7 +86,32 @@ impl Record {
if entry.name.is_empty() {
continue;
}
let node = record_root.create_record_hierarchy(&entry.name);

let mut segments = entry.name.split(".");
let Some(top) = segments.next() else {
continue;
};

if !top.is_empty() {
// Absolute path
current_path.clear();
current_path.push(top.to_owned());

if record_root.get(top).is_none() {
// Top-level is assumed to be the record name
record_root.add(Node::record(top));
}
}

for segment in segments {
if segment.is_empty() {
let _ = current_path.pop();
} else {
current_path.push(segment.to_owned());
}
}

let node = record_root.create_hierarchy_from_iter(&current_path);
node.description = entry.description;
if let Some(value) = self.read_field(offset * 8 + entry.offset, entry.size) {
node.kind = NodeType::Field { value }
Expand Down
6 changes: 4 additions & 2 deletions lib/tests/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@ fn merge() {
#[test]
fn merge_record() {
let mut root0 = Node::root();
root0.create_record_hierarchy("foo.bar.reg0");
root0.add(Node::record("foo"));
root0.create_hierarchy("foo.bar.reg0");
root0.create_hierarchy("some.bar.reg1");

let mut root1 = Node::root();
root1.create_record_hierarchy("foo.bar.reg1");
root1.add(Node::record("foo"));
root1.create_hierarchy("foo.bar.reg1");

root0.merge(root1);

Expand Down
38 changes: 37 additions & 1 deletion lib/tests/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ foo.bar;4;8;;0";

let root = record.decode_with_csv(csv.as_bytes(), 0).unwrap();
let section = root.get_by_path("foo").unwrap();
assert_eq!(section.kind, NodeType::Section);
assert_eq!(section.kind, NodeType::Record);
let field = root.get_by_path("foo.bar").unwrap();
assert_eq!(field.kind, NodeType::Field { value: 0x18 });
let field = root.get_by_path("foo.bar.baz").unwrap();
Expand All @@ -36,6 +36,42 @@ foo.bar;4;8;;0";
);
}

#[test]
fn relative_paths() {
let record = Record {
header: Header::default(),
data: vec![
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D,
0x8E, 0x8F,
],
};

let csv = "name;offset;size;description;bitfield
foo;0;128;;0
.aaa;8;8;;0
.bbb;16;8;;0
..ccc;24;8;;0
foo.ddd.eee;32;8;;0
...ddd;40;8;;0
..fff;48;8;;0";

let root = record.decode_with_csv(csv.as_bytes(), 0).unwrap();
let section = root.get_by_path("foo").unwrap();
assert_eq!(section.kind, NodeType::Record);
let field = root.get_by_path("foo.aaa").unwrap();
assert_eq!(field.kind, NodeType::Field { value: 0x81 });
let field = root.get_by_path("foo.aaa.bbb").unwrap();
assert_eq!(field.kind, NodeType::Field { value: 0x82 });
let field = root.get_by_path("foo.aaa.ccc").unwrap();
assert_eq!(field.kind, NodeType::Field { value: 0x83 });
let field = root.get_by_path("foo.ddd.eee").unwrap();
assert_eq!(field.kind, NodeType::Field { value: 0x84 });
let field = root.get_by_path("foo.ddd").unwrap();
assert_eq!(field.kind, NodeType::Field { value: 0x85 });
let field = root.get_by_path("foo.fff").unwrap();
assert_eq!(field.kind, NodeType::Field { value: 0x86 });
}

#[test]
fn decode() {
let mut cm = CollateralManager::file_system_tree(Path::new(COLLATERAL_TREE_PATH)).unwrap();
Expand Down