Skip to main content

serde_er7/
repetition.rs

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