use super::{ComprInfo, PayloadProps, PayloadRef};
use crate::Tag;
use alloc::vec::Vec;
use der::{
asn1::{Ia5String, OctetString},
referenced::{OwnedToRef, RefToOwned},
Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Writer,
};
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(Eq, PartialEq))]
pub struct Payload {
pub(super) tag_4cc: Tag,
pub(super) builder_string: Ia5String,
pub(super) data: OctetString,
pub(super) keybags: Option<OctetString>,
pub(super) compr_info: Option<ComprInfo>,
pub(super) props: Option<PayloadProps>,
}
impl<'a> Payload {
pub fn new(tag: Tag, builder_string: &str, data: Vec<u8>) -> der::Result<Self> {
Ok(Self {
tag_4cc: tag,
builder_string: Ia5String::new(builder_string)?,
data: OctetString::new(data)?,
keybags: None,
compr_info: None,
props: None,
})
}
pub fn parse(bytes: &'a [u8]) -> der::Result<Self> {
Self::from_der(bytes)
}
pub fn tag(&self) -> Tag {
self.tag_4cc
}
pub fn set_tag(&mut self, tag: Tag) {
self.tag_4cc = tag;
}
pub fn builder_string(&self) -> &str {
self.builder_string.as_str()
}
pub fn set_builder_string(&mut self, s: &'a str) -> der::Result<()> {
self.builder_string = Ia5String::new(s)?;
Ok(())
}
pub fn data(&self) -> &[u8] {
self.data.as_bytes()
}
pub fn set_data(&mut self, data: Vec<u8>) -> der::Result<()> {
self.data = OctetString::new(data)?;
Ok(())
}
pub fn keybags(&self) -> Option<&[u8]> {
self.keybags.as_ref().map(OctetString::as_bytes)
}
pub fn set_keybags(&mut self, bytes: Option<Vec<u8>>) -> der::Result<()> {
self.keybags = bytes.map(OctetString::new).transpose()?;
Ok(())
}
pub fn compr_info(&self) -> Option<&ComprInfo> {
self.compr_info.as_ref()
}
pub fn set_compr_info(&mut self, compr_info: Option<ComprInfo>) {
self.compr_info = compr_info;
}
pub fn props(&self) -> Option<&PayloadProps> {
self.props.as_ref()
}
pub fn set_props(&mut self, props: Option<PayloadProps>) {
self.props = props;
}
pub fn decode_after_magic<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
PayloadRef::decode_after_magic(decoder).map(Payload::from)
}
}
impl From<PayloadRef<'_>> for Payload {
fn from(value: PayloadRef<'_>) -> Self {
(&value).into()
}
}
impl From<&'_ PayloadRef<'_>> for Payload {
fn from(value: &'_ PayloadRef<'_>) -> Self {
Self {
tag_4cc: value.tag_4cc,
builder_string: value.builder_string.ref_to_owned(),
data: value.data.ref_to_owned(),
keybags: value.keybags.ref_to_owned(),
compr_info: value.compr_info.clone(),
props: value.props.ref_to_owned(),
}
}
}
impl OwnedToRef for Payload {
type Borrowed<'a> = PayloadRef<'a>;
fn owned_to_ref(&self) -> Self::Borrowed<'_> {
self.into()
}
}
impl<'a> DecodeValue<'a> for Payload {
fn decode_value<R: Reader<'a>>(decoder: &mut R, header: Header) -> der::Result<Self> {
PayloadRef::decode_value(decoder, header).map(Payload::from)
}
}
impl EncodeValue for Payload {
fn value_len(&self) -> der::Result<Length> {
PayloadRef::from(self).encoded_len()
}
fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
PayloadRef::from(self).encode_value(encoder)
}
}
impl FixedTag for Payload {
const TAG: der::Tag = der::Tag::Sequence;
}