use crate::error as asn1err;
use crate::tag::Tag;
use crate::traits::Asn1Object;
use std::ops::{Deref, DerefMut};
pub static SET_OF_TAG_NUMBER: u8 = 0x11;
#[derive(Debug, Default, Clone, PartialEq)]
pub struct SetOf<T>(pub Vec<T>);
pub fn setof_tag() -> Tag {
return Tag::new_constructed_universal(SET_OF_TAG_NUMBER);
}
impl<T> Deref for SetOf<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for SetOf<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: Asn1Object> Asn1Object for SetOf<T> {
fn tag() -> Tag {
return setof_tag();
}
fn build_value(&self) -> Vec<u8> {
let mut value: Vec<u8> = Vec::new();
for item in self.iter() {
value.append(&mut item.build())
}
return value;
}
fn parse_value(&mut self, raw: &[u8]) -> asn1err::Result<()> {
let mut components: Vec<T> = Vec::new();
let mut raw = raw;
while !raw.is_empty() {
let (raw_tmp, component) = T::parse(raw)?;
raw = raw_tmp;
components.push(component);
}
self.0 = components;
return Ok(());
}
}
#[cfg(test)]
mod tests {
use super::super::integer::{Integer, INTEGER_TAG_NUMBER};
use super::*;
#[test]
fn test_build_set_of_integers() {
let mut seq_of: SetOf<Integer> = SetOf::default();
seq_of.push(Integer::from(9));
seq_of.push(Integer::from(1000));
assert_eq!(
vec![
0x31,
0x7,
INTEGER_TAG_NUMBER,
0x1,
0x9,
INTEGER_TAG_NUMBER,
0x2,
0x3,
0xe8
],
seq_of.build()
);
}
#[test]
fn test_build_empty_set_of() {
let seq_of: SetOf<Integer> = SetOf::default();
assert_eq!(vec![0x31, 0x0], seq_of.build());
}
#[test]
fn test_parse_sequence_of_integers() {
let (_, seq_of) = SetOf::<Integer>::parse(&[
0x31,
0x7,
INTEGER_TAG_NUMBER,
0x1,
0x9,
INTEGER_TAG_NUMBER,
0x2,
0x3,
0xe8,
])
.unwrap();
assert_eq!(Integer::from(9), seq_of[0]);
assert_eq!(Integer::from(1000), seq_of[1]);
}
#[test]
fn test_parse_empty_sequence() {
let (_, seq_of) = SetOf::<Integer>::parse(&[0x31, 0x0]).unwrap();
assert_eq!(0, seq_of.len());
}
#[test]
fn test_parse_integers_with_excesive_bytes() {
let raw = [
0x31,
0x7,
INTEGER_TAG_NUMBER,
0x1,
0x9,
INTEGER_TAG_NUMBER,
0x2,
0x3,
0xe8,
0xff,
0xff,
];
let (rest, seq_of) = SetOf::<Integer>::parse(&raw).unwrap();
let x: &[u8] = &[0xff, 0xff];
assert_eq!(x, rest);
assert_eq!(Integer::from(9), seq_of[0]);
assert_eq!(Integer::from(1000), seq_of[1]);
}
#[should_panic(expected = "UnmatchedTag")]
#[test]
fn test_parse_with_invalid_sequence_of_tag() {
SetOf::<Integer>::parse(&[0xff, 0x0]).unwrap();
}
#[should_panic(expected = "UnmatchedTag")]
#[test]
fn test_parse_with_invalid_inner_type_tag() {
SetOf::<Integer>::parse(&[0x31, 0x3, 0xff, 0x1, 0x9]).unwrap();
}
}