use num_enum::{IntoPrimitive, TryFromPrimitive};
use crate::{Path, coding::*};
use super::{Message, Version};
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Announce<'a> {
Active {
#[cfg_attr(feature = "serde", serde(borrow))]
suffix: Path<'a>,
hops: u64,
},
Ended {
#[cfg_attr(feature = "serde", serde(borrow))]
suffix: Path<'a>,
hops: u64,
},
}
impl Message for Announce<'_> {
fn decode_msg<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
let status = AnnounceStatus::decode(r, version)?;
let suffix = Path::decode(r, version)?;
let hops = match version {
Version::Lite03 => u64::decode(r, version)?,
Version::Lite01 | Version::Lite02 => 0,
};
Ok(match status {
AnnounceStatus::Active => Self::Active { suffix, hops },
AnnounceStatus::Ended => Self::Ended { suffix, hops },
})
}
fn encode_msg<W: bytes::BufMut>(&self, w: &mut W, version: Version) -> Result<(), EncodeError> {
match self {
Self::Active { suffix, hops } => {
AnnounceStatus::Active.encode(w, version)?;
suffix.encode(w, version)?;
match version {
Version::Lite03 => hops.encode(w, version)?,
Version::Lite01 | Version::Lite02 => {}
}
}
Self::Ended { suffix, hops } => {
AnnounceStatus::Ended.encode(w, version)?;
suffix.encode(w, version)?;
match version {
Version::Lite03 => hops.encode(w, version)?,
Version::Lite01 | Version::Lite02 => {}
}
}
}
Ok(())
}
}
#[derive(Clone, Debug)]
pub struct AnnouncePlease<'a> {
pub prefix: Path<'a>,
}
impl Message for AnnouncePlease<'_> {
fn decode_msg<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
let prefix = Path::decode(r, version)?;
Ok(Self { prefix })
}
fn encode_msg<W: bytes::BufMut>(&self, w: &mut W, version: Version) -> Result<(), EncodeError> {
self.prefix.encode(w, version)?;
Ok(())
}
}
#[derive(Clone, Copy, Debug, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
enum AnnounceStatus {
Ended = 0,
Active = 1,
}
impl Decode<Version> for AnnounceStatus {
fn decode<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
let status = u8::decode(r, version)?;
status.try_into().map_err(|_| DecodeError::InvalidValue)
}
}
impl Encode<Version> for AnnounceStatus {
fn encode<W: bytes::BufMut>(&self, w: &mut W, version: Version) -> Result<(), EncodeError> {
(*self as u8).encode(w, version)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AnnounceInit<'a> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub suffixes: Vec<Path<'a>>,
}
impl Message for AnnounceInit<'_> {
fn decode_msg<R: bytes::Buf>(r: &mut R, version: Version) -> Result<Self, DecodeError> {
match version {
Version::Lite01 | Version::Lite02 => {}
Version::Lite03 => {
return Err(DecodeError::Version);
}
}
let count = u64::decode(r, version)?;
let mut paths = Vec::with_capacity(count.min(1024) as usize);
for _ in 0..count {
paths.push(Path::decode(r, version)?);
}
Ok(Self { suffixes: paths })
}
fn encode_msg<W: bytes::BufMut>(&self, w: &mut W, version: Version) -> Result<(), EncodeError> {
match version {
Version::Lite01 | Version::Lite02 => {}
Version::Lite03 => {
return Err(EncodeError::Version);
}
}
(self.suffixes.len() as u64).encode(w, version)?;
for path in &self.suffixes {
path.encode(w, version)?;
}
Ok(())
}
}