use mig_assembly::assembler::{AssembledGroup, AssembledTree};
use mig_types::segment::OwnedSegment;
pub fn tree_to_owned_segments(tree: &AssembledTree) -> Vec<OwnedSegment> {
let mut segments = Vec::new();
let mut number = 1u32;
for seg in &tree.segments[..tree.post_group_start] {
segments.push(OwnedSegment {
id: seg.tag.clone(),
elements: seg.elements.clone(),
segment_number: number,
});
number += 1;
}
for (i, group) in tree.groups.iter().enumerate() {
if let Some(inter_segs) = tree.inter_group_segments.get(&i) {
for seg in inter_segs {
segments.push(OwnedSegment {
id: seg.tag.clone(),
elements: seg.elements.clone(),
segment_number: number,
});
number += 1;
}
}
collect_group_segments(group, &mut segments, &mut number);
}
for seg in &tree.segments[tree.post_group_start..] {
segments.push(OwnedSegment {
id: seg.tag.clone(),
elements: seg.elements.clone(),
segment_number: number,
});
number += 1;
}
segments
}
fn collect_group_segments(
group: &AssembledGroup,
segments: &mut Vec<OwnedSegment>,
number: &mut u32,
) {
for rep in &group.repetitions {
for seg in &rep.segments {
segments.push(OwnedSegment {
id: seg.tag.clone(),
elements: seg.elements.clone(),
segment_number: *number,
});
*number += 1;
}
for child_group in &rep.child_groups {
collect_group_segments(child_group, segments, number);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use mig_assembly::assembler::{AssembledGroupInstance, AssembledSegment};
use std::collections::BTreeMap;
fn seg(tag: &str, elements: Vec<Vec<&str>>) -> AssembledSegment {
AssembledSegment {
tag: tag.to_string(),
elements: elements
.into_iter()
.map(|e| e.into_iter().map(|s| s.to_string()).collect())
.collect(),
mig_number: None,
segment_number: None,
}
}
#[test]
fn test_empty_tree() {
let tree = AssembledTree {
segments: vec![],
groups: vec![],
post_group_start: 0,
inter_group_segments: BTreeMap::new(),
};
let result = tree_to_owned_segments(&tree);
assert!(result.is_empty());
}
#[test]
fn test_flat_segments_only() {
let tree = AssembledTree {
segments: vec![
seg("UNH", vec![vec!["1"], vec!["UTILMD"]]),
seg("UNT", vec![vec!["5"], vec!["1"]]),
],
groups: vec![],
post_group_start: 1,
inter_group_segments: BTreeMap::new(),
};
let result = tree_to_owned_segments(&tree);
assert_eq!(result.len(), 2);
assert_eq!(result[0].id, "UNH");
assert_eq!(result[0].segment_number, 1);
assert_eq!(result[1].id, "UNT");
assert_eq!(result[1].segment_number, 2);
}
#[test]
fn test_with_groups() {
let tree = AssembledTree {
segments: vec![seg("UNH", vec![vec!["1"]]), seg("UNT", vec![vec!["5"]])],
groups: vec![AssembledGroup {
group_id: "SG2".to_string(),
repetitions: vec![AssembledGroupInstance {
segments: vec![seg("NAD", vec![vec!["MS"]]), seg("CTA", vec![vec!["IC"]])],
child_groups: vec![],
entry_mig_number: None,
variant_mig_numbers: vec![],
skipped_segments: vec![],
skipped_positions: Vec::new(),
}],
}],
post_group_start: 1,
inter_group_segments: BTreeMap::new(),
};
let result = tree_to_owned_segments(&tree);
assert_eq!(result.len(), 4);
assert_eq!(result[0].id, "UNH");
assert_eq!(result[0].segment_number, 1);
assert_eq!(result[1].id, "NAD");
assert_eq!(result[1].segment_number, 2);
assert_eq!(result[2].id, "CTA");
assert_eq!(result[2].segment_number, 3);
assert_eq!(result[3].id, "UNT");
assert_eq!(result[3].segment_number, 4);
}
#[test]
fn test_nested_groups() {
let tree = AssembledTree {
segments: vec![seg("UNH", vec![vec!["1"]])],
groups: vec![AssembledGroup {
group_id: "SG4".to_string(),
repetitions: vec![AssembledGroupInstance {
segments: vec![seg("IDE", vec![vec!["24"]])],
child_groups: vec![AssembledGroup {
group_id: "SG5".to_string(),
repetitions: vec![AssembledGroupInstance {
segments: vec![seg("LOC", vec![vec!["Z16"]])],
child_groups: vec![],
entry_mig_number: None,
variant_mig_numbers: vec![],
skipped_segments: vec![],
skipped_positions: Vec::new(),
}],
}],
entry_mig_number: None,
variant_mig_numbers: vec![],
skipped_segments: vec![],
skipped_positions: Vec::new(),
}],
}],
post_group_start: 1,
inter_group_segments: BTreeMap::new(),
};
let result = tree_to_owned_segments(&tree);
assert_eq!(result.len(), 3);
assert_eq!(result[0].id, "UNH");
assert_eq!(result[1].id, "IDE");
assert_eq!(result[2].id, "LOC");
for (i, seg) in result.iter().enumerate() {
assert_eq!(seg.segment_number, (i + 1) as u32);
}
}
}