use super::ast::ProtobufConversionError;
#[derive(Debug, thiserror::Error)]
pub enum DecodeError {
#[error(transparent)]
Proto(prost::DecodeError),
#[error(transparent)]
Conversion(ProtobufConversionError),
}
impl From<prost::DecodeError> for DecodeError {
fn from(e: prost::DecodeError) -> Self {
Self::Proto(e)
}
}
impl From<ProtobufConversionError> for DecodeError {
fn from(e: ProtobufConversionError) -> Self {
Self::Conversion(e)
}
}
pub trait Protobuf: Sized {
fn encode(&self) -> Vec<u8>;
fn decode(buf: impl prost::bytes::Buf) -> Result<Self, DecodeError>;
}
#[expect(
dead_code,
reason = "experimental feature, we might have use for this one in the future"
)]
pub(crate) fn encode<M: prost::Message>(
thing: impl Into<M>,
buf: &mut impl prost::bytes::BufMut,
) -> Result<(), prost::EncodeError> {
thing.into().encode(buf)
}
pub(crate) fn encode_to_vec<M: prost::Message>(thing: impl Into<M>) -> Vec<u8> {
thing.into().encode_to_vec()
}
use std::default::Default;
#[expect(
dead_code,
reason = "available for types with infallible From conversions"
)]
pub(crate) fn decode<M: prost::Message + Default, T: From<M>>(
buf: impl prost::bytes::Buf,
) -> Result<T, DecodeError> {
Ok(M::decode(buf)?.into())
}
pub(crate) fn try_decode<
M: prost::Message + Default,
E: Into<ProtobufConversionError>,
T: TryFrom<M, Error = E>,
>(
buf: impl prost::bytes::Buf,
) -> Result<T, DecodeError> {
M::decode(buf)?
.try_into()
.map_err(|e: E| DecodeError::Conversion(e.into()))
}