Skip to main content

mig_types/
navigator.rs

1//! Group-scoped segment navigation trait.
2
3use crate::segment::OwnedSegment;
4
5/// Provides group-scoped segment access for condition evaluation.
6///
7/// Implementations translate hierarchical group paths (e.g., `["SG4", "SG8"]`)
8/// into segment lookups scoped to a specific group instance.
9pub trait GroupNavigator: Send + Sync {
10    /// Find all segments with the given tag within a specific group instance.
11    ///
12    /// * `segment_id` - Segment tag to find (e.g., "SEQ", "CCI")
13    /// * `group_path` - Path of group IDs from root (e.g., `&["SG4", "SG8"]`)
14    /// * `instance_index` - Which repetition of the innermost group (0-based)
15    fn find_segments_in_group(
16        &self,
17        segment_id: &str,
18        group_path: &[&str],
19        instance_index: usize,
20    ) -> Vec<OwnedSegment>;
21
22    /// Find segments matching a tag + qualifier within a group instance.
23    ///
24    /// * `segment_id` - Segment tag to find
25    /// * `element_index` - Which element contains the qualifier
26    /// * `qualifier` - Expected qualifier value
27    /// * `group_path` - Path of group IDs from root
28    /// * `instance_index` - Which repetition of the innermost group (0-based)
29    fn find_segments_with_qualifier_in_group(
30        &self,
31        segment_id: &str,
32        element_index: usize,
33        qualifier: &str,
34        group_path: &[&str],
35        instance_index: usize,
36    ) -> Vec<OwnedSegment>;
37
38    /// Count repetitions of a group at the given path.
39    fn group_instance_count(&self, group_path: &[&str]) -> usize;
40
41    /// Check if a group instance has any segments at all.
42    ///
43    /// Returns `true` if the group instance at `instance_index` contains at least
44    /// one segment. Used to distinguish genuinely populated group instances from
45    /// navigator implementations that can't resolve per-instance segments.
46    fn has_any_segment_in_group(&self, _group_path: &[&str], _instance_index: usize) -> bool {
47        false // Default: unknown, treat as unpopulated
48    }
49
50    /// Check if a group instance belongs to the MIG variant identified by `mig_number`.
51    ///
52    /// Returns `true` when the instance's variant defines the given `mig_number`
53    /// (directly or in a nested group). Used to scope per-instance rules — a rule
54    /// tagged with `mig_number` only applies to instances whose variant includes
55    /// that number. Example: PID 55218 has two SG8 variants (sg8_z01 with SEQ
56    /// mig=00115, sg8_z45_z84 with SEQ mig=00171). A `[1P1..n]` package on SEQ
57    /// mig=00171 must not be checked against sg8_z01 instances.
58    ///
59    /// Default: `true` (cannot determine — keep old behavior). Implementations
60    /// backed by an assembled tree should consult `variant_mig_numbers`.
61    fn instance_has_mig_number(
62        &self,
63        _group_path: &[&str],
64        _instance_index: usize,
65        _mig_number: &str,
66    ) -> bool {
67        true
68    }
69
70    /// Count repetitions of a child group within a specific parent group instance.
71    ///
72    /// * `parent_path` - Path to the parent group (e.g., `&["SG4", "SG8"]`)
73    /// * `parent_instance` - Which repetition of the parent group (0-based)
74    /// * `child_group_id` - ID of the child group to count (e.g., `"SG10"`)
75    fn child_group_instance_count(
76        &self,
77        parent_path: &[&str],
78        parent_instance: usize,
79        child_group_id: &str,
80    ) -> usize {
81        let _ = (parent_path, parent_instance, child_group_id);
82        0
83    }
84
85    /// Find all segments with the given tag within a child group instance.
86    ///
87    /// * `segment_id` - Segment tag to find (e.g., "CCI")
88    /// * `parent_path` - Path to the parent group (e.g., `&["SG4", "SG8"]`)
89    /// * `parent_instance` - Which repetition of the parent group (0-based)
90    /// * `child_group_id` - ID of the child group (e.g., `"SG10"`)
91    /// * `child_instance` - Which repetition of the child group (0-based)
92    fn find_segments_in_child_group(
93        &self,
94        segment_id: &str,
95        parent_path: &[&str],
96        parent_instance: usize,
97        child_group_id: &str,
98        child_instance: usize,
99    ) -> Vec<OwnedSegment> {
100        let _ = (
101            segment_id,
102            parent_path,
103            parent_instance,
104            child_group_id,
105            child_instance,
106        );
107        vec![]
108    }
109
110    /// Extract a single value from the first matching segment in a group instance.
111    ///
112    /// More efficient than `find_segments_in_group` when only one value is needed.
113    ///
114    /// * `segment_id` - Segment tag to find
115    /// * `element_index` - Which element to extract from
116    /// * `component_index` - Which component within the element
117    /// * `group_path` - Path of group IDs from root
118    /// * `instance_index` - Which repetition of the innermost group (0-based)
119    fn extract_value_in_group(
120        &self,
121        segment_id: &str,
122        element_index: usize,
123        component_index: usize,
124        group_path: &[&str],
125        instance_index: usize,
126    ) -> Option<String> {
127        let _ = (
128            segment_id,
129            element_index,
130            component_index,
131            group_path,
132            instance_index,
133        );
134        None
135    }
136}