Skip to content

Commit

Permalink
Improve debug+trace, and require Display+Debug on errors
Browse files Browse the repository at this point in the history
  • Loading branch information
chifflier committed Mar 14, 2024
1 parent 7ed4a85 commit e16a494
Show file tree
Hide file tree
Showing 9 changed files with 304 additions and 155 deletions.
48 changes: 31 additions & 17 deletions src/asn1_types/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,26 @@ macro_rules! impl_int {
type Error = Error;

fn try_from(any: &'b Any<'a>) -> Result<Self> {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_primitive()?;
let uint = if is_highest_bit_set(any.as_bytes()) {
<$uint>::from_be_bytes(decode_array_int(&any)?)
} else {
// read as uint, but check if the value will fit in a signed integer
let u = <$uint>::from_be_bytes(decode_array_uint(&any)?);
if u > <$int>::MAX as $uint {
return Err(Error::IntegerTooLarge);
}
u
};
Ok(uint as $int)
$crate::debug::trace_generic(
core::any::type_name::<$int>(),
"Conversion to int",
|any| {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_primitive()?;
let uint = if is_highest_bit_set(any.as_bytes()) {
<$uint>::from_be_bytes(decode_array_int(&any)?)
} else {
// read as uint, but check if the value will fit in a signed integer
let u = <$uint>::from_be_bytes(decode_array_uint(&any)?);
if u > <$int>::MAX as $uint {
return Err(Error::IntegerTooLarge);
}
u
};
Ok(uint as $int)
},
any,
)
}
}

Expand Down Expand Up @@ -162,10 +169,17 @@ macro_rules! impl_uint {
type Error = Error;

fn try_from(any: &'b Any<'a>) -> Result<Self> {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_primitive()?;
let result = Self::from_be_bytes(decode_array_uint(any)?);
Ok(result)
$crate::debug::trace_generic(
core::any::type_name::<$ty>(),
"Conversion to uint",
|any| {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_primitive()?;
let result = Self::from_be_bytes(decode_array_uint(any)?);
Ok(result)
},
any,
)
}
}
impl CheckDerConstraints for $ty {
Expand Down
30 changes: 19 additions & 11 deletions src/asn1_types/sequence/sequence_of.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::*;
use alloc::vec::Vec;

Check warning on line 2 in src/asn1_types/sequence/sequence_of.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

the item `Vec` is imported redundantly
use core::convert::TryFrom;
use core::fmt::{Debug, Display};
use core::iter::FromIterator;
use core::ops::{Deref, DerefMut};

use self::debug::trace;
use self::debug::{trace, trace_generic};

/// The `SEQUENCE OF` object is an ordered list of homogeneous types.
///
Expand Down Expand Up @@ -130,18 +131,25 @@ where
impl<'a, T, E> FromDer<'a, E> for SequenceOf<T>
where
T: FromDer<'a, E>,
E: From<Error>,
E: From<Error> + Display + Debug,
{
fn from_der(bytes: &'a [u8]) -> ParseResult<Self, E> {
let (rem, any) =
trace(core::any::type_name::<Self>(), parse_der_any, bytes).map_err(Err::convert)?;
any.header
.assert_tag(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;
let items = SequenceIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<Vec<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, SequenceOf::new(items)))
trace_generic(
core::any::type_name::<Self>(),
"SequenceOf::from_der",
|bytes| {
let (rem, any) = trace(core::any::type_name::<Self>(), parse_der_any, bytes)
.map_err(Err::convert)?;
any.header
.assert_tag(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;

Check failure on line 145 in src/asn1_types/sequence/sequence_of.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

unnecessary qualification
let items = SequenceIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<Vec<T>, E>>()
.map_err(nom::Err::Error)?;

Check failure on line 148 in src/asn1_types/sequence/sequence_of.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

unnecessary qualification
Ok((rem, SequenceOf::new(items)))
},
bytes,
)
}
}

Expand Down
54 changes: 39 additions & 15 deletions src/asn1_types/sequence/vec.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::*;
use alloc::vec::Vec;
use core::convert::TryFrom;
use core::fmt::Debug;

use self::debug::trace;
use self::debug::{trace, trace_generic};

// // XXX this compiles but requires bound TryFrom :/
// impl<'a, 'b, T> TryFrom<&'b Any<'a>> for Vec<T>
Expand Down Expand Up @@ -51,10 +52,26 @@ where
type Error = Error;

fn try_from(any: Any<'a>) -> Result<Self> {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_constructed()?;
let items = SetIterator::<T, BerParser>::new(any.data).collect::<Result<Vec<T>>>()?;
Ok(items)
trace_generic(
core::any::type_name::<Self>(),
"T::from(Any)",
|any| {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_constructed()?;
let items = SetIterator::<T, BerParser>::new(any.data)
.collect::<Result<Vec<T>>>()
.map_err(|e| {
debug_eprintln!(
core::any::type_name::<T>(),
"≠ {}",
"Conversion from Any failed".red()
);
e
})?;
Ok(items)
},
any,
)
}
}

Expand Down Expand Up @@ -93,18 +110,25 @@ impl<T> Tagged for Vec<T> {
impl<'a, T, E> FromDer<'a, E> for Vec<T>
where
T: FromDer<'a, E>,
E: From<Error>,
E: From<Error> + Debug,
{
fn from_der(bytes: &'a [u8]) -> ParseResult<Self, E> {
let (rem, any) =
trace(core::any::type_name::<Self>(), parse_der_any, bytes).map_err(Err::convert)?;
any.header
.assert_tag(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;
let v = SequenceIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<Vec<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, v))
trace_generic(
core::any::type_name::<Self>(),
"Sequence::from_der",
|bytes| {
let (rem, any) = trace(core::any::type_name::<Self>(), parse_der_any, bytes)
.map_err(Err::convert)?;
any.header
.assert_tag(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;

Check failure on line 124 in src/asn1_types/sequence/vec.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

unnecessary qualification
let v = SequenceIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<Vec<T>, E>>()
.map_err(nom::Err::Error)?;

Check failure on line 127 in src/asn1_types/sequence/vec.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

unnecessary qualification
Ok((rem, v))
},
bytes,
)
}
}

Expand Down
53 changes: 34 additions & 19 deletions src/asn1_types/set/btreeset.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::*;
use alloc::collections::BTreeSet;
use core::convert::TryFrom;
use core::{convert::TryFrom, fmt::Debug};

use self::debug::trace;
use self::debug::{trace, trace_generic};

impl<T> Tagged for BTreeSet<T> {
const TAG: Tag = Tag::Set;
Expand All @@ -16,10 +16,18 @@ where
type Error = Error;

fn try_from(any: Any<'a>) -> Result<Self> {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_constructed()?;
let items = SetIterator::<T, BerParser>::new(any.data).collect::<Result<BTreeSet<T>>>()?;
Ok(items)
trace_generic(
core::any::type_name::<Self>(),
"BTreeSet::from_der",
|any| {
any.tag().assert_eq(Self::TAG)?;
any.header.assert_constructed()?;
let items =
SetIterator::<T, BerParser>::new(any.data).collect::<Result<BTreeSet<T>>>()?;
Ok(items)
},
any,
)
}
}

Expand All @@ -43,21 +51,28 @@ impl<'a, T, E> FromDer<'a, E> for BTreeSet<T>
where
T: FromDer<'a, E>,
T: Ord,
E: From<Error>,
E: From<Error> + Debug,
{
fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, E> {
let (rem, any) =
trace(core::any::type_name::<Self>(), Any::from_der, bytes).map_err(Err::convert)?;
any.tag()
.assert_eq(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;
any.header
.assert_constructed()
.map_err(|e| nom::Err::Error(e.into()))?;
let items = SetIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<BTreeSet<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, items))
trace_generic(
core::any::type_name::<Self>(),
"BTreeSet::from_der",
|bytes| {
let (rem, any) = trace(core::any::type_name::<Self>(), Any::from_der, bytes)
.map_err(Err::convert)?;
any.tag()
.assert_eq(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;

Check failure on line 65 in src/asn1_types/set/btreeset.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

unnecessary qualification
any.header
.assert_constructed()
.map_err(|e| nom::Err::Error(e.into()))?;
let items = SetIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<BTreeSet<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, items))
},
bytes,
)
}
}

Expand Down
36 changes: 22 additions & 14 deletions src/asn1_types/set/hashset.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![cfg(feature = "std")]
use crate::*;
use core::fmt::Debug;
use std::collections::HashSet;
use std::convert::TryFrom;
use std::hash::Hash;

use self::debug::trace;
use self::debug::{trace, trace_generic};

impl<T> Tagged for HashSet<T> {
const TAG: Tag = Tag::Set;
Expand Down Expand Up @@ -45,21 +46,28 @@ impl<'a, T, E> FromDer<'a, E> for HashSet<T>
where
T: FromDer<'a, E>,
T: Hash + Eq,
E: From<Error>,
E: From<Error> + Debug,
{
fn from_der(bytes: &'a [u8]) -> ParseResult<'a, Self, E> {
let (rem, any) =
trace(core::any::type_name::<Self>(), Any::from_der, bytes).map_err(Err::convert)?;
any.tag()
.assert_eq(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;
any.header
.assert_constructed()
.map_err(|e| nom::Err::Error(e.into()))?;
let items = SetIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<HashSet<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, items))
trace_generic(
core::any::type_name::<Self>(),
"BTreeSet::from_der",
|bytes| {
let (rem, any) = trace(core::any::type_name::<Self>(), Any::from_der, bytes)
.map_err(Err::convert)?;
any.tag()
.assert_eq(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;
any.header
.assert_constructed()
.map_err(|e| nom::Err::Error(e.into()))?;
let items = SetIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<HashSet<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, items))
},
bytes,
)
}
}

Expand Down
30 changes: 19 additions & 11 deletions src/asn1_types/set/set_of.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::*;
use alloc::vec::Vec;
use core::convert::TryFrom;
use core::fmt::{Debug, Display};
use core::iter::FromIterator;
use core::ops::{Deref, DerefMut};

use self::debug::trace;
use self::debug::{trace, trace_generic};

/// The `SET OF` object is an unordered list of homogeneous types.
///
Expand Down Expand Up @@ -130,18 +131,25 @@ where
impl<'a, T, E> FromDer<'a, E> for SetOf<T>
where
T: FromDer<'a, E>,
E: From<Error>,
E: From<Error> + Display + Debug,
{
fn from_der(bytes: &'a [u8]) -> ParseResult<Self, E> {
let (rem, any) =
trace(core::any::type_name::<Self>(), Any::from_der, bytes).map_err(Err::convert)?;
any.header
.assert_tag(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;
let items = SetIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<Vec<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, SetOf::new(items)))
trace_generic(
core::any::type_name::<Self>(),
"SetOf::from_der",
|bytes| {
let (rem, any) = trace(core::any::type_name::<Self>(), Any::from_der, bytes)
.map_err(Err::convert)?;
any.header
.assert_tag(Self::TAG)
.map_err(|e| nom::Err::Error(e.into()))?;
let items = SetIterator::<T, DerParser, E>::new(any.data)
.collect::<Result<Vec<T>, E>>()
.map_err(nom::Err::Error)?;
Ok((rem, SetOf::new(items)))
},
bytes,
)
}
}

Expand Down
Loading

0 comments on commit e16a494

Please sign in to comment.