use super::{
arguments::DecodeArgs,
decoder::{self, Arity, Limits},
};
pub use ic_platform_macros::{codec_query as query, codec_update as update};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum EmptyArgs {
Reject,
Unit,
}
pub fn admit_len(actual: usize, limits: Limits) -> Result<(), decoder::Error> {
if actual > limits.bytes {
Err(decoder::Error::Limit)
} else {
Ok(())
}
}
pub fn decode<'a, T: DecodeArgs<'a>>(
bytes: &'a [u8],
mut limits: Limits,
empty: EmptyArgs,
arity: Arity,
) -> Result<T, decoder::Error> {
admit_len(bytes.len(), limits)?;
let bytes = if bytes.is_empty() && empty == EmptyArgs::Unit {
let empty = crate::candid_args::empty();
limits.bytes = limits.bytes.max(empty.len());
empty
} else {
bytes
};
decoder::decode_args(bytes, limits, arity)
}
pub fn read<T: for<'a> DecodeArgs<'a>>(
limits: Limits,
empty: EmptyArgs,
arity: Arity,
) -> Result<T, decoder::Error> {
admit_len(crate::ic0::msg_arg_data_size(), limits)?;
let bytes = crate::cdk::api::msg_arg_data();
decode(&bytes, limits, empty, arity)
}
#[cfg(test)]
mod tests;