1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use super::{ Result, Asn1DerError, DerObject, FromDerObject };

#[inline] #[doc(hidden)]
pub fn parse_next<T: FromDerObject>(iter: &mut Iterator<Item = &DerObject>) -> Result<T> {
	let der_object = some_or!(iter.next(), throw_err!(Asn1DerError::NotEnoughBytes));
	Ok(try_err!(T::from_der_object(der_object.clone())))
}

/// This macro helps you to implement the DER-conversion-traits on your own structs
///
/// Usage: `asn1_der_impl!(StructName{ field0_name, field1_name, ..., fieldN_name })`
///
/// Example:
///
/// ```ignore
/// struct Address {
/// 	street: String,
/// 	house_number: u64,
/// 	postal_code: u64,
/// 	state: String,
/// 	country: String
/// }
/// asn1_der_impl!(Address{ street, house_number, postal_code, state, country }); // Now our struct supports all DER-conversion-traits
///
/// struct Customer {
/// 	name: String,
/// 	e_mail_address: String,
/// 	postal_address: Address
/// }
/// asn1_der_impl!(Customer{ name, e_mail_address, postal_address }); // Now this struct supports all DER-conversion-traits too! It's only necessary that all fields implement the DER-conversion-traits
///
/// // Serialization:
/// let encoded = my_customer.clone().into_der_encoded(); // This returns a vector containing the DER-encoded representation of this customer (a sequence containing the struct's fields)
///
/// // Parsing:
/// let my_decoded_customer = Customer::from_der_encoded(encoded).unwrap(); // This returns our customer (if the data is valid)
/// ```
#[macro_export]
macro_rules! asn1_der_impl {
    ($struct_name:ident { $($field_name:ident),+ }) => {
    	impl $crate::FromDerObject for $struct_name {
    		fn from_der_object(der_object: $crate::DerObject) -> $crate::Result<Self> {
    			let seq = try_err!(Vec::<$crate::DerObject>::from_der_object(der_object));
    			let mut seq_iter = seq.iter();
    			
    			Ok($struct_name {
    				$($field_name: try_err!($crate::macros::parse_next(&mut seq_iter))),+
    			})
    		}
    	}
    	impl $crate::FromDerEncoded for $struct_name {
			fn from_der_encoded(data: Vec<u8>) -> $crate::Result<Self> {
				let der_object: $crate::DerObject = try_err!($crate::DerObject::from_der_encoded(data));
				Ok(try_err!(Self::from_der_object(der_object)))
			}
			fn with_der_encoded(data: &[u8]) -> $crate::Result<Self> {
				let der_object: $crate::DerObject = try_err!($crate::DerObject::with_der_encoded(data));
				Ok(try_err!(Self::from_der_object(der_object)))
			}
		}
    	
    	impl $crate::IntoDerObject for $struct_name {
    		fn into_der_object(self) -> $crate::DerObject {
    			let mut seq = Vec::new();
    			$(seq.push(self.$field_name.into_der_object());)+;
    			seq.into_der_object()
    		}
    	}
    	impl $crate::IntoDerEncoded for $struct_name {
			fn into_der_encoded(self) -> Vec<u8> {
				self.into_der_object().into_der_encoded()
			}
		}
    };
}