commit dfc4c27bf631b5b1d304562d9a26656836a573ae
parent 356cbe0fc11ee4dc1f93908dcc1e858c5291e20c
Author: William Casarin <jb55@jb55.com>
Date: Mon, 19 Aug 2024 15:31:14 -0700
filter: expose more builder options
to do this, we need to make filterbuilder handle errors better
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
M | src/error.rs | | | 54 | +++++++++++++++++++++++++++++++++++++++++++----------- |
M | src/filter.rs | | | 201 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
M | src/lib.rs | | | 2 | +- |
3 files changed, 163 insertions(+), 94 deletions(-)
diff --git a/src/error.rs b/src/error.rs
@@ -10,21 +10,53 @@ pub enum Error {
TransactionFailed,
SubscriptionError,
BufferOverflow,
+ Filter(FilterError),
+}
+
+impl Error {
+ pub fn filter(ferr: FilterError) -> Self {
+ Error::Filter(ferr)
+ }
+}
+
+#[derive(Debug, Eq, PartialEq)]
+pub enum FilterError {
+ FieldAlreadyExists,
+ FieldAlreadyStarted,
+}
+
+impl FilterError {
+ pub fn already_exists() -> Error {
+ Error::Filter(FilterError::FieldAlreadyExists)
+ }
+
+ pub fn already_started() -> Error {
+ Error::Filter(FilterError::FieldAlreadyStarted)
+ }
+}
+
+impl fmt::Display for FilterError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ FilterError::FieldAlreadyExists => write!(f, "field already exists"),
+ FilterError::FieldAlreadyStarted => write!(f, "field already started"),
+ }
+ }
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let s = match self {
- Error::DbOpenFailed => "Open failed",
- Error::NotFound => "Not found",
- Error::QueryError => "Query failed",
- Error::DecodeError => "Decode error",
- Error::NoteProcessFailed => "Note process failed",
- Error::TransactionFailed => "Transaction failed",
- Error::SubscriptionError => "Subscription failed",
- Error::BufferOverflow => "Buffer overflow",
- };
- write!(f, "{}", s)
+ match self {
+ Error::DbOpenFailed => write!(f, "Open failed"),
+ Error::NotFound => write!(f, "Not found"),
+ Error::QueryError => write!(f, "Query failed"),
+ Error::DecodeError => write!(f, "Decode error"),
+ Error::NoteProcessFailed => write!(f, "Note process failed"),
+ Error::TransactionFailed => write!(f, "Transaction failed"),
+ Error::SubscriptionError => write!(f, "Subscription failed"),
+ Error::BufferOverflow => write!(f, "Buffer overflow"),
+ Error::Filter(filter_err) => write!(f, "Filter: {filter_err}"),
+ }
}
}
diff --git a/src/filter.rs b/src/filter.rs
@@ -1,4 +1,4 @@
-use crate::{bindings, Error, Note};
+use crate::{bindings, Error, FilterError, Note, Result};
use std::ffi::CString;
use std::os::raw::c_char;
use std::ptr::null_mut;
@@ -112,7 +112,7 @@ impl Filter {
self.data.as_mut_ptr()
}
- pub fn json_with_bufsize(&self, bufsize: usize) -> Result<String, Error> {
+ pub fn json_with_bufsize(&self, bufsize: usize) -> Result<String> {
let mut buf = Vec::with_capacity(bufsize);
unsafe {
let size = bindings::ndb_filter_json(
@@ -132,7 +132,7 @@ impl Filter {
}
}
- pub fn json(&self) -> Result<String, Error> {
+ pub fn json(&self) -> Result<String> {
// 1mb buffer
self.json_with_bufsize(1024usize * 1024usize)
}
@@ -159,162 +159,199 @@ impl FilterBuilder {
self.data.as_mut_ptr()
}
- fn add_int_element(&mut self, i: u64) {
- unsafe { bindings::ndb_filter_add_int_element(self.as_mut_ptr(), i) };
+ pub fn add_int_element(&mut self, i: u64) -> Result<()> {
+ let res = unsafe { bindings::ndb_filter_add_int_element(self.as_mut_ptr(), i) };
+ if res == 0 {
+ return Err(FilterError::already_exists());
+ }
+
+ Ok(())
}
- fn add_str_element(&mut self, s: &str) {
+ pub fn add_str_element(&mut self, s: &str) -> Result<()> {
let c_str = CString::new(s).expect("string to cstring conversion failed");
- unsafe {
- bindings::ndb_filter_add_str_element(self.as_mut_ptr(), c_str.as_ptr());
- };
+ let r = unsafe { bindings::ndb_filter_add_str_element(self.as_mut_ptr(), c_str.as_ptr()) };
+
+ if r == 0 {
+ return Err(FilterError::already_exists());
+ }
+
+ Ok(())
}
- fn add_id_element(&mut self, id: &[u8; 32]) {
+ pub fn add_id_element(&mut self, id: &[u8; 32]) -> Result<()> {
let ptr: *const ::std::os::raw::c_uchar = id.as_ptr() as *const ::std::os::raw::c_uchar;
- unsafe {
- bindings::ndb_filter_add_id_element(self.as_mut_ptr(), ptr);
- };
+ let r = unsafe { bindings::ndb_filter_add_id_element(self.as_mut_ptr(), ptr) };
+
+ if r == 0 {
+ return Err(FilterError::already_exists());
+ }
+
+ Ok(())
}
- fn start_field(&mut self, field: bindings::ndb_filter_fieldtype) {
- unsafe { bindings::ndb_filter_start_field(self.as_mut_ptr(), field) };
+ pub fn start_field(&mut self, field: bindings::ndb_filter_fieldtype) -> Result<()> {
+ let r = unsafe { bindings::ndb_filter_start_field(self.as_mut_ptr(), field) };
+
+ if r == 0 {
+ return Err(FilterError::already_started());
+ }
+
+ Ok(())
}
- fn start_tags_field(&mut self, tag: char) {
- unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
+ pub fn start_tags_field(&mut self, tag: char) -> Result<()> {
+ let r =
+ unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
+ if r == 0 {
+ return Err(FilterError::already_started());
+ }
+ Ok(())
}
- fn start_kinds_field(&mut self) {
- self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_KINDS);
+ pub fn start_kinds_field(&mut self) -> Result<()> {
+ self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_KINDS)
}
- fn start_authors_field(&mut self) {
- self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_AUTHORS);
+ pub fn start_authors_field(&mut self) -> Result<()> {
+ self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_AUTHORS)
}
- fn start_since_field(&mut self) {
- self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_SINCE);
+ pub fn start_since_field(&mut self) -> Result<()> {
+ self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_SINCE)
}
- fn start_until_field(&mut self) {
- self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_UNTIL);
+ pub fn start_until_field(&mut self) -> Result<()> {
+ self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_UNTIL)
}
- fn start_limit_field(&mut self) {
- self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_LIMIT);
+ pub fn start_limit_field(&mut self) -> Result<()> {
+ self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_LIMIT)
}
- fn start_ids_field(&mut self) {
- self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_IDS);
+ pub fn start_ids_field(&mut self) -> Result<()> {
+ self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_IDS)
}
#[allow(dead_code)]
- fn start_events_field(&mut self) {
- self.start_tags_field('e');
+ pub fn start_events_field(&mut self) -> Result<()> {
+ self.start_tags_field('e')
}
- fn start_pubkeys_field(&mut self) {
- self.start_tags_field('p');
+ pub fn start_pubkeys_field(&mut self) -> Result<()> {
+ self.start_tags_field('p')
}
- fn start_tag_field(&mut self, tag: char) {
- unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
+ pub fn start_tag_field(&mut self, tag: char) -> Result<()> {
+ let r =
+ unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
+ if r == 0 {
+ return Err(Error::filter(FilterError::FieldAlreadyStarted));
+ }
+ Ok(())
}
- fn end_field(&mut self) {
- unsafe { bindings::ndb_filter_end_field(self.as_mut_ptr()) }
+ pub fn end_field(&mut self) {
+ unsafe {
+ bindings::ndb_filter_end_field(self.as_mut_ptr());
+ };
}
- pub fn events(mut self, events: Vec<[u8; 32]>) -> Self {
- self.start_tag_field('e');
+ pub fn events(mut self, events: Vec<[u8; 32]>) -> Result<Self> {
+ self.start_tag_field('e')?;
for ref id in events {
- self.add_id_element(id);
+ self.add_id_element(id)?;
}
self.end_field();
- self
+ Ok(self)
}
- pub fn event(mut self, id: &[u8; 32]) -> Self {
- self.start_tag_field('e');
- self.add_id_element(id);
+ pub fn event(mut self, id: &[u8; 32]) -> Result<Self> {
+ self.start_tag_field('e')?;
+ self.add_id_element(id)?;
self.end_field();
- self
+ Ok(self)
}
- pub fn ids(mut self, ids: Vec<[u8; 32]>) -> Self {
- self.start_ids_field();
- for ref id in ids {
- self.add_id_element(id);
+ pub fn ids<'a, I>(mut self, ids: I) -> Result<Self>
+ where
+ I: Iterator<Item = &'a [u8; 32]>,
+ {
+ self.start_ids_field()?;
+ for id in ids {
+ self.add_id_element(id)?;
}
self.end_field();
- self
+ Ok(self)
}
- pub fn pubkeys(mut self, pubkeys: Vec<[u8; 32]>) -> Self {
- self.start_tag_field('p');
+ pub fn pubkeys(mut self, pubkeys: Vec<[u8; 32]>) -> Result<Self> {
+ self.start_tag_field('p')?;
for ref pk in pubkeys {
- self.add_id_element(pk);
+ self.add_id_element(pk)?;
}
self.end_field();
- self
+ Ok(self)
}
- pub fn authors(mut self, authors: Vec<[u8; 32]>) -> Self {
- self.start_authors_field();
+ pub fn authors<'a, I>(mut self, authors: I) -> Result<Self>
+ where
+ I: Iterator<Item = &'a [u8; 32]>,
+ {
+ self.start_authors_field()?;
for author in authors {
- self.add_id_element(&author);
+ self.add_id_element(author)?;
}
self.end_field();
- self
+ Ok(self)
}
- pub fn kinds(mut self, kinds: Vec<u64>) -> Self {
- self.start_kinds_field();
+ pub fn kinds(mut self, kinds: Vec<u64>) -> Result<Self> {
+ self.start_kinds_field()?;
for kind in kinds {
- self.add_int_element(kind);
+ self.add_int_element(kind)?;
}
self.end_field();
- self
+ Ok(self)
}
- pub fn pubkey(mut self, pubkeys: Vec<[u8; 32]>) -> Self {
- self.start_pubkeys_field();
+ pub fn pubkey(mut self, pubkeys: Vec<[u8; 32]>) -> Result<Self> {
+ self.start_pubkeys_field()?;
for ref pubkey in pubkeys {
- self.add_id_element(pubkey);
+ self.add_id_element(pubkey)?;
}
self.end_field();
- self
+ Ok(self)
}
- pub fn tags(mut self, tags: Vec<String>, tag: char) -> Self {
- self.start_tag_field(tag);
+ pub fn tags(mut self, tags: Vec<String>, tag: char) -> Result<Self> {
+ self.start_tag_field(tag)?;
for tag in tags {
- self.add_str_element(&tag);
+ self.add_str_element(&tag)?;
}
self.end_field();
- self
+ Ok(self)
}
- pub fn since(mut self, since: u64) -> Self {
- self.start_since_field();
- self.add_int_element(since);
+ pub fn since(mut self, since: u64) -> Result<Self> {
+ self.start_since_field()?;
+ self.add_int_element(since)?;
self.end_field();
- self
+ Ok(self)
}
- pub fn until(mut self, until: u64) -> Self {
- self.start_until_field();
- self.add_int_element(until);
+ pub fn until(mut self, until: u64) -> Result<Self> {
+ self.start_until_field()?;
+ self.add_int_element(until)?;
self.end_field();
- self
+ Ok(self)
}
- pub fn limit(mut self, limit: u64) -> Self {
- self.start_limit_field();
- self.add_int_element(limit);
+ pub fn limit(mut self, limit: u64) -> Result<Self> {
+ self.start_limit_field()?;
+ self.add_int_element(limit)?;
self.end_field();
- self
+ Ok(self)
}
pub fn build(&mut self) -> Filter {
diff --git a/src/lib.rs b/src/lib.rs
@@ -28,7 +28,7 @@ mod util;
pub use block::{Block, BlockType, Blocks, Mention};
pub use config::Config;
-pub use error::Error;
+pub use error::{Error, FilterError};
pub use filter::{Filter, FilterBuilder};
pub use ndb::Ndb;
pub use ndb_profile::{NdbProfile, NdbProfileRecord};