hl7_parser/builder/
field.rs

1use super::{ComponentBuilder, RepeatBuilder};
2use crate::{
3    datetime::TimeStamp,
4    message::{Field, Separators},
5};
6use display::FieldBuilderDisplay;
7use std::{collections::HashMap, fmt::Display};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum FieldBuilder {
12    Value(String),
13    Repeats(Vec<RepeatBuilder>),
14}
15
16impl Default for FieldBuilder {
17    fn default() -> Self {
18        FieldBuilder::Value(String::new())
19    }
20}
21
22impl FieldBuilder {
23    pub fn with_value(value: String) -> Self {
24        FieldBuilder::Value(value)
25    }
26
27    pub fn with_repeats(repeats: Vec<RepeatBuilder>) -> Self {
28        FieldBuilder::Repeats(repeats)
29    }
30
31    pub fn value(&self) -> Option<&String> {
32        match self {
33            FieldBuilder::Value(value) => Some(value),
34            _ => None,
35        }
36    }
37
38    pub fn repeats(&self) -> Option<&Vec<RepeatBuilder>> {
39        match self {
40            FieldBuilder::Repeats(repeats) => Some(repeats),
41            _ => None,
42        }
43    }
44
45    pub fn value_mut(&mut self) -> Option<&mut String> {
46        match self {
47            FieldBuilder::Value(value) => Some(value),
48            _ => None,
49        }
50    }
51
52    pub fn repeats_mut(&mut self) -> Option<&mut Vec<RepeatBuilder>> {
53        match self {
54            FieldBuilder::Repeats(repeats) => Some(repeats),
55            _ => None,
56        }
57    }
58
59    pub fn into_value(self) -> Option<String> {
60        match self {
61            FieldBuilder::Value(value) => Some(value),
62            _ => None,
63        }
64    }
65
66    pub fn into_repeats(self) -> Option<Vec<RepeatBuilder>> {
67        match self {
68            FieldBuilder::Repeats(repeats) => Some(repeats),
69            _ => None,
70        }
71    }
72
73    pub fn has_repeats(&self) -> bool {
74        matches!(self, FieldBuilder::Repeats(_))
75    }
76
77    pub fn is_empty(&self) -> bool {
78        match self {
79            FieldBuilder::Value(value) => value.is_empty(),
80            FieldBuilder::Repeats(repeats) => repeats.is_empty(),
81        }
82    }
83
84    pub fn set_value(&mut self, value: String) {
85        *self = FieldBuilder::Value(value);
86    }
87
88    pub fn set_timestamp<T: Into<TimeStamp>>(&mut self, timestamp: T) {
89        *self = FieldBuilder::Value(timestamp.into().to_string());
90    }
91
92    pub fn set_repeats(&mut self, repeats: Vec<RepeatBuilder>) {
93        *self = FieldBuilder::Repeats(repeats);
94    }
95
96    pub fn set_component<C: Into<ComponentBuilder>>(&mut self, index: usize, component: C) {
97        let component = component.into();
98        match self {
99            FieldBuilder::Repeats(repeats) => {
100                if let Some(repeat) = repeats.last_mut() {
101                    repeat.set_component(index, component);
102                } else {
103                    let mut repeat = RepeatBuilder::default();
104                    repeat.set_component(index, component);
105                    repeats.push(repeat);
106                }
107            }
108            _ => {
109                let mut repeat = RepeatBuilder::default();
110                repeat.set_component(index, component);
111                *self = FieldBuilder::Repeats(vec![repeat]);
112            }
113        }
114    }
115
116    pub fn with_component<C: Into<ComponentBuilder>>(mut self, index: usize, component: C) -> Self {
117        self.set_component(index, component);
118        self
119    }
120
121    pub fn with_component_value<S: ToString>(self, index: usize, value: S) -> Self {
122        self.with_component(index, ComponentBuilder::Value(value.to_string()))
123    }
124
125    pub fn push_repeat(&mut self, repeat: RepeatBuilder) {
126        match self {
127            FieldBuilder::Repeats(repeats) => repeats.push(repeat),
128            _ => *self = FieldBuilder::Repeats(vec![repeat]),
129        }
130    }
131
132    pub fn clear(&mut self) {
133        *self = FieldBuilder::Value(String::new());
134    }
135
136    pub fn repeat(&self, index: usize) -> Option<&RepeatBuilder> {
137        match self {
138            FieldBuilder::Repeats(repeats) => repeats.get(index),
139            _ => None,
140        }
141    }
142
143    pub fn repeat_mut(&mut self, index: usize) -> Option<&mut RepeatBuilder> {
144        match self {
145            FieldBuilder::Repeats(repeats) => repeats.get_mut(index),
146            _ => None,
147        }
148    }
149
150    pub fn remove_repeat(&mut self, index: usize) -> Option<RepeatBuilder> {
151        match self {
152            FieldBuilder::Repeats(repeats) => {
153                if index < repeats.len() {
154                    Some(repeats.remove(index))
155                } else {
156                    None
157                }
158            }
159            _ => None,
160        }
161    }
162
163    pub fn display<'a>(&'a self, separators: &'a Separators) -> FieldBuilderDisplay<'a> {
164        FieldBuilderDisplay {
165            field: self,
166            separators,
167        }
168    }
169
170    pub fn from_component_map<I: Into<usize>, C: Into<ComponentBuilder>>(
171        components: HashMap<I, C>,
172    ) -> Self {
173        let repeat = RepeatBuilder::from_component_map(components);
174        FieldBuilder::Repeats(vec![repeat])
175    }
176
177    pub fn from_repeats_map<
178        I: Into<usize>,
179        C: Into<ComponentBuilder>,
180        V: IntoIterator<Item = HashMap<I, C>>,
181    >(
182        repeats: V,
183    ) -> Self {
184        let repeats = repeats
185            .into_iter()
186            .map(|components| RepeatBuilder::from_component_map(components))
187            .collect();
188        FieldBuilder::Repeats(repeats)
189    }
190}
191
192mod display {
193    use super::*;
194
195    pub struct FieldBuilderDisplay<'a> {
196        pub(super) field: &'a FieldBuilder,
197        pub(super) separators: &'a Separators,
198    }
199
200    impl<'a> Display for FieldBuilderDisplay<'a> {
201        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202            match self.field {
203                FieldBuilder::Value(value) => self.separators.encode(value).fmt(f),
204                FieldBuilder::Repeats(repeats) => {
205                    let mut first = true;
206                    for repeat in repeats {
207                        if first {
208                            first = false;
209                        } else {
210                            write!(f, "{}", self.separators.repetition)?;
211                        }
212                        write!(f, "{}", repeat.display(self.separators))?;
213                    }
214                    Ok(())
215                }
216            }
217        }
218    }
219}
220
221impl<S: ToString> From<S> for FieldBuilder {
222    fn from(value: S) -> Self {
223        FieldBuilder::Value(value.to_string())
224    }
225}
226
227impl<'m> From<&'m Field<'m>> for FieldBuilder {
228    fn from(field: &'m Field) -> Self {
229        if field.has_repeats()
230            || (!field.repeats.is_empty()
231                && (field.repeats[0].has_components()
232                    || (!field.repeats[0].components.is_empty()
233                        && field.repeats[0].components[0].has_subcomponents())))
234        {
235            FieldBuilder::Repeats(field.repeats().map(RepeatBuilder::from).collect())
236        } else {
237            FieldBuilder::Value(field.raw_value().to_string())
238        }
239    }
240}
241
242#[cfg(test)]
243mod tests {
244    use super::*;
245    use pretty_assertions_sorted::assert_eq;
246
247    #[test]
248    fn can_display_field_builder() {
249        let separators = Separators::default();
250        let field = crate::parser::parse_field("foo~bar").unwrap();
251        let field = FieldBuilder::from(&field);
252        let display = field.display(&separators).to_string();
253        assert_eq!(display, "foo~bar");
254    }
255}