use crate::types::{GeneralName, GeneralNames};
use crate::yasna::{BERDecodable, BERReader, DERWriter, Tag};
use crate::{ASN1Result, DerWrite};
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Role<'a> {
pub role_authority: Option<GeneralNames<'a>>,
pub role_name: GeneralName<'a>,
}
impl Role<'_> {
const TAG_ROLE_AUTHORITY: u64 = 0;
const TAG_ROLE_NAME: u64 = 1;
}
impl DerWrite for Role<'_> {
fn write(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
if let Some(role_authority) = self.role_authority.as_ref() {
writer
.next()
.write_tagged_implicit(Tag::context(Self::TAG_ROLE_AUTHORITY), |w| {
role_authority.write(w)
})
};
writer
.next()
.write_tagged(Tag::context(Self::TAG_ROLE_NAME), |w| self.role_name.write(w))
});
}
}
impl BERDecodable for Role<'_> {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let role_authority = reader.read_optional(|r_optional| {
r_optional.read_tagged_implicit(Tag::context(Self::TAG_ROLE_AUTHORITY), |r| {
GeneralNames::decode_ber(r)
})
})?;
let role_name = reader
.next()
.read_tagged(Tag::context(Self::TAG_ROLE_NAME), |r| GeneralName::decode_ber(r))?;
Ok(Role {
role_authority,
role_name,
})
})
}
}
#[cfg(test)]
mod tests {
use b64_ct::{ToBase64, STANDARD};
use crate::{FromDer, ToDer};
use super::*;
#[test]
fn role_construct() {
let example = Role {
role_authority: None,
role_name: GeneralName::RegisteredID(vec![1, 2, 3, 4, 5, 6, 7, 8, 9].into()),
};
let der = example.to_der();
println!("{}", der.to_base64(STANDARD));
let example_decode = Role::from_der(&der).expect("from der");
assert_eq!(example_decode, example);
}
}