Skip to content

Commit

Permalink
Move TaggedParser methods from_ber_and_then (and _der) to Any
Browse files Browse the repository at this point in the history
  • Loading branch information
chifflier committed May 23, 2022
1 parent 4689ebe commit 0c0a4aa
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 53 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ It also adds a lot of tests to improve code coverage.
asn1-rs:

- Add helper types for Application/Private tagged values
- TaggedParser: remove constraints `from_ber_and_then` (and `_der`)
- Any: add methods `from_ber_and_then` (and `_der`)
- TaggedParser: add documentation for `from_ber_and_then` (and `_der`)
- Oid: add method `starts_with`
- Fix documentation of application and private tagged helpers
- Fix clippy warnings
Expand Down
48 changes: 48 additions & 0 deletions src/asn1_types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,54 @@ impl<'a> Any<'a> {
T::from_ber(self.data)
}

/// Parse a BER value and apply the provided parsing function to content
///
/// After parsing, the sequence object and header are discarded.
pub fn from_ber_and_then<F, T, E>(
class: Class,
tag: u32,
bytes: &'a [u8],
op: F,
) -> ParseResult<'a, T, E>
where
F: FnOnce(&'a [u8]) -> ParseResult<T, E>,
E: From<Error>,
{
let (rem, any) = Any::from_ber(bytes).map_err(Err::convert)?;
any.tag()
.assert_eq(Tag(tag))
.map_err(|e| nom::Err::Error(e.into()))?;
any.class()
.assert_eq(class)
.map_err(|e| nom::Err::Error(e.into()))?;
let (_, res) = op(any.data)?;
Ok((rem, res))
}

/// Parse a DER value and apply the provided parsing function to content
///
/// After parsing, the sequence object and header are discarded.
pub fn from_der_and_then<F, T, E>(
class: Class,
tag: u32,
bytes: &'a [u8],
op: F,
) -> ParseResult<'a, T, E>
where
F: FnOnce(&'a [u8]) -> ParseResult<T, E>,
E: From<Error>,
{
let (rem, any) = Any::from_der(bytes).map_err(Err::convert)?;
any.tag()
.assert_eq(Tag(tag))
.map_err(|e| nom::Err::Error(e.into()))?;
any.class()
.assert_eq(class)
.map_err(|e| nom::Err::Error(e.into()))?;
let (_, res) = op(any.data)?;
Ok((rem, res))
}

#[inline]
pub fn parse_der<T>(&'a self) -> ParseResult<'a, T>
where
Expand Down
40 changes: 40 additions & 0 deletions src/asn1_types/tagged/explicit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,46 @@ impl<'a, T, E> TaggedParser<'a, Explicit, T, E> {
_e: PhantomData,
}
}

/// Parse a BER tagged value and apply the provided parsing function to content
///
/// After parsing, the sequence object and header are discarded.
///
/// Note: this function is provided for `Explicit`, but there is not difference between
/// explicit or implicit tags. The `op` function is responsible of handling the content.
#[inline]
pub fn from_ber_and_then<F>(
class: Class,
tag: u32,
bytes: &'a [u8],
op: F,
) -> ParseResult<'a, T, E>
where
F: FnOnce(&'a [u8]) -> ParseResult<T, E>,
E: From<Error>,
{
Any::from_ber_and_then(class, tag, bytes, op)
}

/// Parse a DER tagged value and apply the provided parsing function to content
///
/// After parsing, the sequence object and header are discarded.
///
/// Note: this function is provided for `Explicit`, but there is not difference between
/// explicit or implicit tags. The `op` function is responsible of handling the content.
#[inline]
pub fn from_der_and_then<F>(
class: Class,
tag: u32,
bytes: &'a [u8],
op: F,
) -> ParseResult<'a, T, E>
where
F: FnOnce(&'a [u8]) -> ParseResult<T, E>,
E: From<Error>,
{
Any::from_der_and_then(class, tag, bytes, op)
}
}

impl<'a, T, E> FromBer<'a, E> for TaggedParser<'a, Explicit, T, E>
Expand Down
52 changes: 0 additions & 52 deletions src/asn1_types/tagged/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,58 +37,6 @@ impl<'a, TagKind, T, E> TaggedParser<'a, TagKind, T, E> {
pub const fn tag(&self) -> Tag {
self.header.tag
}

/// Parse a BER tagged value and apply the provided parsing function to content
///
/// After parsing, the sequence object and header are discarded.
///
/// Note: there is not difference between explicit or implicit tags.
pub fn from_ber_and_then<F>(
class: Class,
tag: u32,
bytes: &'a [u8],
op: F,
) -> ParseResult<'a, T, E>
where
F: FnOnce(&'a [u8]) -> ParseResult<T, E>,
E: From<Error>,
{
let (rem, any) = Any::from_ber(bytes).map_err(Err::convert)?;
any.tag()
.assert_eq(Tag(tag))
.map_err(|e| nom::Err::Error(e.into()))?;
any.class()
.assert_eq(class)
.map_err(|e| nom::Err::Error(e.into()))?;
let (_, res) = op(any.data)?;
Ok((rem, res))
}

/// Parse a DER tagged value and apply the provided parsing function to content
///
/// After parsing, the sequence object and header are discarded.
///
/// Note: there is not difference between explicit or implicit tags.
pub fn from_der_and_then<F>(
class: Class,
tag: u32,
bytes: &'a [u8],
op: F,
) -> ParseResult<'a, T, E>
where
F: FnOnce(&'a [u8]) -> ParseResult<T, E>,
E: From<Error>,
{
let (rem, any) = Any::from_der(bytes).map_err(Err::convert)?;
any.tag()
.assert_eq(Tag(tag))
.map_err(|e| nom::Err::Error(e.into()))?;
any.class()
.assert_eq(class)
.map_err(|e| nom::Err::Error(e.into()))?;
let (_, res) = op(any.data)?;
Ok((rem, res))
}
}

impl<'a, TagKind, T, E> AsRef<T> for TaggedParser<'a, TagKind, T, E> {
Expand Down

0 comments on commit 0c0a4aa

Please sign in to comment.