1use crate::message::{Component, Field, Repeat, Segment, Separators, Subcomponent};
2
3mod span;
4pub(crate) type Span<'m> = span::Span<'m>;
5
6mod component;
7mod field;
8pub(crate) mod message;
9mod msh;
10mod repeat;
11pub(crate) mod segment;
12mod subcomponent;
13
14#[derive(Debug, thiserror::Error, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub enum ParseError {
18 #[error("Message parsing failed at position {position}: `{fragment}`")]
20 FailedToParse { position: usize, fragment: String },
21
22 #[error("Message parsing failed because of incomplete input.{}", .0.map(|s| format!(" Need at least {s} more characters to continue.")).unwrap_or_default())]
24 IncompleteInput(Option<usize>),
25}
26
27impl<'s> From<nom::Err<nom::error::Error<Span<'s>>>> for ParseError {
28 fn from(e: nom::Err<nom::error::Error<Span<'s>>>) -> Self {
29 match e {
30 nom::Err::Incomplete(nom::Needed::Unknown) => ParseError::IncompleteInput(None),
31 nom::Err::Incomplete(nom::Needed::Size(size)) => {
32 ParseError::IncompleteInput(Some(size.get()))
33 }
34 nom::Err::Error(e) | nom::Err::Failure(e) => {
35 let position = e.input.offset;
36 ParseError::FailedToParse {
37 position,
38 fragment: e.input.input.chars().take(7).collect(),
39 }
40 }
41 }
42 }
43}
44
45pub fn parse_subcomponent(input: &str) -> Result<Subcomponent<'_>, ParseError> {
47 let separators = Separators::default();
48 subcomponent::subcomponent(separators)(Span::new(input))
49 .map(|(_, m)| m)
50 .map_err(|e| e.into())
51}
52
53pub fn parse_subcomponent_with_separators(
55 input: &str,
56 separators: Separators,
57) -> Result<Subcomponent<'_>, ParseError> {
58 subcomponent::subcomponent(separators)(Span::new(input))
59 .map(|(_, m)| m)
60 .map_err(|e| e.into())
61}
62
63pub fn parse_component(input: &str) -> Result<Component<'_>, ParseError> {
65 let separators = Separators::default();
66 component::component(separators)(Span::new(input))
67 .map(|(_, m)| m)
68 .map_err(|e| e.into())
69}
70
71pub fn parse_component_with_separators(
73 input: &str,
74 separators: Separators,
75) -> Result<Component<'_>, ParseError> {
76 component::component(separators)(Span::new(input))
77 .map(|(_, m)| m)
78 .map_err(|e| e.into())
79}
80
81pub fn parse_repeat(input: &str) -> Result<Repeat<'_>, ParseError> {
83 let separators = Separators::default();
84 repeat::repeat(separators)(Span::new(input))
85 .map(|(_, m)| m)
86 .map_err(|e| e.into())
87}
88
89pub fn parse_repeat_with_separators(
91 input: &str,
92 separators: Separators,
93) -> Result<Repeat<'_>, ParseError> {
94 repeat::repeat(separators)(Span::new(input))
95 .map(|(_, m)| m)
96 .map_err(|e| e.into())
97}
98
99pub fn parse_field(input: &str) -> Result<Field<'_>, ParseError> {
101 let separators = Separators::default();
102 field::field(separators)(Span::new(input))
103 .map(|(_, m)| m)
104 .map_err(|e| e.into())
105}
106
107pub fn parse_field_with_separators(
109 input: &str,
110 separators: Separators,
111) -> Result<Field<'_>, ParseError> {
112 field::field(separators)(Span::new(input))
113 .map(|(_, m)| m)
114 .map_err(|e| e.into())
115}
116
117pub fn parse_segment(input: &str) -> Result<Segment<'_>, ParseError> {
119 let separators = Separators::default();
120 segment::segment(separators)(Span::new(input))
121 .map(|(_, m)| m)
122 .map_err(|e| e.into())
123}
124
125pub fn parse_segment_with_separators(
127 input: &str,
128 separators: Separators,
129) -> Result<Segment<'_>, ParseError> {
130 segment::segment(separators)(Span::new(input))
131 .map(|(_, m)| m)
132 .map_err(|e| e.into())
133}
134
135pub fn parse_msh(input: &str) -> Result<(Separators, Segment<'_>), ParseError> {
137 msh::msh(false)(Span::new(input))
138 .map(|(_, m)| (m.separators, m.into()))
139 .map_err(|e| e.into())
140}
141
142pub fn parse_message(input: &str) -> Result<crate::Message<'_>, ParseError> {
144 crate::parser::message::message(false)(Span::new(input))
145 .map(|(_, m)| m)
146 .map_err(|e| e.into())
147}
148
149pub fn parse_message_with_lenient_newlines(
150 input: &str,
151 lenient_newlines: bool,
152) -> Result<crate::Message<'_>, ParseError> {
153 crate::parser::message::message(lenient_newlines)(Span::new(input))
154 .map(|(_, m)| m)
155 .map_err(|e| e.into())
156}