mirror of
https://git.meli.delivery/meli/meli
synced 2024-11-17 03:26:20 +00:00
melib/email/parser: add backtrace field to ParsingError
Add backtrace field to ParsingError when the build is for testing or documentation. Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
This commit is contained in:
parent
ab1b946fd9
commit
f685726eac
@ -22,6 +22,8 @@
|
|||||||
//! Parsers for email. See submodules.
|
//! Parsers for email. See submodules.
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
use std::backtrace::Backtrace;
|
||||||
use std::{borrow::Cow, convert::TryFrom, fmt::Write};
|
use std::{borrow::Cow, convert::TryFrom, fmt::Write};
|
||||||
|
|
||||||
use nom::{
|
use nom::{
|
||||||
@ -51,29 +53,58 @@ macro_rules! to_str {
|
|||||||
unsafe { std::str::from_utf8_unchecked($l) }
|
unsafe { std::str::from_utf8_unchecked($l) }
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
#[derive(Eq, PartialEq)]
|
|
||||||
pub struct ParsingError<I> {
|
pub struct ParsingError<I> {
|
||||||
pub input: I,
|
pub input: I,
|
||||||
pub error: Cow<'static, str>,
|
pub error: Cow<'static, str>,
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
pub backtrace: Backtrace,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: PartialEq> PartialEq for ParsingError<I> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.input.eq(&other.input) && self.error.eq(&other.error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for ParsingError<&'_ [u8]> {
|
impl std::fmt::Debug for ParsingError<&'_ [u8]> {
|
||||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
{
|
||||||
|
fmt.debug_struct("ParsingError")
|
||||||
|
.field("input", &to_str!(self.input))
|
||||||
|
.field("error", &self.error)
|
||||||
|
.field("backtrace", &self.backtrace)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
#[cfg(not(any(test, doc)))]
|
||||||
|
{
|
||||||
fmt.debug_struct("ParsingError")
|
fmt.debug_struct("ParsingError")
|
||||||
.field("input", &to_str!(self.input))
|
.field("input", &to_str!(self.input))
|
||||||
.field("error", &self.error)
|
.field("error", &self.error)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for ParsingError<&'_ str> {
|
impl std::fmt::Debug for ParsingError<&'_ str> {
|
||||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
{
|
||||||
|
fmt.debug_struct("ParsingError")
|
||||||
|
.field("input", &self.input)
|
||||||
|
.field("error", &self.error)
|
||||||
|
.field("backtrace", &self.backtrace)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
#[cfg(not(any(test, doc)))]
|
||||||
|
{
|
||||||
fmt.debug_struct("ParsingError")
|
fmt.debug_struct("ParsingError")
|
||||||
.field("input", &self.input)
|
.field("input", &self.input)
|
||||||
.field("error", &self.error)
|
.field("error", &self.error)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct DebugOkWrapper<'r, I, R: AsRef<[u8]>>(&'r IResult<I, R>);
|
struct DebugOkWrapper<'r, I, R: AsRef<[u8]>>(&'r IResult<I, R>);
|
||||||
|
|
||||||
@ -94,6 +125,8 @@ impl<'i> ParsingError<&'i str> {
|
|||||||
ParsingError {
|
ParsingError {
|
||||||
input: self.input.as_bytes(),
|
input: self.input.as_bytes(),
|
||||||
error: self.error,
|
error: self.error,
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
backtrace: self.backtrace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,6 +136,8 @@ impl<I> From<(I, &'static str)> for ParsingError<I> {
|
|||||||
Self {
|
Self {
|
||||||
input,
|
input,
|
||||||
error: error.into(),
|
error: error.into(),
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
backtrace: Backtrace::capture(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,6 +147,8 @@ impl<I> From<(I, String)> for ParsingError<I> {
|
|||||||
Self {
|
Self {
|
||||||
input,
|
input,
|
||||||
error: error.into(),
|
error: error.into(),
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
backtrace: Backtrace::capture(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +158,8 @@ impl<I> nom::error::ParseError<I> for ParsingError<I> {
|
|||||||
Self {
|
Self {
|
||||||
input,
|
input,
|
||||||
error: kind.description().to_string().into(),
|
error: kind.description().to_string().into(),
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
backtrace: Backtrace::capture(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +167,8 @@ impl<I> nom::error::ParseError<I> for ParsingError<I> {
|
|||||||
Self {
|
Self {
|
||||||
input,
|
input,
|
||||||
error: format!("{}, {}", kind.description(), other.error).into(),
|
error: format!("{}, {}", kind.description(), other.error).into(),
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
backtrace: Backtrace::capture(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,6 +178,8 @@ impl<I, E> nom::error::FromExternalError<I, E> for ParsingError<I> {
|
|||||||
Self {
|
Self {
|
||||||
input,
|
input,
|
||||||
error: kind.description().to_string().into(),
|
error: kind.description().to_string().into(),
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
backtrace: Backtrace::capture(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +188,8 @@ impl<I> nom::error::ContextError<I> for ParsingError<I> {}
|
|||||||
|
|
||||||
impl<'i> From<ParsingError<&'i [u8]>> for Error {
|
impl<'i> From<ParsingError<&'i [u8]>> for Error {
|
||||||
fn from(val: ParsingError<&'i [u8]>) -> Self {
|
fn from(val: ParsingError<&'i [u8]>) -> Self {
|
||||||
Self::new("Parsing error").set_summary(format!(
|
Self::new("Parsing error")
|
||||||
|
.set_summary(format!(
|
||||||
r#"In input: "{}...",
|
r#"In input: "{}...",
|
||||||
Error: {}"#,
|
Error: {}"#,
|
||||||
String::from_utf8_lossy(val.input)
|
String::from_utf8_lossy(val.input)
|
||||||
@ -154,17 +198,53 @@ Error: {}"#,
|
|||||||
.collect::<String>(),
|
.collect::<String>(),
|
||||||
val.error
|
val.error
|
||||||
))
|
))
|
||||||
|
.set_details({
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
{
|
||||||
|
println!(
|
||||||
|
"\tInput:\n{}\tError:\n{}\n\tBacktrace:\n{}",
|
||||||
|
String::from_utf8_lossy(val.input)
|
||||||
|
.chars()
|
||||||
|
.take(30)
|
||||||
|
.collect::<String>(),
|
||||||
|
val.error,
|
||||||
|
val.backtrace
|
||||||
|
);
|
||||||
|
val.backtrace.to_string()
|
||||||
|
}
|
||||||
|
#[cfg(not(any(test, doc)))]
|
||||||
|
{
|
||||||
|
""
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i> From<ParsingError<&'i str>> for Error {
|
impl<'i> From<ParsingError<&'i str>> for Error {
|
||||||
fn from(val: ParsingError<&'i str>) -> Self {
|
fn from(val: ParsingError<&'i str>) -> Self {
|
||||||
Self::new("Parsing error").set_summary(format!(
|
Self::new("Parsing error")
|
||||||
|
.set_summary(format!(
|
||||||
r#"In input: "{}...",
|
r#"In input: "{}...",
|
||||||
Error: {}"#,
|
Error: {}"#,
|
||||||
val.input.chars().take(30).collect::<String>(),
|
val.input.chars().take(30).collect::<String>(),
|
||||||
val.error
|
val.error
|
||||||
))
|
))
|
||||||
|
.set_details({
|
||||||
|
#[cfg(any(test, doc))]
|
||||||
|
{
|
||||||
|
println!(
|
||||||
|
"\tInput:\n{}\tError:\n{}\n\tBacktrace:\n{}",
|
||||||
|
val.input.chars().take(30).collect::<String>(),
|
||||||
|
val.error,
|
||||||
|
val.backtrace
|
||||||
|
);
|
||||||
|
val.backtrace.to_string()
|
||||||
|
}
|
||||||
|
#[cfg(not(any(test, doc)))]
|
||||||
|
{
|
||||||
|
""
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user