better debug

This commit is contained in:
Quentin 2023-08-30 19:30:10 +02:00
parent 18bb04340a
commit 9b828ad6ad
Signed by: quentin
GPG key ID: E9602264D639FF68
5 changed files with 80 additions and 13 deletions

View file

@ -1,3 +1,4 @@
use std::fmt;
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::{tag, take_while1}, bytes::complete::{tag, take_while1},
@ -11,13 +12,21 @@ use nom::{
use crate::text::whitespace::{foldable_line, obs_crlf}; use crate::text::whitespace::{foldable_line, obs_crlf};
use crate::text::misc_token::unstructured; use crate::text::misc_token::unstructured;
#[derive(Debug, PartialEq, Clone)] #[derive(PartialEq, Clone)]
pub struct Kv2<'a>(pub &'a [u8], pub &'a [u8]); pub struct Kv2<'a>(pub &'a [u8], pub &'a [u8]);
impl<'a> From<(&'a [u8], &'a [u8])> for Kv2<'a> { impl<'a> From<(&'a [u8], &'a [u8])> for Kv2<'a> {
fn from(pair: (&'a [u8], &'a [u8])) -> Self { fn from(pair: (&'a [u8], &'a [u8])) -> Self {
Self(pair.0, pair.1) Self(pair.0, pair.1)
} }
} }
impl<'a> fmt::Debug for Kv2<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("header::Kv2")
.field(&String::from_utf8_lossy(self.0))
.field(&String::from_utf8_lossy(self.1))
.finish()
}
}
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum Field<'a> { pub enum Field<'a> {

View file

@ -10,6 +10,7 @@ pub mod mechanism;
/// Content-Type representation /// Content-Type representation
pub mod r#type; pub mod r#type;
use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use crate::imf::identification::MessageID; use crate::imf::identification::MessageID;
@ -55,15 +56,27 @@ impl<'a, T: WithDefaultType> From<AnyMIMEWithDefault<'a, T>> for AnyMIME<'a> {
} }
} }
#[derive(Debug, PartialEq, Default, Clone)] #[derive(PartialEq, Default, Clone)]
pub struct NaiveMIME<'a> { pub struct NaiveMIME<'a> {
pub ctype: Option<NaiveType<'a>>, pub ctype: Option<NaiveType<'a>>,
pub transfer_encoding: Mechanism<'a>, pub transfer_encoding: Mechanism<'a>,
pub id: Option<MessageID<'a>>, pub id: Option<MessageID<'a>>,
pub description: Option<Unstructured<'a>>, pub description: Option<Unstructured<'a>>,
pub fields: Vec<header::Field<'a>>, pub kv: Vec<header::Field<'a>>,
pub raw: &'a [u8], pub raw: &'a [u8],
} }
impl<'a> fmt::Debug for NaiveMIME<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("NaiveMime")
.field("ctype", &self.ctype)
.field("transfer_encoding", &self.transfer_encoding)
.field("id", &self.id)
.field("description", &self.description)
.field("kv", &self.kv)
.field("raw", &String::from_utf8_lossy(self.raw))
.finish()
}
}
impl<'a> FromIterator<Content<'a>> for NaiveMIME<'a> { impl<'a> FromIterator<Content<'a>> for NaiveMIME<'a> {
fn from_iter<I: IntoIterator<Item = Content<'a>>>(it: I) -> Self { fn from_iter<I: IntoIterator<Item = Content<'a>>>(it: I) -> Self {
@ -83,8 +96,8 @@ impl<'a> FromIterator<Content<'a>> for NaiveMIME<'a> {
} }
impl<'a> NaiveMIME<'a> { impl<'a> NaiveMIME<'a> {
pub fn with_fields(mut self, fields: Vec<header::Field<'a>>) -> Self { pub fn with_kv(mut self, fields: Vec<header::Field<'a>>) -> Self {
self.fields = fields; self self.kv = fields; self
} }
pub fn with_raw(mut self, raw: &'a [u8]) -> Self { pub fn with_raw(mut self, raw: &'a [u8]) -> Self {
self.raw = raw; self self.raw = raw; self

View file

@ -1,3 +1,4 @@
use std::fmt;
use nom::{ use nom::{
bytes::complete::tag, bytes::complete::tag,
combinator::{map, opt}, combinator::{map, opt},
@ -12,12 +13,21 @@ use crate::text::words::mime_atom;
use crate::mime::{AnyMIME, MIME, NaiveMIME}; use crate::mime::{AnyMIME, MIME, NaiveMIME};
// --------- NAIVE TYPE // --------- NAIVE TYPE
#[derive(Debug, PartialEq, Clone)] #[derive(PartialEq, Clone)]
pub struct NaiveType<'a> { pub struct NaiveType<'a> {
pub main: &'a [u8], pub main: &'a [u8],
pub sub: &'a [u8], pub sub: &'a [u8],
pub params: Vec<Parameter<'a>>, pub params: Vec<Parameter<'a>>,
} }
impl<'a> fmt::Debug for NaiveType<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("mime::NaiveType")
.field("main", &String::from_utf8_lossy(self.main))
.field("sub", &String::from_utf8_lossy(self.sub))
.field("params", &self.params)
.finish()
}
}
impl<'a> NaiveType<'a> { impl<'a> NaiveType<'a> {
pub fn to_type(&self) -> AnyType { pub fn to_type(&self) -> AnyType {
self.into() self.into()
@ -30,11 +40,20 @@ pub fn naive_type(input: &[u8]) -> IResult<&[u8], NaiveType> {
)(input) )(input)
} }
#[derive(Debug, PartialEq, Clone)] #[derive(PartialEq, Clone)]
pub struct Parameter<'a> { pub struct Parameter<'a> {
pub name: &'a [u8], pub name: &'a [u8],
pub value: MIMEWord<'a>, pub value: MIMEWord<'a>,
} }
impl<'a> fmt::Debug for Parameter<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("mime::Parameter")
.field("name", &String::from_utf8_lossy(self.name))
.field("value", &self.value)
.finish()
}
}
pub fn parameter(input: &[u8]) -> IResult<&[u8], Parameter> { pub fn parameter(input: &[u8]) -> IResult<&[u8], Parameter> {
map( map(
tuple((mime_atom, tag(b"="), mime_word)), tuple((mime_atom, tag(b"="), mime_word)),

View file

@ -1,3 +1,4 @@
use std::fmt;
use nom::IResult; use nom::IResult;
use crate::header; use crate::header;
@ -8,13 +9,23 @@ use crate::text::boundary::{boundary, Delimiter};
use crate::pointers; use crate::pointers;
//--- Multipart //--- Multipart
#[derive(Debug, PartialEq)] #[derive(PartialEq)]
pub struct Multipart<'a> { pub struct Multipart<'a> {
pub mime: mime::MIME<'a, mime::r#type::Multipart>, pub mime: mime::MIME<'a, mime::r#type::Multipart>,
pub children: Vec<AnyPart<'a>>, pub children: Vec<AnyPart<'a>>,
pub raw_part_inner: &'a [u8], pub raw_part_inner: &'a [u8],
pub raw_part_outer: &'a [u8], pub raw_part_outer: &'a [u8],
} }
impl<'a> fmt::Debug for Multipart<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("part::Multipart")
.field("mime", &self.mime)
.field("children", &self.children)
.field("raw_part_inner", &String::from_utf8_lossy(self.raw_part_inner))
.field("raw_part_outer", &String::from_utf8_lossy(self.raw_part_outer))
.finish()
}
}
impl<'a> Multipart<'a> { impl<'a> Multipart<'a> {
pub fn preamble(&self) -> &'a [u8] { pub fn preamble(&self) -> &'a [u8] {
pointers::parsed(self.raw_part_outer, self.raw_part_inner) pointers::parsed(self.raw_part_outer, self.raw_part_inner)
@ -83,7 +94,7 @@ pub fn multipart<'a>(
.collect::<mime::NaiveMIME>(); .collect::<mime::NaiveMIME>();
let mime = mime let mime = mime
.with_fields(fields) .with_kv(fields)
.with_raw(raw_hdrs); .with_raw(raw_hdrs);
(input_eom, mime) (input_eom, mime)
@ -113,7 +124,7 @@ pub fn multipart<'a>(
//--- Message //--- Message
#[derive(Debug, PartialEq)] #[derive(PartialEq)]
pub struct Message<'a> { pub struct Message<'a> {
pub mime: mime::MIME<'a, mime::r#type::DeductibleMessage>, pub mime: mime::MIME<'a, mime::r#type::DeductibleMessage>,
pub imf: imf::Imf<'a>, pub imf: imf::Imf<'a>,
@ -123,6 +134,18 @@ pub struct Message<'a> {
pub raw_headers: &'a [u8], pub raw_headers: &'a [u8],
pub raw_body: &'a [u8], pub raw_body: &'a [u8],
} }
impl<'a> fmt::Debug for Message<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("part::Message")
.field("mime", &self.mime)
.field("imf", &self.imf)
.field("child", &self.child)
.field("raw_part", &String::from_utf8_lossy(self.raw_part))
.field("raw_headers", &String::from_utf8_lossy(self.raw_headers))
.field("raw_body", &String::from_utf8_lossy(self.raw_body))
.finish()
}
}
pub fn message<'a>( pub fn message<'a>(
m: mime::MIME<'a, mime::r#type::DeductibleMessage>, m: mime::MIME<'a, mime::r#type::DeductibleMessage>,
@ -142,7 +165,7 @@ pub fn message<'a>(
let (naive_mime, imf) = part::field::split_and_build(&headers); let (naive_mime, imf) = part::field::split_and_build(&headers);
// interpret headers to choose a mime type // interpret headers to choose a mime type
let in_mime = naive_mime.with_fields(headers).with_raw(raw_headers).to_interpreted::<mime::WithGenericDefault>().into(); let in_mime = naive_mime.with_kv(headers).with_raw(raw_headers).to_interpreted::<mime::WithGenericDefault>().into();
//--------------- //---------------
// parse a part following this mime specification // parse a part following this mime specification
@ -256,6 +279,9 @@ It DOES end with a linebreak.
] ]
}), }),
raw: &b"Content-type: text/plain; charset=us-ascii\n\n"[..], raw: &b"Content-type: text/plain; charset=us-ascii\n\n"[..],
kv: vec![
header::Field::Good(header::Kv2(&b"Content-type"[..], &b"text/plain; charset=us-ascii"[..]))
],
..mime::NaiveMIME::default() ..mime::NaiveMIME::default()
}, },
}, },

View file

@ -14,7 +14,7 @@ impl<'a> fmt::Debug for Text<'a> {
.field("mime", &self.mime) .field("mime", &self.mime)
.field( .field(
"body", "body",
&format_args!("\"{}\"", String::from_utf8_lossy(self.body)), &String::from_utf8_lossy(self.body),
) )
.finish() .finish()
} }
@ -32,7 +32,7 @@ impl<'a> fmt::Debug for Binary<'a> {
.field("mime", &self.mime) .field("mime", &self.mime)
.field( .field(
"body", "body",
&format_args!("\"{}\"", String::from_utf8_lossy(self.body)), &String::from_utf8_lossy(self.body),
) )
.finish() .finish()
} }