use core::str;
use minicbor::data::{Tag, Type};
use minicbor::decode::Error;
use minicbor::encode::Write;
use minicbor::{Decode, Decoder, Encode, Encoder};
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct Challenge {
pub id: [u8; 32],
pub signature: [u8; 64],
}
impl Challenge {
pub const TAG: Tag = Tag::new(710);
}
impl<'b, C> Decode<'b, C> for Challenge {
fn decode(d: &mut Decoder<'b>, _ctx: &mut C) -> Result<Self, Error> {
let mut id = None;
let mut signature = None;
macro_rules! decode_inner {
() => {
match d.u32()? {
1 => {
let mut buf = [0; 32];
hex::decode_to_slice(d.str()?, &mut buf)
.map_err(|_| Error::message("invalid hex string (id)"))?;
id = Some(buf);
}
2 => {
let mut buf = [0; 64];
hex::decode_to_slice(d.str()?, &mut buf)
.map_err(|_| Error::message("invalid hex string (signature)"))?;
signature = Some(buf);
}
3 => (),
_ => return Err(Error::message("unknown map entry")),
}
};
}
if let Some(len) = d.map()? {
for _ in 0..len {
decode_inner!();
}
} else {
while d.datatype()? != Type::Break {
decode_inner!();
}
}
Ok(Self {
id: id.ok_or_else(|| Error::message("id is missing"))?,
signature: signature.ok_or_else(|| Error::message("signature is missing"))?,
})
}
}
impl<C> Encode<C> for Challenge {
fn encode<W: Write>(
&self,
e: &mut Encoder<W>,
_ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
let mut id = [0; 64];
let mut signature = [0; 128];
hex::encode_to_slice(self.id, &mut id).unwrap();
hex::encode_to_slice(self.signature, &mut signature).unwrap();
let id = str::from_utf8(&id).unwrap();
let signature = str::from_utf8(&signature).unwrap();
e.map(2)?;
e.u8(1)?.str(id)?;
e.u8(2)?.str(signature)?;
Ok(())
}
}
#[derive(Debug, Decode, Clone, Encode, Eq, PartialEq, Hash)]
#[cbor(map)]
pub struct Solution<'a> {
#[cbor(b(1))]
pub word1: &'a str,
#[cbor(b(2))]
pub word2: &'a str,
#[cbor(b(3))]
pub word3: &'a str,
#[cbor(b(4))]
pub word4: &'a str,
}
impl<'a> Solution<'a> {
pub const TAG: Tag = Tag::new(711);
}