Skip to content

Commit

Permalink
Implement BerObject::try_from(Any) (Closes #67)
Browse files Browse the repository at this point in the history
  • Loading branch information
chifflier committed Feb 23, 2024
1 parent c0bcf16 commit 6781082
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/ber/ber.rs
@@ -1,6 +1,8 @@
use super::{Class, Header, Length, Tag};
use crate::ber::ber_read_element_content_as;
use crate::ber::bitstring_to_u64;
use crate::ber::integer::*;
use crate::ber::MAX_RECURSION;
use crate::error::BerError;
use crate::oid::Oid;
use alloc::borrow::ToOwned;
Expand All @@ -12,6 +14,7 @@ use asn1_rs::Any;
use bitvec::{order::Msb0, slice::BitSlice};
use core::convert::AsRef;

Check warning on line 15 in src/ber/ber.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

the item `AsRef` is imported redundantly
use core::convert::From;

Check warning on line 16 in src/ber/ber.rs

View workflow job for this annotation

GitHub Actions / Check (nightly)

the item `From` is imported redundantly
use core::convert::TryFrom;
use core::ops::Index;

/// Representation of a BER-encoded (X.690) object
Expand Down Expand Up @@ -717,6 +720,40 @@ impl<'a> BerObject<'a> {
}
}

impl<'a> TryFrom<Any<'a>> for BerObject<'a> {
type Error = asn1_rs::Error;

fn try_from(any: Any<'a>) -> Result<Self, Self::Error> {
let (header, data) = (any.header, any.data);
let (_, content) = ber_read_element_content_as(
data,
header.tag(),
header.length(),
header.constructed(),
MAX_RECURSION,
)?;
let obj = BerObject::from_header_and_content(header, content);
Ok(obj)
}
}

impl<'a, 'b> TryFrom<&'b Any<'a>> for BerObject<'a> {
type Error = asn1_rs::Error;

fn try_from(any: &'b Any<'a>) -> Result<Self, Self::Error> {
let (header, data) = (any.header.clone(), any.data);
let (_, content) = ber_read_element_content_as(
data,
header.tag(),
header.length(),
header.constructed(),
MAX_RECURSION,
)?;
let obj = BerObject::from_header_and_content(header, content);
Ok(obj)
}
}

// This is a consuming iterator
impl<'a> IntoIterator for BerObject<'a> {
type Item = BerObject<'a>;
Expand Down Expand Up @@ -843,9 +880,22 @@ impl<'a> AsRef<[u8]> for BitStringObject<'a> {

#[cfg(test)]
mod tests {
use asn1_rs::{Any, FromDer};
use core::convert::TryFrom;

use crate::ber::*;
use crate::oid::*;

#[test]
fn ber_from_any() {
let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];

let (rem, any) = Any::from_der(bytes).expect("parsing failed");
assert!(rem.is_empty());
let obj = BerObject::try_from(any).expect("try_from(any) failed");
assert_eq!(obj.as_u32(), Ok(0x10001_u32));
}

#[test]
fn test_der_as_u64() {
let der_obj = BerObject::from_int_slice(b"\x01\x00\x02");
Expand Down

0 comments on commit 6781082

Please sign in to comment.