hl7_parser/builder/
field.rs1use 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}