diff --git a/magnetar_mmm_parser/src/lib.rs b/magnetar_mmm_parser/src/lib.rs index 25dfbc2..52c5e84 100644 --- a/magnetar_mmm_parser/src/lib.rs +++ b/magnetar_mmm_parser/src/lib.rs @@ -635,6 +635,16 @@ impl Context { } } + pub fn parse_profile_fields(&self, input: &str) -> Token { + match self.inline_profile_fields(Span::new_extra(input, SpanMeta::default())) { + Ok((_, t)) => t.merged(), + Err(e) => { + trace!(input = input, "Profile field parser fail: {:?}", e); + Token::PlainText(e.to_compact_string()) + } + } + } + #[inline] fn partial( &self, @@ -666,6 +676,19 @@ impl Context { )(input) } + fn inline_profile_fields<'a>(&self, input: Span<'a>) -> IResult, Token> { + map( + many1(alt(( + self.partial(Self::unicode_emoji), + self.partial(Self::tag_mention), + self.partial(Self::tag_hashtag), + self.partial(Self::raw_url), + self.partial(Self::tag_raw_text), + ))), + Token::Sequence, + )(input) + } + fn inline_ui<'a>(&self, input: Span<'a>) -> IResult, Token> { map( many1(alt(( @@ -1437,6 +1460,7 @@ impl Context { return Ok((plain_out, Token::PlainText(plain.into()))); } + let start = input; let tags = one_of("@!"); let (input, mention_type) = map(tags, |c| match c { '@' => MentionType::User, @@ -1462,9 +1486,19 @@ impl Context { )(input)?; let host = host.map(|h| h.trim_end_matches(|c| matches!(c, '.' | '-' | '_'))); + let input = host.map(|c| before.slice(c.len() + 1..)).unwrap_or(before); + + if let (input, Some(_)) = + peek(opt(tuple((recognize(tag(":")), alphanumeric1_unicode))))(input)? + { + return Ok(( + input, + Token::PlainText(start.up_to(&input).into_fragment().into()), + )); + } Ok(( - host.map(|c| before.slice(c.len() + 1..)).unwrap_or(before), + input, Token::Mention { mention_type, name: name.into(), @@ -2145,6 +2179,11 @@ text"# Token::PlainText(" test".into()) ]) ); + + assert_eq!( + parse_full("@tag:domain.com"), + Token::PlainText("@tag:domain.com".into()) + ); } #[test]