use std::fmt;
use flatbuffers::InvalidFlatbuffer;
pub use flatbuffers::{FlatBufferBuilder, ForwardsUOffset, Vector};
use nostr::prelude::*;
#[allow(
unused_imports,
dead_code,
clippy::all,
unsafe_code,
missing_docs,
unsafe_op_in_unsafe_fn
)]
mod event_generated;
pub use self::event_generated::event_fbs;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum MissingField {
Id,
Pubkey,
Tags,
Content,
Sig,
}
impl fmt::Display for MissingField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Id => write!(f, "id"),
Self::Pubkey => write!(f, "pubkey"),
Self::Tags => write!(f, "tags"),
Self::Content => write!(f, "content"),
Self::Sig => write!(f, "sig"),
}
}
}
#[derive(Debug)]
pub enum Error {
Protocol(nostr::error::Error),
FlatBuffer(InvalidFlatbuffer),
FieldNotFound(MissingField),
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Protocol(e) => e.fmt(f),
Self::FlatBuffer(e) => write!(f, "{e}"),
Self::FieldNotFound(field) => write!(f, "'{field}' field not found"),
}
}
}
impl From<nostr::error::Error> for Error {
fn from(e: nostr::error::Error) -> Self {
Self::Protocol(e)
}
}
impl From<InvalidFlatbuffer> for Error {
fn from(e: InvalidFlatbuffer) -> Self {
Self::FlatBuffer(e)
}
}
pub trait FlatBufferEncode {
fn encode<'a>(&self, fbb: &'a mut FlatBufferBuilder) -> &'a [u8];
}
pub trait FlatBufferDecode: Sized {
fn decode(buf: &[u8]) -> Result<Self, Error>;
}
pub trait FlatBufferDecodeBorrowed<'a>: Sized {
fn decode(buf: &'a [u8]) -> Result<Self, Error>;
}
impl FlatBufferEncode for Event {
fn encode<'a>(&self, fbb: &'a mut FlatBufferBuilder) -> &'a [u8] {
fbb.reset();
let id = event_fbs::Fixed32Bytes::new(self.id.as_bytes());
let pubkey = event_fbs::Fixed32Bytes::new(self.pubkey.as_bytes());
let sig = event_fbs::Fixed64Bytes::new(self.sig.as_ref());
let tags = self
.tags
.iter()
.map(|t| {
let tags = t
.as_slice()
.iter()
.map(|t| fbb.create_string(t))
.collect::<Vec<_>>();
let args = event_fbs::StringVectorArgs {
data: Some(fbb.create_vector(&tags)),
};
event_fbs::StringVector::create(fbb, &args)
})
.collect::<Vec<_>>();
let args = event_fbs::EventArgs {
id: Some(&id),
pubkey: Some(&pubkey),
created_at: self.created_at.as_secs(),
kind: self.kind.as_u16() as u64,
tags: Some(fbb.create_vector(&tags)),
content: Some(fbb.create_string(&self.content)),
sig: Some(&sig),
};
let offset = event_fbs::Event::create(fbb, &args);
event_fbs::finish_event_buffer(fbb, offset);
fbb.finished_data()
}
}
impl FlatBufferDecode for Event {
fn decode(buf: &[u8]) -> Result<Self, Error> {
let ev = event_fbs::root_as_event(buf)?;
let tags = ev
.tags()
.ok_or(Error::FieldNotFound(MissingField::Tags))?
.into_iter()
.filter_map(|tag| tag.data().map(Tag::parse))
.collect::<Result<Vec<Tag>, _>>()?;
Ok(Self::new(
EventId::from_byte_array(ev.id().ok_or(Error::FieldNotFound(MissingField::Id))?.0),
PublicKey::from_byte_array(
ev.pubkey()
.ok_or(Error::FieldNotFound(MissingField::Pubkey))?
.0,
),
Timestamp::from(ev.created_at()),
Kind::from(ev.kind() as u16),
tags,
ev.content()
.ok_or(Error::FieldNotFound(MissingField::Content))?
.to_owned(),
Signature::from_byte_array(ev.sig().ok_or(Error::FieldNotFound(MissingField::Sig))?.0),
))
}
}