use std::num::ParseIntError;
use std::ops::Range;
use std::str::Utf8Error;
use thiserror::Error;
#[cfg(feature = "use-tracing")]
use tracing::trace;
mod flags;
mod parse;
pub use flags::Dictionary;
pub use flags::Flags;
#[derive(Debug)]
pub struct Mail<'a> {
pub message: &'a [u8],
pub flags: Flags,
pub dictionary: Dictionary,
}
#[derive(Debug, Error)]
pub enum ParseError {
#[error("Byte Count for Message is Empty")]
EmptyByteCount,
#[error("Missing 0xa byte terminator")]
MissingTerminator,
#[error("Invalid Unicode in file header [{0:?}]: {1}")]
InvalidUnicode(Range<usize>, Utf8Error),
#[error("Invalid Byte Count Header. Can't convert {0} to usize: {1}")]
InvalidByteCount(String, ParseIntError),
#[error("Message Ended unexpectedly at byte {0}")]
UnexpectedEnding(usize),
#[error("Invalid Plist data: {0}")]
InvalidPlistData(&'static str),
}
pub fn parse_emlx<'a>(content: &'a [u8]) -> Result<Mail<'a>, ParseError> {
let (message, plist) = parse::split(&content)?;
#[cfg(feature = "use-tracing")]
trace!("Read Message Part:\n{:?}\n", std::str::from_utf8(message));
let (flags, dictionary) = flags::detect(plist)?;
Ok(Mail {
message,
flags,
dictionary,
})
}