io_smtp/rfc5321/types/
text.rs1use core::fmt;
7
8use alloc::{borrow::Cow, vec::Vec};
9
10use bounded_static_derive::ToStatic;
11use chumsky::prelude::*;
12
13#[derive(Clone, Debug, PartialEq, Eq, Hash, ToStatic)]
15pub struct SmtpText<'a>(pub(crate) Cow<'a, str>);
16
17impl SmtpText<'_> {
18 pub fn parse<'a>(bytes: &'a [u8]) -> Result<SmtpText<'a>, Vec<Rich<'a, u8>>> {
21 parsers::text()
22 .then_ignore(end())
23 .parse(bytes)
24 .into_result()
25 }
26}
27
28impl fmt::Display for SmtpText<'_> {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 write!(f, "{}", self.0.as_ref())
31 }
32}
33
34impl<'a> From<SmtpText<'a>> for Cow<'a, str> {
35 fn from(text: SmtpText<'a>) -> Self {
36 text.0
37 }
38}
39
40impl AsRef<str> for SmtpText<'_> {
41 fn as_ref(&self) -> &str {
42 self.0.as_ref()
43 }
44}
45
46pub(crate) mod parsers {
47 use core::str::from_utf8;
50
51 use alloc::borrow::Cow;
52
53 use chumsky::prelude::*;
54
55 use crate::{rfc5321::SmtpText, utils::parsers::Extra};
56
57 pub(crate) fn text<'a>() -> impl Parser<'a, &'a [u8], SmtpText<'a>, Extra<'a>> + Clone {
64 any()
65 .filter(|b| matches!(*b, 0x09 | 0x20..=0x7e))
66 .repeated()
67 .at_least(1)
68 .to_slice()
69 .map(from_utf8)
70 .map(Result::unwrap)
71 .map(Cow::from)
72 .map(SmtpText)
73 }
74}