hl7_parser/parser/
repeat.rs

1use super::{component::component, Span};
2use crate::message::{Repeat, Separators};
3use nom::{character::complete::char, combinator::consumed, multi::separated_list0, IResult};
4
5pub fn repeat<'i>(seps: Separators) -> impl FnMut(Span<'i>) -> IResult<Span<'i>, Repeat<'i>> {
6    move |i| parse_repeat(i, seps)
7}
8
9fn parse_repeat(i: Span, seps: Separators) -> IResult<Span, Repeat> {
10    let pos_start = i.offset;
11    let (i, (repeat_src, v)) = consumed(separated_list0(char(seps.component), component(seps)))(i)?;
12    let pos_end = i.offset;
13
14    let v = Repeat {
15        source: repeat_src.input,
16        components: v,
17        range: pos_start..pos_end,
18    };
19    Ok((i, v))
20}
21
22#[cfg(test)]
23mod tests {
24    use super::*;
25    use pretty_assertions_sorted::assert_eq;
26
27    #[test]
28    fn can_parse_repeat_basic() {
29        let separators = Separators::default();
30
31        let input = Span::new("foo");
32        let actual = parse_repeat(input, separators).unwrap().1;
33        assert_eq!(actual.components.len(), 1);
34        assert_eq!(actual.range, 0..3);
35    }
36
37    #[test]
38    fn can_parse_repeat_with_components() {
39        let separators = Separators::default();
40
41        let input = Span::new("foo^bar");
42        let actual = parse_repeat(input, separators).unwrap().1;
43        assert_eq!(actual.components.len(), 2);
44        assert_eq!(actual.range, 0..7);
45    }
46
47    #[test]
48    fn can_parse_repeat_with_no_subcomponents_and_escaped_component_separator() {
49        let separators = Separators::default();
50
51        let input = Span::new(r"foo\S\bar");
52        let actual = parse_repeat(input, separators).unwrap().1;
53        assert_eq!(actual.components.len(), 1);
54        assert_eq!(actual.range, 0..9);
55        assert_eq!(actual.components[0].subcomponents.len(), 1);
56        let decoded = actual.components[0].display(&separators).to_string();
57        assert_eq!(decoded, "foo^bar");
58    }
59}