use super::{Data, DataRef, DecodeError, EncodeError, WireType};
macro_rules! bad_bail {
(
$(#[$meta:meta])*
$name: ident
) => {
$(#[$meta])*
#[viewit::viewit(
getters(vis_all = "pub"),
setters(vis_all = "pub", prefix = "with")
)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
#[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
pub struct $name<I> {
#[viewit(
getter(const, attrs(doc = "Returns the incarnation of the message")),
setter(
const,
attrs(doc = "Sets the incarnation of the message (Builder pattern)")
)
)]
incarnation: u32,
#[viewit(
getter(const, style = "ref", attrs(doc = "Returns the node of the message")),
setter(attrs(doc = "Sets the node of the message (Builder pattern)"))
)]
node: I,
#[viewit(
getter(const, style = "ref", attrs(doc = "Returns the source node of the message")),
setter(attrs(doc = "Sets the source node of the message (Builder pattern)"))
)]
from: I,
}
paste::paste! {
const [< $name:upper _INCARNATION_TAG >]: u8 = 1;
const [< $name:upper _INCARNATION_BYTE >]: u8 = super::merge(WireType::Varint, [< $name:upper _ INCARNATION_TAG >]);
const [< $name:upper _NODE_TAG >]: u8 = 2;
const [< $name:upper _FROM_TAG >]: u8 = 3;
impl<'a, I: Data> DataRef<'a, $name<I>> for $name<I::Ref<'a>> {
fn decode(src: &'a [u8]) -> Result<(usize, Self), DecodeError>
where
Self: Sized,
{
let mut node = None;
let mut from = None;
let mut incarnation = None;
let mut offset = 0;
while offset < src.len() {
match src[offset] {
[< $name:upper _INCARNATION_BYTE >] => {
if incarnation.is_some() {
return Err(DecodeError::duplicate_field(stringify!($name), "incarnation", [< $name:upper _INCARNATION_TAG >]));
}
offset += 1;
let (bytes_read, value) = <u32 as DataRef<u32>>::decode(&src[offset..])?;
offset += bytes_read;
incarnation = Some(value);
}
b if b == $name::<I>::node_byte() => {
if node.is_some() {
return Err(DecodeError::duplicate_field(stringify!($name), "node", $name::<I>::node_byte()));
}
offset += 1;
let (bytes_read, value) = I::Ref::decode_length_delimited(&src[offset..])?;
offset += bytes_read;
node = Some(value);
}
b if b == $name::<I>::from_byte() => {
if from.is_some() {
return Err(DecodeError::duplicate_field(stringify!($name), "from", $name::<I>::from_byte()));
}
offset += 1;
let (bytes_read, value) = I::Ref::decode_length_delimited(&src[offset..])?;
offset += bytes_read;
from = Some(value);
}
_ => offset += super::skip(stringify!($name), &src[offset..])?,
}
}
let incarnation = incarnation.ok_or_else(|| DecodeError::missing_field(stringify!($name), "incarnation"))?;
let node = node.ok_or_else(|| DecodeError::missing_field(stringify!($name), "node"))?;
let from = from.ok_or_else(|| DecodeError::missing_field(stringify!($name), "from"))?;
Ok((offset, Self {
incarnation,
node,
from,
}))
}
}
impl<I: Data> Data for $name<I> {
type Ref<'a> = $name<I::Ref<'a>>;
fn from_ref(val: Self::Ref<'_>) -> Result<Self, DecodeError> {
let Self::Ref { incarnation, node, from } = val;
I::from_ref(node)
.and_then(|node| I::from_ref(from).map(|from| Self::new(incarnation, node, from)))
}
fn encoded_len(&self) -> usize {
let mut len = 1 + self.incarnation.encoded_len();
len += 1 + self.node.encoded_len_with_length_delimited();
len += 1 + self.from.encoded_len_with_length_delimited();
len
}
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
macro_rules! bail {
($this:ident($offset:expr, $len:ident)) => {
if $offset >= $len {
return Err(EncodeError::insufficient_buffer($this.encoded_len(), $len));
}
};
}
let len = buf.len();
bail!(self(0, len));
let mut offset = 0;
buf[offset] = [< $name:upper _INCARNATION_BYTE >];
offset += 1;
offset += self.incarnation.encode(&mut buf[offset..]).map_err(|e| e.update(self.encoded_len(), len))?;
bail!(self(offset, len));
buf[offset] = Self::node_byte();
offset += 1;
offset += self.node.encode_length_delimited(&mut buf[offset..]).map_err(|e| e.update(self.encoded_len(), len))?;
bail!(self(offset, len));
buf[offset] = Self::from_byte();
offset += 1;
offset += self.from.encode_length_delimited(&mut buf[offset..]).map_err(|e| e.update(self.encoded_len(), len))?;
#[cfg(debug_assertions)]
super::debug_assert_write_eq::<Self>(offset, self.encoded_len());
Ok(offset)
}
}
impl<I> $name<I> {
#[inline]
const fn node_byte() -> u8
where
I: Data,
{
super::merge(I::WIRE_TYPE, [< $name:upper _NODE_TAG >])
}
#[inline]
const fn from_byte() -> u8
where
I: Data,
{
super::merge(I::WIRE_TYPE, [< $name:upper _FROM_TAG >])
}
}
}
impl<I> $name<I> {
#[inline]
pub const fn new(incarnation: u32, node: I, from: I) -> Self {
Self {
incarnation,
node,
from,
}
}
#[inline]
pub fn set_incarnation(&mut self, incarnation: u32) -> &mut Self {
self.incarnation = incarnation;
self
}
#[inline]
pub fn set_from(&mut self, source: I) -> &mut Self {
self.from = source;
self
}
#[inline]
pub fn set_node(&mut self, target: I) -> &mut Self {
self.node = target;
self
}
}
};
}
bad_bail!(
Suspect
);
bad_bail!(
Dead
);