Skip to main content

zer_core/
field_mapping.rs

1use crate::record::FieldName;
2
3/// Declares how one field from source A maps to one field from source B.
4///
5/// Used when the two sources have structurally different schemas (e.g. BRP
6/// `voornamen` maps to SIS `name`) and the comparator needs explicit guidance about
7/// which field on each side should be compared.
8#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
9pub struct FieldMapping {
10    pub a_field:     FieldName,
11    pub b_field:     FieldName,
12    pub null_policy: NullPolicy,
13}
14
15impl FieldMapping {
16    pub fn new(a_field: impl Into<FieldName>, b_field: impl Into<FieldName>) -> Self {
17        Self {
18            a_field:     a_field.into(),
19            b_field:     b_field.into(),
20            null_policy: NullPolicy::Skip,
21        }
22    }
23
24    pub fn with_null_policy(mut self, policy: NullPolicy) -> Self {
25        self.null_policy = policy;
26        self
27    }
28}
29
30/// How the comparator treats a field pair where one or both values are absent.
31#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
32#[serde(rename_all = "snake_case")]
33pub enum NullPolicy {
34    /// Return `ComparisonLevel::Null` (255), EM skips this field for the pair.
35    #[default]
36    Skip,
37    /// Return `ComparisonLevel::None` (0), treated as a hard non-match signal.
38    PenaliseAbsence,
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn default_null_policy_is_skip() {
47        let m = FieldMapping::new("voornamen", "name");
48        assert_eq!(m.null_policy, NullPolicy::Skip);
49    }
50
51    #[test]
52    fn null_policy_round_trips_json() {
53        let m = FieldMapping::new("geboortedatum", "dob")
54            .with_null_policy(NullPolicy::PenaliseAbsence);
55        let json = serde_json::to_string(&m).unwrap();
56        let back: FieldMapping = serde_json::from_str(&json).unwrap();
57        assert_eq!(back.null_policy, NullPolicy::PenaliseAbsence);
58        assert_eq!(back.a_field, "geboortedatum");
59        assert_eq!(back.b_field, "dob");
60    }
61}