use crate::{
frame::{parse::take_address, FrameGenerator, FrameParser},
types::Address,
Result,
};
use nom::{bytes::complete::take, IResult};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Recipient {
Address(Address),
Namespace(Address),
}
impl Recipient {
pub fn inner_address(&self) -> Address {
match self {
Self::Address(addr) => *addr,
Self::Namespace(addr) => *addr,
}
}
}
impl FrameGenerator for Option<Recipient> {
fn generate(self, buf: &mut Vec<u8>) -> Result<()> {
match self {
None => {
buf.push(0);
}
Some(Recipient::Address(addr)) => {
buf.push(1);
addr.generate(buf)?;
}
Some(Recipient::Namespace(addr)) => {
buf.push(2);
addr.generate(buf)?;
}
}
Ok(())
}
}
impl FrameParser for Option<Recipient> {
type Output = Self;
fn parse(input: &[u8]) -> IResult<&[u8], Self::Output> {
let (input, mode) = take(1 as usize)(input)?;
match mode[0] {
0 => Ok((input, None)),
1 => {
let (input, addr) = take_address(input)?;
Ok((input, Some(Recipient::Address(addr))))
}
2 => {
let (input, addr) = take_address(input)?;
Ok((input, Some(Recipient::Namespace(addr))))
}
mode => {
unreachable!(
"\n(mode: {mode}) is definitely reachable but you've been naughty with your data"
)
}
}
}
}