ic-backup 0.63.0

Host-side snapshot backup and same-release recovery for Internet Computer canisters
Documentation
//! Private field mappings; Platform owns binary parsing, traversal and accounting.

use ic_platform::candid_codec::{
    Encode, Error, Type, Writer,
    decoder::{self, Decode, Reader},
};

pub(crate) struct BoundedVec<T, const N: usize>(pub(crate) Vec<T>);
impl<T: Encode, const N: usize> Encode for BoundedVec<T, N> {
    const TYPE: &'static Type = <Vec<T> as Encode>::TYPE;
    fn write(&self, out: &mut Writer) -> Result<(), Error> {
        self.0.write(out)
    }
}
impl<'a, T: Decode<'a>, const N: usize> Decode<'a> for BoundedVec<T, N> {
    fn read(reader: &mut Reader<'a>, wire: i64) -> Result<Self, decoder::Error> {
        reader.bounded_vec(wire, N).map(Self)
    }
}

pub(crate) struct StrictOption<T>(pub(crate) Option<T>);
impl<T: Encode> Encode for StrictOption<T> {
    const TYPE: &'static Type = <Option<T> as Encode>::TYPE;
    fn write(&self, out: &mut Writer) -> Result<(), Error> {
        self.0.write(out)
    }
}
// Preserve recognized Candid option promotion and null/reserved absence from
// retained metadata frames. A failed inner type is malformed here, so the generic
// option decoder cannot silently coerce an unknown variant into None.
struct RequiredValue<T>(T);
impl<T: Encode> Encode for RequiredValue<T> {
    const TYPE: &'static Type = T::TYPE;
    fn write(&self, out: &mut Writer) -> Result<(), Error> {
        self.0.write(out)
    }
}
impl<'a, T: Decode<'a>> Decode<'a> for RequiredValue<T> {
    fn read(reader: &mut Reader<'a>, wire: i64) -> Result<Self, decoder::Error> {
        T::read(reader, wire)
            .map(Self)
            .map_err(|error| match error {
                decoder::Error::Type => decoder::Error::Malformed,
                other => other,
            })
    }
}
impl<'a, T: Decode<'a>> Decode<'a> for StrictOption<T> {
    fn read(reader: &mut Reader<'a>, wire: i64) -> Result<Self, decoder::Error> {
        if matches!(wire, -1 | -16) {
            return Ok(Self(None));
        }
        Option::<RequiredValue<T>>::read(reader, wire).map(|value| Self(value.map(|value| value.0)))
    }
    fn missing() -> Result<Self, decoder::Error> {
        Ok(Self(None))
    }
}

pub(crate) struct StrictReserved;
impl Encode for StrictReserved {
    const TYPE: &'static Type = &Type::Primitive(-16);
    fn write(&self, _: &mut Writer) -> Result<(), Error> {
        Ok(())
    }
}
impl<'a> Decode<'a> for StrictReserved {
    fn read(_: &mut Reader<'a>, wire: i64) -> Result<Self, decoder::Error> {
        if wire == -16 {
            Ok(Self)
        } else {
            Err(decoder::Error::Type)
        }
    }
}