red_asn1 0.4.2

A little library to encode/decode ASN1 DER
Documentation
use crate::types::integer::Asn1Int;
use crate::error as asn1err;
use crate::tag::Tag;
use crate::traits::Asn1Object;
use std::ops::{Deref, DerefMut};

pub static ENUMERATED_TAG_NUMBER: u8 = 0x0a;

#[derive(Clone, Debug, Default, PartialEq)]
pub struct Enumerated<T: Asn1Int>(T);

impl<T: Asn1Int> Enumerated<T> {
    pub fn new(v: T) -> Self {
        return Self(v);
    }
}

impl<T: Asn1Int> Deref for Enumerated<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T: Asn1Int> DerefMut for Enumerated<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl<T: Asn1Int> Asn1Object for Enumerated<T> {
    fn tag() -> Tag {
        return Tag::new_primitive_universal(ENUMERATED_TAG_NUMBER);
    }

    fn build_value(&self) -> Vec<u8> {
        return self.0.build_int_value();
    }

    fn parse_value(&mut self, raw: &[u8]) -> asn1err::Result<()> {
        self.0 = T::parse_int_value(raw)?;
        return Ok(());
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_build() {
        assert_eq!(vec![0xa, 0x1, 0x0], Enumerated::new(0 as u32).build());
        assert_eq!(vec![0xa, 0x1, 0x1], Enumerated::new(1 as u32).build());
        assert_eq!(
            vec![0xa, 0x1, 0xff],
            Enumerated::new((-1i32) as u32).build()
        );

        assert_eq!(vec![0xa, 0x1, 0x7F], Enumerated::new(127 as u32).build());
        assert_eq!(
            vec![0xa, 0x2, 0x00, 0x80],
            Enumerated::new(128 as u32).build()
        );
        assert_eq!(
            vec![0xa, 0x2, 0x01, 0x00],
            Enumerated::new(256 as u32).build()
        );
        assert_eq!(
            vec![0xa, 0x1, 0x80],
            Enumerated::new(-128i32 as u32).build()
        );
        assert_eq!(
            vec![0xa, 0x2, 0xFF, 0x7F],
            Enumerated::new(-129i32 as u32).build()
        );

        assert_eq!(
            vec![0xa, 0x4, 0xF8, 0x45, 0x33, 0x8],
            Enumerated::new(4165284616 as u32).build()
        );
    }

    #[test]
    fn test_parse() {
        assert_eq!(
            Enumerated::new(0 as u32),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x0]).unwrap().1
        );
        assert_eq!(
            Enumerated::new(1 as u32),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x1]).unwrap().1
        );
        assert_eq!(
            Enumerated::new(-1i32 as u32),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0xff]).unwrap().1
        );

        assert_eq!(
            Enumerated::new(127 as u32),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x7F]).unwrap().1
        );
        assert_eq!(
            Enumerated::new(128u32),
            Enumerated::<u32>::parse(&[0xa, 0x2, 0x00, 0x80]).unwrap().1
        );
        assert_eq!(
            Enumerated::new(256u32),
            Enumerated::<u32>::parse(&[0xa, 0x2, 0x01, 0x00]).unwrap().1
        );
        assert_eq!(
            Enumerated::new(-128i32 as u32),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x80]).unwrap().1
        );
        assert_eq!(
            Enumerated::new(-129i32 as u32),
            Enumerated::<u32>::parse(&[0xa, 0x2, 0xFF, 0x7F]).unwrap().1
        );

        assert_eq!(
            Enumerated::new(4165284616u32),
            Enumerated::<u32>::parse(&[0xa, 0x4, 0xF8, 0x45, 0x33, 0x8])
                .unwrap()
                .1
        );
    }

    #[test]
    fn test_parse_with_excesive_bytes() {
        let x: &[u8] = &[0x22];
        assert_eq!(
            (x, Enumerated::new(0)),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x0, 0x22]).unwrap()
        );
        assert_eq!(
            (x, Enumerated::new(1)),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x1, 0x22]).unwrap()
        );
        assert_eq!(
            (x, Enumerated::new(-1i32 as u32)),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0xff, 0x22]).unwrap()
        );

        assert_eq!(
            (x, Enumerated::new(127)),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x7F, 0x22]).unwrap()
        );
        assert_eq!(
            (x, Enumerated::new(128)),
            Enumerated::<u32>::parse(&[0xa, 0x2, 0x00, 0x80, 0x22]).unwrap()
        );
        assert_eq!(
            (x, Enumerated::new(256u32)),
            Enumerated::<u32>::parse(&[0xa, 0x2, 0x01, 0x00, 0x22]).unwrap()
        );
        assert_eq!(
            (x, Enumerated::new(-128i32 as u32)),
            Enumerated::<u32>::parse(&[0xa, 0x1, 0x80, 0x22]).unwrap()
        );
        assert_eq!(
            (x, Enumerated::new(-129i32 as u32)),
            Enumerated::<u32>::parse(&[0xa, 0x2, 0xFF, 0x7F, 0x22]).unwrap()
        );

        assert_eq!(
            (x, Enumerated::new(4165284616u32)),
            Enumerated::<u32>::parse(&[0xa, 0x4, 0xF8, 0x45, 0x33, 0x8, 0x22])
                .unwrap()
        );
    }

    #[should_panic(expected = "UnmatchedTag")]
    #[test]
    fn test_parse_with_invalid_tag() {
        Enumerated::<u32>::parse(&[0x7, 0x1, 0x0]).unwrap();
    }

    #[should_panic(expected = "IncorrectValue(\"No octets for i32\")")]
    #[test]
    fn test_parse_without_enough_value_octets() {
        Enumerated::<u32>::parse(&[0xa, 0x0]).unwrap();
    }

    #[should_panic(
        expected = "IncorrectValue(\"Too many octets for i32: 9 octets\")"
    )]
    #[test]
    fn test_parse_with_too_much_value_octets() {
        Enumerated::<u32>::parse(&[
            0xa, 9, 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
        ])
        .unwrap();
    }

    #[test]
    fn test_parse_with_the_limit_of_value_octets() {
        Enumerated::<u32>::parse(&[0xa, 4, 0, 0x1, 0x2, 0x3]).unwrap();
    }
}