more debug

This commit is contained in:
Quentin 2023-07-23 17:14:16 +02:00
parent c97595c128
commit b4e8b99b22
Signed by: quentin
GPG key ID: E9602264D639FF68
6 changed files with 86 additions and 75 deletions

34
Cargo.lock generated
View file

@ -47,17 +47,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chardetng"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b8f0b65b7b08ae3c8187e8d77174de20cb6777864c6b832d8ad365999cf1ea"
dependencies = [
"cfg-if",
"encoding_rs",
"memchr",
]
[[package]]
name = "chrono"
version = "0.4.26"
@ -79,6 +68,17 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "eml-codec"
version = "0.1.0"
dependencies = [
"base64",
"chrono",
"encoding_rs",
"nom",
"walkdir",
]
[[package]]
name = "encoding_rs"
version = "0.8.32"
@ -111,18 +111,6 @@ dependencies = [
"cc",
]
[[package]]
name = "imf-codec"
version = "0.1.0"
dependencies = [
"base64",
"chardetng",
"chrono",
"encoding_rs",
"nom",
"walkdir",
]
[[package]]
name = "js-sys"
version = "0.3.63"

View file

@ -1,5 +1,5 @@
[package]
name = "imf-codec"
name = "eml-codec"
version = "0.1.0"
edition = "2021"
license = "GPL-3.0-or-later"
@ -7,20 +7,19 @@ license = "GPL-3.0-or-later"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "imf_codec"
name = "eml_codec"
path = "src/lib.rs"
[[bin]]
name = "imf_parse"
name = "eml_parse"
path = "src/parse.rs"
[dependencies]
nom = "7"
chrono = "0.4"
chardetng = "0.1"
encoding_rs = "0.8"
base64 = "0.21"
encoding_rs = "0.8"
[dev-dependencies]
walkdir = "2"

View file

@ -3,35 +3,13 @@
use std::io;
use std::io::Read;
/*
fn parser<'a, F>(input: &'a [u8], func: F) -> ()
where
F: FnOnce(&Section) -> (),
{
let seg = segment::new(input).unwrap();
let charset = seg.charset();
let fields = charset.fields().unwrap();
let field_names = fields.names();
let field_body = field_names.body();
let section = field_body.section();
func(&section.fields);
}*/
fn main() {
/*
// Read full mail in memory
let mut rawmail = Vec::new();
io::stdin().lock().read_to_end(&mut rawmail).unwrap();
// Parse it
parser(&rawmail[..], |section| {
// Checks/debug
println!("{:?}", section);
assert!(section.date.is_some());
assert!(section.from.len() > 0);
assert!(section.bad_fields.len() == 0);
});
*/
println!("hello world");
let eml = eml_codec::email(&rawmail).unwrap();
println!("{:#?}", eml);
assert!(eml.1.date.is_some());
assert!(eml.1.from.len() > 0);
}

View file

@ -1,3 +1,4 @@
use std::fmt;
use nom::{
branch::alt,
bytes::complete::is_not,
@ -25,11 +26,29 @@ pub struct Message<'a>(
pub Box<AnyPart<'a>>,
);
#[derive(Debug, PartialEq)]
#[derive(PartialEq)]
pub struct Text<'a>(pub mime::mime::Text<'a>, pub &'a [u8]);
impl<'a> fmt::Debug for Text<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt
.debug_struct("part::Text")
.field("mime", &self.0)
.field("body", &format_args!("\"{}\"", String::from_utf8_lossy(self.1)))
.finish()
}
}
#[derive(Debug, PartialEq)]
#[derive(PartialEq)]
pub struct Binary<'a>(pub mime::mime::Binary<'a>, pub &'a [u8]);
impl<'a> fmt::Debug for Binary<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt
.debug_struct("part::Binary")
.field("mime", &self.0)
.field("body", &format_args!("\"{}\"", String::from_utf8_lossy(self.1)))
.finish()
}
}
#[derive(Debug, PartialEq)]
pub enum AnyPart<'a> {

View file

@ -1,3 +1,4 @@
use std::fmt;
use nom::{
branch::alt,
bytes::complete::{tag, take_while1},
@ -12,13 +13,13 @@ use crate::text::misc_token::{phrase, word, Phrase, Word};
use crate::text::whitespace::{cfws, fws, is_obs_no_ws_ctl};
use crate::text::words::atom;
#[derive(Debug, PartialEq)]
#[derive(PartialEq)]
pub struct AddrSpec<'a> {
pub local_part: LocalPart<'a>,
pub domain: Domain<'a>,
}
impl<'a> AddrSpec<'a> {
pub fn to_string(&self) -> String {
impl<'a> ToString for AddrSpec<'a> {
fn to_string(&self) -> String {
format!(
"{}@{}",
self.local_part.to_string(),
@ -26,6 +27,11 @@ impl<'a> AddrSpec<'a> {
)
}
}
impl<'a> fmt::Debug for AddrSpec<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("AddrSpec").field(&format_args!("\"{}\"", self.to_string())).finish()
}
}
#[derive(Debug, PartialEq)]
pub struct MailboxRef<'a> {
@ -33,8 +39,8 @@ pub struct MailboxRef<'a> {
pub addrspec: AddrSpec<'a>,
pub name: Option<Phrase<'a>>,
}
impl<'a> MailboxRef<'a> {
pub fn to_string(&self) -> String {
impl<'a> ToString for MailboxRef<'a> {
fn to_string(&self) -> String {
match &self.name {
Some(n) => format!("{} <{}>", n.to_string(), self.addrspec.to_string()),
None => self.addrspec.to_string(),
@ -166,14 +172,14 @@ fn obs_local_part(input: &[u8]) -> IResult<&[u8], LocalPart> {
)(input)
}
#[derive(Debug, PartialEq)]
#[derive(PartialEq)]
pub enum Domain<'a> {
Atoms(Vec<&'a [u8]>),
Litteral(Vec<&'a [u8]>),
}
impl<'a> Domain<'a> {
pub fn to_string(&self) -> String {
impl<'a> ToString for Domain<'a> {
fn to_string(&self) -> String {
match self {
Domain::Atoms(v) => v
.iter()
@ -201,6 +207,11 @@ impl<'a> Domain<'a> {
}
}
}
impl<'a> fmt::Debug for Domain<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Domain").field(&format_args!("\"{}\"", self.to_string())).finish()
}
}
/// Obsolete domain
///

View file

@ -1,3 +1,4 @@
use std::fmt;
use nom::{
branch::alt,
bytes::complete::{tag, take_while1},
@ -50,15 +51,15 @@ pub fn mime_word(input: &[u8]) -> IResult<&[u8], MIMEWord> {
))(input)
}
#[derive(Debug, PartialEq)]
#[derive(PartialEq)]
pub enum Word<'a> {
Quoted(QuotedString<'a>),
Encoded(encoding::EncodedWord<'a>),
Atom(&'a [u8]),
}
impl<'a> Word<'a> {
pub fn to_string(&self) -> String {
impl<'a> ToString for Word<'a> {
fn to_string(&self) -> String {
match self {
Word::Quoted(v) => v.to_string(),
Word::Encoded(v) => v.to_string(),
@ -69,6 +70,11 @@ impl<'a> Word<'a> {
}
}
}
impl<'a> fmt::Debug for Word<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Word").field(&format_args!("\"{}\"", self.to_string())).finish()
}
}
/// Word
///
@ -83,11 +89,11 @@ pub fn word(input: &[u8]) -> IResult<&[u8], Word> {
))(input)
}
#[derive(Debug, PartialEq)]
#[derive(PartialEq)]
pub struct Phrase<'a>(pub Vec<Word<'a>>);
impl<'a> Phrase<'a> {
pub fn to_string(&self) -> String {
impl<'a> ToString for Phrase<'a> {
fn to_string(&self) -> String {
self.0
.iter()
.map(|v| v.to_string())
@ -95,6 +101,11 @@ impl<'a> Phrase<'a> {
.join(" ")
}
}
impl<'a> fmt::Debug for Phrase<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Phrase").field(&format_args!("\"{}\"", self.to_string())).finish()
}
}
/// Phrase
///
@ -122,8 +133,8 @@ pub enum UnstrToken<'a> {
Plain(&'a [u8]),
}
impl<'a> UnstrToken<'a> {
pub fn to_string(&self) -> String {
impl<'a> ToString for UnstrToken<'a> {
fn to_string(&self) -> String {
match self {
UnstrToken::Init => "".into(),
UnstrToken::Encoded(e) => e.to_string(),
@ -135,11 +146,11 @@ impl<'a> UnstrToken<'a> {
}
}
#[derive(Debug, PartialEq, Clone)]
#[derive(PartialEq, Clone)]
pub struct Unstructured<'a>(pub Vec<UnstrToken<'a>>);
impl<'a> Unstructured<'a> {
pub fn to_string(&self) -> String {
impl<'a> ToString for Unstructured<'a> {
fn to_string(&self) -> String {
self.0
.iter()
.fold(
@ -162,6 +173,11 @@ impl<'a> Unstructured<'a> {
.1
}
}
impl<'a> fmt::Debug for Unstructured<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Unstructured").field(&format_args!("\"{}\"", self.to_string())).finish()
}
}
/// Unstructured header field body
///