Skip to content

Commit

Permalink
fbs: complete Event encoding/decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
yukibtc committed Oct 26, 2023
1 parent 35156ea commit 09da56b
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
target/
db/
.DS_Store
*.db
*.db-shm
Expand Down
6 changes: 5 additions & 1 deletion crates/nostr-sdk-fbs/fbs/event.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ struct Fixed64Bytes {
val: [ubyte:64];
}

table StringVector {
data: [string];
}

table Event {
id: Fixed32Bytes;
pubkey: Fixed32Bytes;
created_at: ulong;
kind: ulong;
tags: [string];
tags: [StringVector];
content: string;
sig: Fixed64Bytes;
}
Expand Down
130 changes: 125 additions & 5 deletions crates/nostr-sdk-fbs/src/event_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,123 @@ pub mod event_fbs {
}
}

pub enum StringVectorOffset {}
#[derive(Copy, Clone, PartialEq)]

pub struct StringVector<'a> {
pub _tab: flatbuffers::Table<'a>,
}

impl<'a> flatbuffers::Follow<'a> for StringVector<'a> {
type Inner = StringVector<'a>;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Self {
_tab: flatbuffers::Table::new(buf, loc),
}
}
}

impl<'a> StringVector<'a> {
pub const VT_DATA: flatbuffers::VOffsetT = 4;

#[inline]
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
StringVector { _tab: table }
}
#[allow(unused_mut)]
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
args: &'args StringVectorArgs<'args>,
) -> flatbuffers::WIPOffset<StringVector<'bldr>> {
let mut builder = StringVectorBuilder::new(_fbb);
if let Some(x) = args.data {
builder.add_data(x);
}
builder.finish()
}

#[inline]
pub fn data(
&self,
) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe {
self._tab.get::<flatbuffers::ForwardsUOffset<
flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>,
>>(StringVector::VT_DATA, None)
}
}
}

impl flatbuffers::Verifiable for StringVector<'_> {
#[inline]
fn run_verifier(
v: &mut flatbuffers::Verifier,
pos: usize,
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
use self::flatbuffers::Verifiable;
v.visit_table(pos)?
.visit_field::<flatbuffers::ForwardsUOffset<
flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<&'_ str>>,
>>("data", Self::VT_DATA, false)?
.finish();
Ok(())
}
}
pub struct StringVectorArgs<'a> {
pub data: Option<
flatbuffers::WIPOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>>,
>,
}
impl<'a> Default for StringVectorArgs<'a> {
#[inline]
fn default() -> Self {
StringVectorArgs { data: None }
}
}

pub struct StringVectorBuilder<'a: 'b, 'b> {
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
}
impl<'a: 'b, 'b> StringVectorBuilder<'a, 'b> {
#[inline]
pub fn add_data(
&mut self,
data: flatbuffers::WIPOffset<
flatbuffers::Vector<'b, flatbuffers::ForwardsUOffset<&'b str>>,
>,
) {
self.fbb_
.push_slot_always::<flatbuffers::WIPOffset<_>>(StringVector::VT_DATA, data);
}
#[inline]
pub fn new(
_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
) -> StringVectorBuilder<'a, 'b> {
let start = _fbb.start_table();
StringVectorBuilder {
fbb_: _fbb,
start_: start,
}
}
#[inline]
pub fn finish(self) -> flatbuffers::WIPOffset<StringVector<'a>> {
let o = self.fbb_.end_table(self.start_);
flatbuffers::WIPOffset::new(o.value())
}
}

impl core::fmt::Debug for StringVector<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut ds = f.debug_struct("StringVector");
ds.field("data", &self.data());
ds.finish()
}
}
pub enum EventOffset {}
#[derive(Copy, Clone, PartialEq)]

Expand Down Expand Up @@ -260,13 +377,14 @@ pub mod event_fbs {
#[inline]
pub fn tags(
&self,
) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<StringVector<'a>>>>
{
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe {
self._tab.get::<flatbuffers::ForwardsUOffset<
flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>,
flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<StringVector>>,
>>(Event::VT_TAGS, None)
}
}
Expand Down Expand Up @@ -302,7 +420,7 @@ pub mod event_fbs {
.visit_field::<u64>("created_at", Self::VT_CREATED_AT, false)?
.visit_field::<u64>("kind", Self::VT_KIND, false)?
.visit_field::<flatbuffers::ForwardsUOffset<
flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<&'_ str>>,
flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<StringVector>>,
>>("tags", Self::VT_TAGS, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>(
"content",
Expand All @@ -320,7 +438,9 @@ pub mod event_fbs {
pub created_at: u64,
pub kind: u64,
pub tags: Option<
flatbuffers::WIPOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>>,
flatbuffers::WIPOffset<
flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<StringVector<'a>>>,
>,
>,
pub content: Option<flatbuffers::WIPOffset<&'a str>>,
pub sig: Option<&'a Fixed64Bytes>,
Expand Down Expand Up @@ -368,7 +488,7 @@ pub mod event_fbs {
pub fn add_tags(
&mut self,
tags: flatbuffers::WIPOffset<
flatbuffers::Vector<'b, flatbuffers::ForwardsUOffset<&'b str>>,
flatbuffers::Vector<'b, flatbuffers::ForwardsUOffset<StringVector<'b>>>,
>,
) {
self.fbb_
Expand Down
43 changes: 36 additions & 7 deletions crates/nostr-sdk-fbs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@

//! Nostr SDK Flatbuffers
use event_generated::event_fbs::{Fixed32Bytes, Fixed64Bytes};
use event_generated::event_fbs::{Fixed32Bytes, Fixed64Bytes, StringVectorArgs};
pub use flatbuffers::FlatBufferBuilder;
use flatbuffers::InvalidFlatbuffer;
use nostr::secp256k1::schnorr::Signature;
use nostr::secp256k1::{self, XOnlyPublicKey};
use nostr::{Event, EventId, Kind, Timestamp};
use nostr::{Event, EventId, Kind, Tag, Timestamp};
use thiserror::Error;

#[allow(unused_imports, dead_code)]
#[allow(unused_imports, dead_code, clippy::all)]
mod event_generated;

pub use self::event_generated::event_fbs;
Expand All @@ -23,6 +23,8 @@ pub enum Error {
#[error(transparent)]
EventId(#[from] nostr::event::id::Error),
#[error(transparent)]
Tag(#[from] nostr::event::tag::Error),
#[error(transparent)]
Secp256k1(#[from] secp256k1::Error),
#[error("not found")]
NotFound,
Expand All @@ -34,19 +36,35 @@ pub trait FlatBufferUtils: Sized {
}

impl FlatBufferUtils for Event {
#[tracing::instrument(skip_all)]
fn encode<'a>(&self, fbb: &'a mut FlatBufferBuilder) -> &'a [u8] {
fbb.reset();

let id = Fixed32Bytes::new(&self.id.to_bytes());
let pubkey = Fixed32Bytes::new(&self.pubkey.serialize());
let sig = Fixed64Bytes::new(self.sig.as_ref());
let tags = self
.tags
.iter()
.map(|t| {
let tags = t
.as_vec()
.iter()
.map(|t| fbb.create_string(t))
.collect::<Vec<_>>();
let args = 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_u64(),
kind: self.kind.as_u64(),
tags: None, // TODO
content: None, // TODO
tags: Some(fbb.create_vector(&tags)),
content: Some(fbb.create_string(&self.content)),
sig: Some(&sig),
};

Expand All @@ -57,15 +75,26 @@ impl FlatBufferUtils for Event {
fbb.finished_data()
}

#[tracing::instrument(skip_all)]
fn decode(buf: &[u8]) -> Result<Self, Error> {
let ev = event_fbs::root_as_event(buf)?;
let tags = ev
.tags()
.ok_or(Error::NotFound)?
.into_iter()
.filter_map(|tag| {
tag.data()
.map(|tag| Tag::parse(tag.into_iter().collect::<Vec<&str>>()))
})
.collect::<Result<Vec<Tag>, _>>()?;

Ok(Self {
id: EventId::from_slice(&ev.id().ok_or(Error::NotFound)?.0)?,
pubkey: XOnlyPublicKey::from_slice(&ev.pubkey().ok_or(Error::NotFound)?.0)?,
created_at: Timestamp::from(ev.created_at()),
kind: Kind::from(ev.kind()),
tags: Vec::new(), // TODO
content: String::new(), // TODO
tags,
content: ev.content().ok_or(Error::NotFound)?.to_owned(),
sig: Signature::from_slice(&ev.sig().ok_or(Error::NotFound)?.0)?,
})
}
Expand Down

0 comments on commit 09da56b

Please sign in to comment.