use std::any::type_name;
use anyhow::Error;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
#[cfg_attr(
feature = "__plugin",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[cfg_attr(feature = "__plugin", derive(bytecheck::CheckBytes))]
#[cfg_attr(feature = "__plugin", repr(u32))]
#[cfg_attr(feature = "encoding-impl", derive(crate::Encode, crate::Decode))]
pub enum PluginError {
SizeInteropFailure(String),
Deserialize(String),
Serialize(String),
}
pub struct PluginSerializedBytes {
pub(crate) field: Vec<u8>,
}
#[cfg(feature = "__plugin")]
impl PluginSerializedBytes {
#[tracing::instrument(level = "info", skip_all)]
pub fn from_bytes(field: Vec<u8>) -> PluginSerializedBytes {
PluginSerializedBytes { field }
}
#[tracing::instrument(level = "info", skip_all)]
pub fn try_serialize<W>(t: &VersionedSerializable<W>) -> Result<Self, Error>
where
W: cbor4ii::core::enc::Encode,
{
let mut buf = cbor4ii::core::utils::BufWriter::new(Vec::new());
t.0.encode(&mut buf)?;
Ok(PluginSerializedBytes {
field: buf.into_inner(),
})
}
#[tracing::instrument(level = "info", skip_all)]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn from_raw_ptr(
raw_allocated_ptr: *const u8,
raw_allocated_ptr_len: usize,
) -> PluginSerializedBytes {
let raw_ptr_bytes =
unsafe { std::slice::from_raw_parts(raw_allocated_ptr, raw_allocated_ptr_len) };
PluginSerializedBytes::from_bytes(raw_ptr_bytes.to_vec())
}
pub fn as_slice(&self) -> &[u8] {
self.field.as_slice()
}
pub fn as_ptr(&self) -> (*const u8, usize) {
(self.field.as_ptr(), self.field.len())
}
#[tracing::instrument(level = "info", skip_all)]
pub fn deserialize<W>(&self) -> Result<VersionedSerializable<W>, Error>
where
W: for<'de> cbor4ii::core::dec::Decode<'de>,
{
use anyhow::Context;
let mut buf = cbor4ii::core::utils::SliceReader::new(&self.field);
let deserialized = <W>::decode(&mut buf)
.with_context(|| format!("failed to deserialize `{}`", type_name::<W>()))?;
Ok(VersionedSerializable(deserialized))
}
}
#[cfg_attr(
feature = "__plugin",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[repr(transparent)]
#[cfg_attr(feature = "__plugin", derive(bytecheck::CheckBytes))]
#[derive(Debug)]
pub struct VersionedSerializable<T>(
))]
pub T,
);
impl<T> VersionedSerializable<T> {
pub fn new(value: T) -> Self {
Self(value)
}
pub fn inner(&self) -> &T {
&self.0
}
pub fn into_inner(self) -> T {
self.0
}
}
pub struct ResultValue<R, E>(pub Result<R, E>);
#[cfg(feature = "encoding-impl")]
impl<R, E> cbor4ii::core::enc::Encode for ResultValue<R, E>
where
R: cbor4ii::core::enc::Encode,
E: cbor4ii::core::enc::Encode,
{
#[inline]
fn encode<W: cbor4ii::core::enc::Write>(
&self,
writer: &mut W,
) -> Result<(), cbor4ii::core::enc::Error<W::Error>> {
use cbor4ii::core::types::Tag;
match &self.0 {
Ok(t) => Tag(1, t).encode(writer),
Err(t) => Tag(0, t).encode(writer),
}
}
}
#[cfg(feature = "encoding-impl")]
impl<'de, T, E> cbor4ii::core::dec::Decode<'de> for ResultValue<T, E>
where
T: cbor4ii::core::dec::Decode<'de>,
E: cbor4ii::core::dec::Decode<'de>,
{
#[inline]
fn decode<R: cbor4ii::core::dec::Read<'de>>(
reader: &mut R,
) -> Result<Self, cbor4ii::core::dec::Error<R::Error>> {
let tag = cbor4ii::core::types::Tag::tag(reader)?;
match tag {
0 => E::decode(reader).map(Result::Err).map(ResultValue),
1 => T::decode(reader).map(Result::Ok).map(ResultValue),
_ => Err(cbor4ii::core::error::DecodeError::Mismatch {
name: &"ResultValue",
found: tag.to_le_bytes()[0],
}),
}
}
}