use std::{collections::BTreeSet, net::SocketAddr};
use nested_enum_utils::common_fields;
use serde::{Deserialize, Serialize};
use snafu::{Backtrace, Snafu};
use crate::{key::NodeId, relay_url::RelayUrl};
mod node;
pub use self::node::NodeTicket;
pub trait Ticket: Sized {
const KIND: &'static str;
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError>;
fn serialize(&self) -> String {
let mut out = Self::KIND.to_string();
data_encoding::BASE32_NOPAD.encode_append(&self.to_bytes(), &mut out);
out.to_ascii_lowercase()
}
fn deserialize(str: &str) -> Result<Self, ParseError> {
let expected = Self::KIND;
let Some(rest) = str.strip_prefix(expected) else {
return Err(KindSnafu { expected }.build());
};
let bytes = data_encoding::BASE32_NOPAD.decode(rest.to_ascii_uppercase().as_bytes())?;
let ticket = Self::from_bytes(&bytes)?;
Ok(ticket)
}
}
#[common_fields({
backtrace: Option<Backtrace>,
#[snafu(implicit)]
span_trace: n0_snafu::SpanTrace,
})]
#[derive(Debug, Snafu)]
#[allow(missing_docs)]
#[snafu(visibility(pub(crate)))]
#[non_exhaustive]
pub enum ParseError {
#[snafu(display("wrong prefix, expected {expected}"))]
Kind {
expected: &'static str,
},
#[snafu(transparent)]
Postcard { source: postcard::Error },
#[snafu(transparent)]
Encoding { source: data_encoding::DecodeError },
#[snafu(display("verification failed: {message}"))]
Verify { message: &'static str },
}
impl ParseError {
pub fn wrong_prefix(expected: &'static str) -> Self {
KindSnafu { expected }.build()
}
pub fn verification_failed(message: &'static str) -> Self {
VerifySnafu { message }.build()
}
}
#[derive(Serialize, Deserialize)]
struct Variant0NodeAddr {
node_id: NodeId,
info: Variant0AddrInfo,
}
#[derive(Serialize, Deserialize)]
struct Variant0AddrInfo {
relay_url: Option<RelayUrl>,
direct_addresses: BTreeSet<SocketAddr>,
}