use super::ImageRef;
use crate::{Manifest, Payload, RestoreInfo, Tag};
use alloc::{boxed::Box, vec::Vec};
use der::{
referenced::{OwnedToRef, RefToOwned},
Decode, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Writer,
};
#[derive(Clone, Debug)]
pub struct Image {
pub(super) payload: Payload,
pub(super) manifest: Option<Box<Manifest>>,
pub(super) restore_info: Option<RestoreInfo>,
}
impl Image {
pub fn new(tag: Tag, builder_string: &str, data: Vec<u8>) -> der::Result<Self> {
Ok(Self {
payload: Payload::new(tag, builder_string, data)?,
manifest: None,
restore_info: None,
})
}
pub fn from_payload(payload: Payload) -> Self {
Self {
payload,
manifest: None,
restore_info: None,
}
}
pub fn from_payload_bytes(bytes: &[u8]) -> der::Result<Self> {
Ok(Self {
payload: Payload::from_der(bytes)?,
manifest: None,
restore_info: None,
})
}
pub fn parse_manifest(&mut self, bytes: &[u8]) -> der::Result<()> {
self.manifest = Some(Box::new(Manifest::from_der(bytes)?));
Ok(())
}
pub fn payload(&self) -> &Payload {
&self.payload
}
pub fn payload_mut(&mut self) -> &mut Payload {
&mut self.payload
}
pub fn manifest(&self) -> Option<&Manifest> {
self.manifest.as_deref()
}
pub fn manifest_mut(&mut self) -> Option<&mut Manifest> {
self.manifest.as_deref_mut()
}
pub fn set_manifest(&mut self, manifest: Option<Box<Manifest>>) -> Option<Box<Manifest>> {
core::mem::replace(&mut self.manifest, manifest)
}
pub fn restore_info(&self) -> Option<&RestoreInfo> {
self.restore_info.as_ref()
}
pub fn restore_info_mut(&mut self) -> Option<&mut RestoreInfo> {
self.restore_info.as_mut()
}
pub fn set_restore_info(&mut self, restore_info: Option<RestoreInfo>) {
self.restore_info = restore_info;
}
pub fn decode_after_magic<'a, R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
ImageRef::decode_after_magic(decoder).map(Into::into)
}
}
impl FixedTag for Image {
const TAG: der::Tag = der::Tag::Sequence;
}
impl<'a> DecodeValue<'a> for Image {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
ImageRef::decode_value(reader, header).map(Into::into)
}
}
impl EncodeValue for Image {
fn value_len(&self) -> der::Result<Length> {
ImageRef::from(self).value_len()
}
fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
ImageRef::from(self).encode_value(encoder)
}
}
impl From<&'_ ImageRef<'_>> for Image {
fn from(value: &'_ ImageRef<'_>) -> Self {
Self {
payload: value.payload.ref_to_owned(),
manifest: value.manifest.as_ref().map(|m| Box::new(m.ref_to_owned())),
restore_info: value.restore_info.as_ref().map(RefToOwned::ref_to_owned),
}
}
}
impl From<ImageRef<'_>> for Image {
fn from(value: ImageRef<'_>) -> Self {
(&value).into()
}
}
impl OwnedToRef for Image {
type Borrowed<'a> = ImageRef<'a>;
fn owned_to_ref(&self) -> Self::Borrowed<'_> {
self.into()
}
}