diff --git a/src/parser/object.rs b/src/parser/object.rs index 417bb78d..ee2c5d36 100644 --- a/src/parser/object.rs +++ b/src/parser/object.rs @@ -1,6 +1,11 @@ +use nom::combinator::map; use nom::combinator::not; +use crate::parser::error::CustomError; +use crate::parser::error::MyError; + use super::error::Res; +use super::parser_with_context::parser_with_context; use super::source::Source; use super::Context; @@ -41,5 +46,43 @@ pub fn standard_set_object<'r, 's>( input: &'s str, ) -> Res<&'s str, Object<'s>> { not(|i| context.check_exit_matcher(i))(input)?; - todo!() + + let plain_text_matcher = parser_with_context!(plain_text)(context); + + map(plain_text_matcher, Object::PlainText)(input) +} + +fn plain_text<'r, 's>(context: Context<'r, 's>, input: &'s str) -> Res<&'s str, PlainText<'s>> { + if input.len() == 0 { + return Err(nom::Err::Error(CustomError::MyError(MyError( + "Zero input length to plain_text.", + )))); + } + // not(|i| context.check_exit_matcher(i))(input)?; + let mut current_input = input.char_indices(); + loop { + match current_input.next() { + Some((offset, _char)) => { + let remaining = &input[offset..]; + let exit_matcher_status = context.check_exit_matcher(remaining); + if exit_matcher_status.is_err() { + if offset == 0 { + // If we're at the start of the input, then nothing is plain text, so fire an error for zero-length match. + exit_matcher_status?; + } else { + return Ok(( + &input[offset..], + PlainText { + source: &input[..offset], + }, + )); + } + } + } + None => { + // We hit the end of the file, so all input must be plain text + return Ok((&input[input.len()..], PlainText { source: input })); + } + }; + } }