Skip to content

Commit

Permalink
use existing codec type
Browse files Browse the repository at this point in the history
  • Loading branch information
XAMPPRocky committed Sep 1, 2023
1 parent 9dc64bd commit 69b6111
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 74 deletions.
77 changes: 63 additions & 14 deletions src/codec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use snafu::*;

use crate::prelude::*;

use snafu::*;
pub use self::{enc::EncodeError, de::DecodeError};

/// A set of supported ASN.1 codecs. Can be used to dynamically encode types
/// into different codecs at runtime.
Expand All @@ -20,22 +22,69 @@ pub enum Codec {
}

impl Codec {
pub fn encode<T: Encode>(self, value: &T) -> Result<Vec<u8>, EncodeError> {
/// Encodes a given value based on the value of `Codec`.
///
/// # Errors
/// - If the value fails to be encoded.
pub fn encode<T: Encode>(self, value: &T) -> Result<alloc::vec::Vec<u8>, EncodeError> {
match self {
Self::Aper => crate::aper::encode(value).context(enc::AperSnafu),
Self::Ber => crate::ber::encode(value).context(enc::BerSnafu),
Self::Cer => crate::cer::encode(value).context(enc::CerSnafu),
Self::Der => crate::der::encode(value).context(enc::DerSnafu),
Self::Uper => crate::uper::encode(value).context(enc::UperSnafu),
}
}

/// Decodes `input` to `D` based on the value of `Codec`.
///
/// # Errors
/// - If `D` cannot be decoded from `input`.
pub fn decode<D: Decode>(&self, input: &[u8]) -> Result<D, DecodeError> {
match self {
Self::Aper => crate::aper::encode(value).context(AperSnafu),
Self::Ber => crate::ber::encode(value).context(BerSnafu),
Self::Cer => crate::cer::encode(value).context(CerSnafu),
Self::Der => crate::der::encode(value).context(DerSnafu),
Self::Uper => crate::uper::encode(value).context(UperSnafu),
Self::Aper => crate::aper::decode(input).context(de::AperSnafu),
Self::Ber => crate::ber::decode(input).context(de::BerSnafu),
Self::Cer => crate::cer::decode(input).context(de::CerSnafu),
Self::Der => crate::der::decode(input).context(de::DerSnafu),
Self::Uper => crate::uper::decode(input).context(de::UperSnafu),
}
}
}

#[derive(Debug, Snafu)]
pub enum EncodeError {
Aper{ source: crate::aper::enc::Error },
Ber{ source: crate::ber::enc::Error },
Cer{ source: crate::der::enc::Error },
Der{ source: crate::der::enc::Error },
Uper{ source: crate::uper::enc::Error },
mod enc {
use super::*;

#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum EncodeError {
#[snafu(display("APER Error: {}", source))]
Aper{ source: crate::aper::enc::Error },
#[snafu(display("BER Error: {}", source))]
Ber{ source: crate::ber::enc::Error },
#[snafu(display("CER Error: {}", source))]
Cer{ source: crate::der::enc::Error },
#[snafu(display("DER Error: {}", source))]
Der{ source: crate::der::enc::Error },
#[snafu(display("UPER Error: {}", source))]
Uper{ source: crate::uper::enc::Error },
}
}

mod de {
use super::*;

#[derive(Debug, Snafu)]
#[snafu(visibility(pub(crate)))]
pub enum DecodeError {
#[snafu(display("APER Error: {}", source))]
Aper{ source: crate::aper::de::Error },
#[snafu(display("BER Error: {}", source))]
Ber{ source: crate::ber::de::Error },
#[snafu(display("CER Error: {}", source))]
Cer{ source: crate::der::de::Error },
#[snafu(display("DER Error: {}", source))]
Der{ source: crate::der::de::Error },
#[snafu(display("UPER Error: {}", source))]
Uper{ source: crate::uper::de::Error },
}
}
66 changes: 9 additions & 57 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,6 @@
#![cfg_attr(not(test), no_std)]
extern crate alloc;

mod per;

pub mod de;
pub mod enc;
pub mod types;

use alloc::boxed::Box;

/// An enum representing a supported ASN.1 codec. This type can be used for
/// dynamically encoding and decoding objects at runtime.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum Codec {
/// Aligned Packed Encoding Rules
Aper,
/// Basic Encoding Rules
Ber,
/// Canonical Encoding Rules
Cer,
/// Distinguished Encoding Rules
Der,
/// Unaligned Packed Encoding Rules
Uper,
}

impl Codec {
/// Encodes a given value based on the value of `Codec`.
///
/// # Errors
/// - If the value fails to be encoded.
pub fn encode<E: Encode>(
&self,
value: &E,
) -> Result<alloc::vec::Vec<u8>, Box<dyn core::fmt::Display>> {
match self {
Self::Ber => ber::encode(value).map_err(|error| Box::new(error) as Box<_>),
Self::Cer => cer::encode(value).map_err(|error| Box::new(error) as Box<_>),
Self::Der => der::encode(value).map_err(|error| Box::new(error) as Box<_>),
Self::Uper => uper::encode(value).map_err(|error| Box::new(error) as Box<_>),
Self::Aper => aper::encode(value).map_err(|error| Box::new(error) as Box<_>),
}
}

/// Decodes `input` to `D` based on the value of `Codec`.
///
/// # Errors
/// - If `D` cannot be decoded from `input`.
pub fn decode<D: Decode>(&self, input: &[u8]) -> Result<D, Box<dyn core::fmt::Display>> {
match self {
Self::Ber => ber::decode(input).map_err(|error| Box::new(error) as Box<_>),
Self::Cer => cer::decode(input).map_err(|error| Box::new(error) as Box<_>),
Self::Der => der::decode(input).map_err(|error| Box::new(error) as Box<_>),
Self::Uper => uper::decode(input).map_err(|error| Box::new(error) as Box<_>),
Self::Aper => aper::decode(input).map_err(|error| Box::new(error) as Box<_>),
}
}
}

#[cfg(test)]
macro_rules! round_trip {
($codec:ident, $typ:ty, $value:expr, $expected:expr) => {{
Expand Down Expand Up @@ -90,8 +33,16 @@ macro_rules! round_trip_with_constraints {
}};
}

pub mod de;
pub mod enc;
pub mod types;
pub mod codec;


// Data Formats

mod per;

pub mod aper;
pub mod ber;
pub mod cer;
Expand All @@ -103,6 +54,7 @@ pub use self::{
de::{Decode, Decoder},
enc::{Encode, Encoder},
types::{AsnType, Tag, TagTree},
codec::Codec,
};

/// A prelude containing the codec traits and all types defined in the [`types`]
Expand Down
9 changes: 6 additions & 3 deletions standards/snmp/src/v3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Message {
/// - If the value fails to be encoded as the `codec`.
pub fn decode_security_parameters<T: SecurityParameters>(
&self,
codec: rasn::Codec,
codec: rasn::codec::Codec,
) -> Result<T, alloc::boxed::Box<dyn core::fmt::Display>> {
if self.global_data.security_model != T::ID.into() {
return Err(Box::new(alloc::format!(
Expand All @@ -65,6 +65,7 @@ impl Message {
}

codec.decode::<T>(&self.security_parameters)
.map_err(|error| Box::new(error) as Box<_>)
}

/// Encodes the given security parameters into the `security_parameters`
Expand All @@ -74,12 +75,14 @@ impl Message {
/// - If the value fails to be encoded as the `codec`.
pub fn encode_security_parameters<T: SecurityParameters>(
&mut self,
codec: rasn::Codec,
codec: rasn::codec::Codec,
value: &T,
) -> Result<(), alloc::boxed::Box<dyn core::fmt::Display>> {
self.global_data.security_model = T::ID.into();

self.security_parameters = codec.encode::<T>(value)?.into();
self.security_parameters = codec.encode::<T>(value)
.map_err(|error| Box::new(error) as Box<_>)?
.into();
Ok(())
}
}
Expand Down

0 comments on commit 69b6111

Please sign in to comment.