Skip to main content

serde_er7/
field.rs

1//! [`Field`]: a sequence of [`Repetition`]s, serialized as an array.
2
3use std::fmt;
4use std::ops::{Deref, DerefMut};
5
6use serde::de::{SeqAccess, Visitor};
7use serde::ser::SerializeSeq;
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9
10use crate::Repetition;
11
12/// A Serde-enabled [`er7::Field`].
13///
14/// A field is nothing but its repetitions in order
15/// ([`er7::Field::repetitions`]), so — like [`Repetition`] one level down —
16/// it serializes as a plain array: `555-1111~555-2222` becomes
17/// `[["555-1111"], ["555-2222"]]`. A field that was sent empty (`||`) has
18/// no repetitions at all, and serializes as `[]`; this is what
19/// distinguishes it from a present-but-empty repetition ([`er7::Field`]
20/// spec).
21///
22/// Example:
23///
24/// ```
25/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
26/// use serde_er7::Field;
27///
28/// let message = er7::parse(r"MSH|^~\&|LAB|555-1111~555-2222")?;
29/// let field = message.segment("MSH").unwrap().field(4).unwrap().clone();
30///
31/// let json = serde_json::to_string(&Field(field))?;
32/// let back: Field = serde_json::from_str(&json)?;
33/// assert_eq!(back.to_er7(&message.separators), "555-1111~555-2222");
34///
35/// // Absent (`||`) round-trips as an empty array, not `[[]]`.
36/// let empty: Field = serde_json::from_str("[]")?;
37/// assert!(empty.repetitions.is_empty());
38/// # Ok(())
39/// # }
40/// ```
41#[derive(Debug, Clone, PartialEq, Eq, Default)]
42pub struct Field(pub er7::Field);
43
44impl From<er7::Field> for Field {
45    fn from(inner: er7::Field) -> Field {
46        Field(inner)
47    }
48}
49
50impl From<Field> for er7::Field {
51    fn from(outer: Field) -> er7::Field {
52        outer.0
53    }
54}
55
56impl Deref for Field {
57    type Target = er7::Field;
58
59    fn deref(&self) -> &er7::Field {
60        &self.0
61    }
62}
63
64impl DerefMut for Field {
65    fn deref_mut(&mut self) -> &mut er7::Field {
66        &mut self.0
67    }
68}
69
70impl Serialize for Field {
71    /// Write each repetition as one array element. See
72    /// [`Component::serialize`](crate::Component#impl) for the cost of the
73    /// clone this involves.
74    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
75    where
76        S: Serializer,
77    {
78        let repetitions = &self.0.repetitions;
79        let mut seq = serializer.serialize_seq(Some(repetitions.len()))?;
80        for repetition in repetitions {
81            seq.serialize_element(&Repetition(repetition.clone()))?;
82        }
83        seq.end()
84    }
85}
86
87struct FieldVisitor;
88
89impl<'de> Visitor<'de> for FieldVisitor {
90    type Value = Field;
91
92    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
93        formatter.write_str("an array of repetitions, each an array of components")
94    }
95
96    fn visit_seq<A>(self, mut seq: A) -> Result<Field, A::Error>
97    where
98        A: SeqAccess<'de>,
99    {
100        let mut repetitions = Vec::with_capacity(seq.size_hint().unwrap_or(0));
101        while let Some(repetition) = seq.next_element::<Repetition>()? {
102            repetitions.push(repetition.0);
103        }
104        Ok(Field(er7::Field { repetitions }))
105    }
106}
107
108impl<'de> Deserialize<'de> for Field {
109    /// Read an array of repetitions into `repetitions`.
110    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
111    where
112        D: Deserializer<'de>,
113    {
114        deserializer.deserialize_seq(FieldVisitor)
115    }
116}
117
118#[cfg(test)]
119mod tests {
120    use super::*;
121
122    #[test]
123    fn round_trips_repeated_values() {
124        let field = Field(er7::Field {
125            repetitions: vec![
126                er7::Repetition {
127                    components: vec![er7::Component {
128                        subcomponents: vec![er7::Subcomponent::new("555-1111")],
129                    }],
130                },
131                er7::Repetition {
132                    components: vec![er7::Component {
133                        subcomponents: vec![er7::Subcomponent::new("555-2222")],
134                    }],
135                },
136            ],
137        });
138        let json = serde_json::to_string(&field).unwrap();
139        assert_eq!(json, r#"[[["555-1111"]],[["555-2222"]]]"#);
140        let back: Field = serde_json::from_str(&json).unwrap();
141        assert_eq!(back, field);
142    }
143
144    #[test]
145    fn an_absent_field_is_an_empty_array() {
146        let field = Field::default();
147        assert_eq!(serde_json::to_string(&field).unwrap(), "[]");
148    }
149}