From 0c0a4aaa2759069b4d2316e8230572f60d63a4c6 Mon Sep 17 00:00:00 2001 From: Pierre Chifflier Date: Mon, 23 May 2022 13:54:54 +0200 Subject: [PATCH] Move TaggedParser methods `from_ber_and_then` (and `_der`) to Any --- CHANGELOG.md | 3 +- src/asn1_types/any.rs | 48 ++++++++++++++++++++++++++++ src/asn1_types/tagged/explicit.rs | 40 ++++++++++++++++++++++++ src/asn1_types/tagged/parser.rs | 52 ------------------------------- 4 files changed, 90 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a922594..4307f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/asn1_types/any.rs b/src/asn1_types/any.rs index 5cc9588..e04a6ce 100644 --- a/src/asn1_types/any.rs +++ b/src/asn1_types/any.rs @@ -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( + class: Class, + tag: u32, + bytes: &'a [u8], + op: F, + ) -> ParseResult<'a, T, E> + where + F: FnOnce(&'a [u8]) -> ParseResult, + E: From, + { + 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( + class: Class, + tag: u32, + bytes: &'a [u8], + op: F, + ) -> ParseResult<'a, T, E> + where + F: FnOnce(&'a [u8]) -> ParseResult, + E: From, + { + 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(&'a self) -> ParseResult<'a, T> where diff --git a/src/asn1_types/tagged/explicit.rs b/src/asn1_types/tagged/explicit.rs index f06543f..aa4c093 100644 --- a/src/asn1_types/tagged/explicit.rs +++ b/src/asn1_types/tagged/explicit.rs @@ -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( + class: Class, + tag: u32, + bytes: &'a [u8], + op: F, + ) -> ParseResult<'a, T, E> + where + F: FnOnce(&'a [u8]) -> ParseResult, + E: From, + { + 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( + class: Class, + tag: u32, + bytes: &'a [u8], + op: F, + ) -> ParseResult<'a, T, E> + where + F: FnOnce(&'a [u8]) -> ParseResult, + E: From, + { + Any::from_der_and_then(class, tag, bytes, op) + } } impl<'a, T, E> FromBer<'a, E> for TaggedParser<'a, Explicit, T, E> diff --git a/src/asn1_types/tagged/parser.rs b/src/asn1_types/tagged/parser.rs index b697ba4..dab6004 100644 --- a/src/asn1_types/tagged/parser.rs +++ b/src/asn1_types/tagged/parser.rs @@ -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( - class: Class, - tag: u32, - bytes: &'a [u8], - op: F, - ) -> ParseResult<'a, T, E> - where - F: FnOnce(&'a [u8]) -> ParseResult, - E: From, - { - 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( - class: Class, - tag: u32, - bytes: &'a [u8], - op: F, - ) -> ParseResult<'a, T, E> - where - F: FnOnce(&'a [u8]) -> ParseResult, - E: From, - { - 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 for TaggedParser<'a, TagKind, T, E> {