nostrdb-rs

nostrdb in rust!
git clone git://jb55.com/nostrdb-rs
Log | Files | Refs | Submodules | README | LICENSE

filter.rs (34380B)


      1 use crate::{bindings, Error, FilterError, Note, Result};
      2 use std::ffi::CString;
      3 use std::os::raw::c_char;
      4 use std::ptr::null_mut;
      5 use tracing::debug;
      6 
      7 #[derive(Debug)]
      8 pub struct FilterBuilder {
      9     pub data: bindings::ndb_filter,
     10 }
     11 
     12 #[derive(Debug)]
     13 pub struct Filter {
     14     pub data: bindings::ndb_filter,
     15 }
     16 
     17 impl Clone for Filter {
     18     fn clone(&self) -> Self {
     19         // Default inits...
     20         //let mut new_filter: bindings::ndb_filter = Default::default();
     21         let null = null_mut();
     22         let mut new_filter = bindings::ndb_filter {
     23             finalized: 0,
     24             elem_buf: bindings::cursor {
     25                 start: null,
     26                 p: null,
     27                 end: null,
     28             },
     29             data_buf: bindings::cursor {
     30                 start: null,
     31                 p: null,
     32                 end: null,
     33             },
     34             num_elements: 0,
     35             current: -1,
     36             elements: [0, 0, 0, 0, 0, 0, 0],
     37         };
     38 
     39         debug!("cloning filter");
     40         unsafe {
     41             bindings::ndb_filter_clone(
     42                 new_filter.as_mut_ptr(),
     43                 self.as_ptr() as *mut bindings::ndb_filter,
     44             );
     45         };
     46         Filter { data: new_filter }
     47     }
     48 }
     49 
     50 impl bindings::ndb_filter {
     51     fn as_ptr(&self) -> *const bindings::ndb_filter {
     52         self as *const bindings::ndb_filter
     53     }
     54 
     55     fn as_mut_ptr(&mut self) -> *mut bindings::ndb_filter {
     56         self as *mut bindings::ndb_filter
     57     }
     58 
     59     fn as_ref(&self) -> &bindings::ndb_filter {
     60         self
     61     }
     62 
     63     pub fn mut_iter(&self) -> MutFilterIter<'_> {
     64         MutFilterIter::new(self.as_ref())
     65     }
     66 
     67     pub fn field(&self, index: i32) -> Option<FilterField<'_>> {
     68         let ptr = unsafe { bindings::ndb_filter_get_elements(self.as_ptr(), index) };
     69 
     70         if ptr.is_null() {
     71             return None;
     72         }
     73 
     74         Some(FilterElements::new(self, ptr).field())
     75     }
     76 
     77     pub fn field_mut(&self, index: i32) -> Option<MutFilterField<'_>> {
     78         let ptr = unsafe { bindings::ndb_filter_get_elements(self.as_ptr(), index) };
     79 
     80         if ptr.is_null() {
     81             return None;
     82         }
     83 
     84         FilterElements::new(self, ptr).field_mut()
     85     }
     86 
     87     pub fn elements(&self, index: i32) -> Option<FilterElements<'_>> {
     88         let ptr = unsafe { bindings::ndb_filter_get_elements(self.as_ptr(), index) };
     89 
     90         if ptr.is_null() {
     91             return None;
     92         }
     93 
     94         Some(FilterElements::new(self, ptr))
     95     }
     96 }
     97 
     98 impl bindings::ndb_filter {
     99     fn new(pages: i32) -> Self {
    100         let null = null_mut();
    101         let mut filter_data = bindings::ndb_filter {
    102             finalized: 0,
    103             elem_buf: bindings::cursor {
    104                 start: null,
    105                 p: null,
    106                 end: null,
    107             },
    108             data_buf: bindings::cursor {
    109                 start: null,
    110                 p: null,
    111                 end: null,
    112             },
    113             num_elements: 0,
    114             current: -1,
    115             elements: [0, 0, 0, 0, 0, 0, 0],
    116         };
    117 
    118         unsafe {
    119             bindings::ndb_filter_init_with(filter_data.as_mut_ptr(), pages);
    120         };
    121 
    122         filter_data
    123     }
    124 }
    125 
    126 impl Filter {
    127     pub fn new_with_capacity(pages: i32) -> FilterBuilder {
    128         FilterBuilder {
    129             data: bindings::ndb_filter::new(pages),
    130         }
    131     }
    132 
    133     #[allow(clippy::new_ret_no_self)]
    134     pub fn new() -> FilterBuilder {
    135         Self::new_with_capacity(256)
    136     }
    137 
    138     pub fn copy_from<'a, I>(filter: I) -> FilterBuilder
    139     where
    140         I: IntoIterator<Item = FilterField<'a>>,
    141     {
    142         let mut builder = Filter::new();
    143         for field in filter {
    144             match field {
    145                 FilterField::Search(search) => {
    146                     builder = builder.search(search);
    147                 }
    148                 FilterField::Ids(ids) => {
    149                     builder = builder.ids(ids);
    150                 }
    151                 FilterField::Authors(authors) => builder = builder.authors(authors),
    152                 FilterField::Kinds(kinds) => builder = builder.kinds(kinds),
    153                 FilterField::Tags(chr, tags) => {
    154                     builder.start_tags_field(chr).unwrap();
    155                     for field in tags {
    156                         match field {
    157                             FilterElement::Id(id) => builder.add_id_element(id).unwrap(),
    158                             FilterElement::Str(str_) => builder.add_str_element(str_).unwrap(),
    159                             FilterElement::Int(int) => builder.add_int_element(int).unwrap(),
    160                         }
    161                     }
    162                     builder.end_field();
    163                 }
    164                 FilterField::Since(n) => builder = builder.since(n),
    165                 FilterField::Until(n) => builder = builder.until(n),
    166                 FilterField::Limit(n) => builder = builder.limit(n),
    167             }
    168         }
    169         builder
    170     }
    171 
    172     pub fn from_json(json: &str) -> Result<Self> {
    173         Self::from_json_with_bufsize(json, 1024usize * 1024usize)
    174     }
    175 
    176     pub fn from_json_with_bufsize(json: &str, bufsize: usize) -> Result<Self> {
    177         let mut buf = Vec::with_capacity(bufsize);
    178         let mut filter = Filter::new();
    179         unsafe {
    180             let json_cstr = CString::new(json).expect("string to cstring conversion failed");
    181             let size = bindings::ndb_filter_from_json(
    182                 json_cstr.as_ptr(),
    183                 json.len() as i32,
    184                 filter.as_mut_ptr(),
    185                 buf.as_mut_ptr(),
    186                 bufsize as ::std::os::raw::c_int,
    187             ) as usize;
    188 
    189             // Step 4: Check the return value for success
    190             if size == 0 {
    191                 return Err(Error::BufferOverflow); // Handle the error appropriately
    192             }
    193 
    194             Ok(Filter { data: filter.data })
    195         }
    196     }
    197 
    198     pub fn to_ref(&self) -> &bindings::ndb_filter {
    199         &self.data
    200     }
    201 
    202     pub fn mut_iter(&self) -> MutFilterIter<'_> {
    203         self.data.mut_iter()
    204     }
    205 
    206     pub fn matches(&self, note: &Note) -> bool {
    207         unsafe {
    208             bindings::ndb_filter_matches(self.as_ptr() as *mut bindings::ndb_filter, note.as_ptr())
    209                 != 0
    210         }
    211     }
    212 
    213     pub fn num_elements(&self) -> i32 {
    214         unsafe { &*(self.as_ptr()) }.num_elements
    215     }
    216 
    217     pub fn limit_mut(self, limit: u64) -> Self {
    218         for field in self.mut_iter() {
    219             if let MutFilterField::Limit(val) = field {
    220                 *val = limit;
    221                 return self;
    222             }
    223         }
    224 
    225         Filter::copy_from(&self).limit(limit).build()
    226     }
    227 
    228     pub fn until_mut(self, until: u64) -> Self {
    229         for field in self.mut_iter() {
    230             if let MutFilterField::Until(val) = field {
    231                 *val = until;
    232                 return self;
    233             }
    234         }
    235 
    236         Filter::copy_from(&self).until(until).build()
    237     }
    238 
    239     pub fn since(&self) -> Option<u64> {
    240         for field in self {
    241             if let FilterField::Since(since) = field {
    242                 return Some(since);
    243             }
    244         }
    245 
    246         None
    247     }
    248 
    249     pub fn limit(&self) -> Option<u64> {
    250         for field in self {
    251             if let FilterField::Limit(limit) = field {
    252                 return Some(limit);
    253             }
    254         }
    255 
    256         None
    257     }
    258 
    259     pub fn until(&self) -> Option<u64> {
    260         for field in self {
    261             if let FilterField::Until(until) = field {
    262                 return Some(until);
    263             }
    264         }
    265 
    266         None
    267     }
    268 
    269     pub fn since_mut(self, since: u64) -> Self {
    270         for field in self.mut_iter() {
    271             if let MutFilterField::Since(val) = field {
    272                 *val = since;
    273                 return self;
    274             }
    275         }
    276 
    277         Filter::copy_from(&self).since(since).build()
    278     }
    279 
    280     pub fn as_ptr(&self) -> *const bindings::ndb_filter {
    281         self.data.as_ptr()
    282     }
    283 
    284     pub fn as_mut_ptr(&mut self) -> *mut bindings::ndb_filter {
    285         self.data.as_mut_ptr()
    286     }
    287 
    288     pub fn json_with_bufsize(&self, bufsize: usize) -> Result<String> {
    289         let mut buf = Vec::with_capacity(bufsize);
    290         unsafe {
    291             let size = bindings::ndb_filter_json(
    292                 self.as_ptr(),
    293                 buf.as_mut_ptr() as *mut ::std::os::raw::c_char,
    294                 bufsize as ::std::os::raw::c_int,
    295             ) as usize;
    296 
    297             // Step 4: Check the return value for success
    298             if size == 0 {
    299                 return Err(Error::BufferOverflow); // Handle the error appropriately
    300             }
    301 
    302             buf.set_len(size);
    303 
    304             Ok(std::str::from_utf8_unchecked(&buf[..size - 1]).to_string())
    305         }
    306     }
    307 
    308     pub fn json(&self) -> Result<String> {
    309         // 1mb buffer
    310         self.json_with_bufsize(1024usize * 1024usize)
    311     }
    312 }
    313 
    314 impl Default for FilterBuilder {
    315     fn default() -> Self {
    316         FilterBuilder::new()
    317     }
    318 }
    319 
    320 impl FilterBuilder {
    321     pub fn new() -> FilterBuilder {
    322         Self::default()
    323     }
    324 
    325     pub fn to_ref(&self) -> &bindings::ndb_filter {
    326         &self.data
    327     }
    328 
    329     pub fn mut_iter(&self) -> MutFilterIter<'_> {
    330         self.data.mut_iter()
    331     }
    332 
    333     pub fn as_ptr(&self) -> *const bindings::ndb_filter {
    334         self.data.as_ptr()
    335     }
    336 
    337     pub fn as_mut_ptr(&mut self) -> *mut bindings::ndb_filter {
    338         self.data.as_mut_ptr()
    339     }
    340 
    341     pub fn add_int_element(&mut self, i: u64) -> Result<()> {
    342         let res = unsafe { bindings::ndb_filter_add_int_element(self.as_mut_ptr(), i) };
    343         if res == 0 {
    344             return Err(FilterError::already_exists());
    345         }
    346 
    347         Ok(())
    348     }
    349 
    350     pub fn add_str_element(&mut self, s: &str) -> Result<()> {
    351         let c_str = CString::new(s).expect("string to cstring conversion failed");
    352         let r = unsafe { bindings::ndb_filter_add_str_element(self.as_mut_ptr(), c_str.as_ptr()) };
    353 
    354         if r == 0 {
    355             return Err(FilterError::already_exists());
    356         }
    357 
    358         Ok(())
    359     }
    360 
    361     pub fn add_id_element(&mut self, id: &[u8; 32]) -> Result<()> {
    362         let ptr: *const ::std::os::raw::c_uchar = id.as_ptr() as *const ::std::os::raw::c_uchar;
    363         let r = unsafe { bindings::ndb_filter_add_id_element(self.as_mut_ptr(), ptr) };
    364 
    365         if r == 0 {
    366             return Err(FilterError::already_exists());
    367         }
    368 
    369         Ok(())
    370     }
    371 
    372     pub fn start_field(&mut self, field: bindings::ndb_filter_fieldtype) -> Result<()> {
    373         let r = unsafe { bindings::ndb_filter_start_field(self.as_mut_ptr(), field) };
    374 
    375         if r == 0 {
    376             return Err(FilterError::already_started());
    377         }
    378 
    379         Ok(())
    380     }
    381 
    382     pub fn start_tags_field(&mut self, tag: char) -> Result<()> {
    383         let r =
    384             unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
    385         if r == 0 {
    386             return Err(FilterError::already_started());
    387         }
    388         Ok(())
    389     }
    390 
    391     pub fn start_kinds_field(&mut self) -> Result<()> {
    392         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_KINDS)
    393     }
    394 
    395     pub fn start_authors_field(&mut self) -> Result<()> {
    396         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_AUTHORS)
    397     }
    398 
    399     pub fn start_since_field(&mut self) -> Result<()> {
    400         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_SINCE)
    401     }
    402 
    403     pub fn start_until_field(&mut self) -> Result<()> {
    404         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_UNTIL)
    405     }
    406 
    407     pub fn start_limit_field(&mut self) -> Result<()> {
    408         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_LIMIT)
    409     }
    410 
    411     pub fn start_ids_field(&mut self) -> Result<()> {
    412         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_IDS)
    413     }
    414 
    415     pub fn start_search_field(&mut self) -> Result<()> {
    416         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_SEARCH)
    417     }
    418 
    419     #[allow(dead_code)]
    420     pub fn start_events_field(&mut self) -> Result<()> {
    421         self.start_tags_field('e')
    422     }
    423 
    424     pub fn start_pubkeys_field(&mut self) -> Result<()> {
    425         self.start_tags_field('p')
    426     }
    427 
    428     pub fn start_tag_field(&mut self, tag: char) -> Result<()> {
    429         let r =
    430             unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
    431         if r == 0 {
    432             return Err(FilterError::FieldAlreadyStarted.into());
    433         }
    434         Ok(())
    435     }
    436 
    437     pub fn end_field(&mut self) {
    438         unsafe {
    439             bindings::ndb_filter_end_field(self.as_mut_ptr());
    440         };
    441     }
    442 
    443     pub fn events<'a, I>(mut self, events: I) -> Self
    444     where
    445         I: IntoIterator<Item = &'a [u8; 32]>,
    446     {
    447         self.start_tag_field('e').unwrap();
    448         for id in events {
    449             self.add_id_element(id).unwrap();
    450         }
    451         self.end_field();
    452         self
    453     }
    454 
    455     pub fn event(mut self, id: &[u8; 32]) -> Self {
    456         self.start_tag_field('e').unwrap();
    457         self.add_id_element(id).unwrap();
    458         self.end_field();
    459         self
    460     }
    461 
    462     pub fn search(mut self, search: &str) -> Self {
    463         self.start_search_field().unwrap();
    464         self.add_str_element(search).unwrap();
    465         self.end_field();
    466         self
    467     }
    468 
    469     pub fn ids<'a, I>(mut self, ids: I) -> Self
    470     where
    471         I: IntoIterator<Item = &'a [u8; 32]>,
    472     {
    473         self.start_ids_field().unwrap();
    474         for id in ids {
    475             self.add_id_element(id).unwrap();
    476         }
    477         self.end_field();
    478         self
    479     }
    480 
    481     pub fn pubkeys<'a, I>(mut self, pubkeys: I) -> Self
    482     where
    483         I: IntoIterator<Item = &'a [u8; 32]>,
    484     {
    485         self.start_tag_field('p').unwrap();
    486         for pk in pubkeys {
    487             self.add_id_element(pk).unwrap();
    488         }
    489         self.end_field();
    490         self
    491     }
    492 
    493     pub fn authors<'a, I>(mut self, authors: I) -> Self
    494     where
    495         I: IntoIterator<Item = &'a [u8; 32]>,
    496     {
    497         self.start_authors_field().unwrap();
    498         for author in authors {
    499             self.add_id_element(author).unwrap();
    500         }
    501         self.end_field();
    502         self
    503     }
    504 
    505     pub fn kinds<I>(mut self, kinds: I) -> Self
    506     where
    507         I: IntoIterator<Item = u64>,
    508     {
    509         self.start_kinds_field().unwrap();
    510         for kind in kinds {
    511             self.add_int_element(kind).unwrap();
    512         }
    513         self.end_field();
    514         self
    515     }
    516 
    517     pub fn pubkey<'a, I>(mut self, pubkeys: I) -> Self
    518     where
    519         I: IntoIterator<Item = &'a [u8; 32]>,
    520     {
    521         self.start_pubkeys_field().unwrap();
    522         for pubkey in pubkeys {
    523             self.add_id_element(pubkey).unwrap();
    524         }
    525         self.end_field();
    526         self
    527     }
    528 
    529     pub fn tags<'a, I>(mut self, tags: I, tag: char) -> Self
    530     where
    531         I: IntoIterator<Item = &'a str>,
    532     {
    533         self.start_tag_field(tag).unwrap();
    534         for tag in tags {
    535             self.add_str_element(tag).unwrap();
    536         }
    537         self.end_field();
    538         self
    539     }
    540 
    541     pub fn since(mut self, since: u64) -> Self {
    542         for field in self.mut_iter() {
    543             if let MutFilterField::Since(val) = field {
    544                 *val = since;
    545                 return self;
    546             }
    547         }
    548 
    549         self.start_since_field().unwrap();
    550         self.add_int_element(since).unwrap();
    551         self.end_field();
    552         self
    553     }
    554 
    555     pub fn until(mut self, until: u64) -> Self {
    556         for field in self.mut_iter() {
    557             if let MutFilterField::Until(val) = field {
    558                 *val = until;
    559                 return self;
    560             }
    561         }
    562 
    563         self.start_until_field().unwrap();
    564         self.add_int_element(until).unwrap();
    565         self.end_field();
    566         self
    567     }
    568 
    569     pub fn limit(mut self, limit: u64) -> Self {
    570         for field in self.mut_iter() {
    571             if let MutFilterField::Limit(val) = field {
    572                 *val = limit;
    573                 return self;
    574             }
    575         }
    576 
    577         self.start_limit_field().unwrap();
    578         self.add_int_element(limit).unwrap();
    579         self.end_field();
    580         self
    581     }
    582 
    583     pub fn build(&mut self) -> Filter {
    584         unsafe {
    585             bindings::ndb_filter_end(self.as_mut_ptr());
    586         };
    587         Filter { data: self.data }
    588     }
    589 }
    590 
    591 impl Drop for Filter {
    592     fn drop(&mut self) {
    593         debug!("dropping filter {:?}", self);
    594         unsafe { bindings::ndb_filter_destroy(self.as_mut_ptr()) };
    595     }
    596 }
    597 
    598 impl Drop for FilterBuilder {
    599     fn drop(&mut self) {
    600         debug!("dropping filter builder");
    601     }
    602 }
    603 
    604 #[derive(Debug, Copy, Clone)]
    605 pub struct MutFilterIter<'a> {
    606     filter: &'a bindings::ndb_filter,
    607     index: i32,
    608 }
    609 
    610 impl<'a> MutFilterIter<'a> {
    611     pub(crate) fn new(filter: &'a bindings::ndb_filter) -> Self {
    612         let index = 0;
    613         MutFilterIter { filter, index }
    614     }
    615 
    616     pub fn done(&self) -> bool {
    617         self.index >= self.filter.num_elements
    618     }
    619 }
    620 
    621 #[derive(Debug, Copy, Clone)]
    622 pub struct FilterIter<'a> {
    623     filter: &'a bindings::ndb_filter,
    624     index: i32,
    625 }
    626 
    627 /// Filter element: `authors`, `limit`, etc
    628 #[derive(Copy, Clone, Debug)]
    629 pub struct FilterElements<'a> {
    630     filter: &'a bindings::ndb_filter,
    631     elements: *mut bindings::ndb_filter_elements,
    632 }
    633 
    634 #[derive(Copy, Clone, Debug)]
    635 pub struct FilterIdElements<'a> {
    636     filter: &'a bindings::ndb_filter,
    637     elements: *mut bindings::ndb_filter_elements,
    638 }
    639 
    640 #[derive(Copy, Clone, Debug)]
    641 pub struct FilterIntElements<'a> {
    642     _filter: &'a bindings::ndb_filter,
    643     elements: *mut bindings::ndb_filter_elements,
    644 }
    645 
    646 pub struct FilterIdElemIter<'a> {
    647     ids: FilterIdElements<'a>,
    648     index: i32,
    649 }
    650 
    651 pub struct FilterIntElemIter<'a> {
    652     ints: FilterIntElements<'a>,
    653     index: i32,
    654 }
    655 
    656 impl<'a> FilterIdElemIter<'a> {
    657     pub(crate) fn new(ids: FilterIdElements<'a>) -> Self {
    658         let index = 0;
    659         Self { ids, index }
    660     }
    661 
    662     pub fn done(&self) -> bool {
    663         self.index >= self.ids.count()
    664     }
    665 }
    666 
    667 impl<'a> FilterIntElemIter<'a> {
    668     pub(crate) fn new(ints: FilterIntElements<'a>) -> Self {
    669         let index = 0;
    670         Self { ints, index }
    671     }
    672 
    673     pub fn done(&self) -> bool {
    674         self.index >= self.ints.count()
    675     }
    676 }
    677 
    678 impl<'a> FilterIdElements<'a> {
    679     pub(crate) fn new(
    680         filter: &'a bindings::ndb_filter,
    681         elements: *mut bindings::ndb_filter_elements,
    682     ) -> Self {
    683         Self { filter, elements }
    684     }
    685 
    686     pub fn count(&self) -> i32 {
    687         unsafe { &*self.elements }.count
    688     }
    689 
    690     /// Field element type. In the case of ids, it would be FieldElemType::Id, etc
    691     fn elemtype(&self) -> FieldElemType {
    692         FieldElemType::new(unsafe { &*self.elements }.field.elem_type)
    693             .expect("expected valid filter element type")
    694     }
    695 
    696     pub fn get(self, index: i32) -> Option<&'a [u8; 32]> {
    697         assert!(self.elemtype() == FieldElemType::Id);
    698 
    699         let id = unsafe {
    700             bindings::ndb_filter_get_id_element(self.filter.as_ptr(), self.elements, index)
    701                 as *const [u8; 32]
    702         };
    703 
    704         if id.is_null() {
    705             return None;
    706         }
    707 
    708         Some(unsafe { &*id })
    709     }
    710 }
    711 
    712 impl<'a> FilterIntElements<'a> {
    713     pub(crate) fn new(
    714         filter: &'a bindings::ndb_filter,
    715         elements: *mut bindings::ndb_filter_elements,
    716     ) -> Self {
    717         Self {
    718             _filter: filter,
    719             elements,
    720         }
    721     }
    722 
    723     pub fn count(&self) -> i32 {
    724         unsafe { &*self.elements }.count
    725     }
    726 
    727     /// Field element type. In the case of ids, it would be FieldElemType::Id, etc
    728     fn elemtype(&self) -> FieldElemType {
    729         FieldElemType::new(unsafe { &*self.elements }.field.elem_type)
    730             .expect("expected valid filter element type")
    731     }
    732 
    733     pub fn get(self, index: i32) -> Option<u64> {
    734         if index >= self.count() {
    735             return None;
    736         }
    737         assert!(self.elemtype() == FieldElemType::Int);
    738         Some(unsafe { bindings::ndb_filter_get_int_element(self.elements, index) })
    739     }
    740 }
    741 
    742 pub enum FilterField<'a> {
    743     Ids(FilterIdElements<'a>),
    744     Authors(FilterIdElements<'a>),
    745     Kinds(FilterIntElements<'a>),
    746     Tags(char, FilterElements<'a>),
    747     Search(&'a str),
    748     Since(u64),
    749     Until(u64),
    750     Limit(u64),
    751 }
    752 
    753 pub enum MutFilterField<'a> {
    754     Since(&'a mut u64),
    755     Until(&'a mut u64),
    756     Limit(&'a mut u64),
    757 }
    758 
    759 impl<'a> FilterField<'a> {
    760     pub fn new(elements: FilterElements<'a>) -> Self {
    761         match elements.fieldtype() {
    762             FilterFieldType::Search => {
    763                 for element in elements {
    764                     if let FilterElement::Str(s) = element {
    765                         return FilterField::Search(s);
    766                     }
    767                 }
    768 
    769                 panic!("something is very wrong");
    770             }
    771 
    772             FilterFieldType::Ids => {
    773                 FilterField::Ids(FilterIdElements::new(elements.filter(), elements.as_ptr()))
    774             }
    775 
    776             FilterFieldType::Authors => {
    777                 FilterField::Authors(FilterIdElements::new(elements.filter(), elements.as_ptr()))
    778             }
    779 
    780             FilterFieldType::Kinds => {
    781                 FilterField::Kinds(FilterIntElements::new(elements.filter(), elements.as_ptr()))
    782             }
    783 
    784             FilterFieldType::Tags => FilterField::Tags(elements.tag(), elements),
    785 
    786             FilterFieldType::Since => FilterField::Since(
    787                 FilterIntElements::new(elements.filter(), elements.as_ptr())
    788                     .into_iter()
    789                     .next()
    790                     .expect("expected since in filter"),
    791             ),
    792 
    793             FilterFieldType::Until => FilterField::Until(
    794                 FilterIntElements::new(elements.filter(), elements.as_ptr())
    795                     .into_iter()
    796                     .next()
    797                     .expect("expected until in filter"),
    798             ),
    799 
    800             FilterFieldType::Limit => FilterField::Limit(
    801                 FilterIntElements::new(elements.filter(), elements.as_ptr())
    802                     .into_iter()
    803                     .next()
    804                     .expect("expected limit in filter"),
    805             ),
    806         }
    807     }
    808 }
    809 
    810 impl<'a> FilterElements<'a> {
    811     pub(crate) fn new(
    812         filter: &'a bindings::ndb_filter,
    813         elements: *mut bindings::ndb_filter_elements,
    814     ) -> Self {
    815         FilterElements { filter, elements }
    816     }
    817 
    818     pub fn filter(self) -> &'a bindings::ndb_filter {
    819         self.filter
    820     }
    821 
    822     pub fn as_ptr(self) -> *mut bindings::ndb_filter_elements {
    823         self.elements
    824     }
    825 
    826     pub fn count(&self) -> i32 {
    827         unsafe { &*self.elements }.count
    828     }
    829 
    830     pub fn field(self) -> FilterField<'a> {
    831         FilterField::new(self)
    832     }
    833 
    834     /// Mutably access since, until, limit. We can probably do others in
    835     /// the future, but this is the most useful at the moment
    836     pub fn field_mut(self) -> Option<MutFilterField<'a>> {
    837         if self.count() != 1 {
    838             return None;
    839         }
    840 
    841         if self.elemtype() != FieldElemType::Int {
    842             return None;
    843         }
    844 
    845         match self.fieldtype() {
    846             FilterFieldType::Since => Some(MutFilterField::Since(self.get_mut_int(0))),
    847             FilterFieldType::Until => Some(MutFilterField::Until(self.get_mut_int(0))),
    848             FilterFieldType::Limit => Some(MutFilterField::Limit(self.get_mut_int(0))),
    849             _ => None,
    850         }
    851     }
    852 
    853     pub fn get_mut_int(&self, index: i32) -> &'a mut u64 {
    854         unsafe { &mut *bindings::ndb_filter_get_int_element_ptr(self.elements, index) }
    855     }
    856 
    857     pub fn get(self, index: i32) -> Option<FilterElement<'a>> {
    858         if index >= self.count() {
    859             return None;
    860         }
    861 
    862         match self.elemtype() {
    863             FieldElemType::Id => {
    864                 let id = unsafe {
    865                     bindings::ndb_filter_get_id_element(self.filter.as_ptr(), self.elements, index)
    866                         as *const [u8; 32]
    867                 };
    868                 if id.is_null() {
    869                     return None;
    870                 }
    871                 Some(FilterElement::Id(unsafe { &*id }))
    872             }
    873 
    874             FieldElemType::Str => {
    875                 let cstr = unsafe {
    876                     bindings::ndb_filter_get_string_element(
    877                         self.filter.as_ptr(),
    878                         self.elements,
    879                         index,
    880                     )
    881                 };
    882                 if cstr.is_null() {
    883                     return None;
    884                 }
    885                 let str = unsafe {
    886                     let byte_slice =
    887                         std::slice::from_raw_parts(cstr as *const u8, libc::strlen(cstr));
    888                     std::str::from_utf8_unchecked(byte_slice)
    889                 };
    890                 Some(FilterElement::Str(str))
    891             }
    892 
    893             FieldElemType::Int => {
    894                 let num = unsafe { bindings::ndb_filter_get_int_element(self.elements, index) };
    895                 Some(FilterElement::Int(num))
    896             }
    897         }
    898     }
    899 
    900     /// Field element type. In the case of ids, it would be FieldElemType::Id, etc
    901     pub fn elemtype(&self) -> FieldElemType {
    902         FieldElemType::new(unsafe { &*self.elements }.field.elem_type)
    903             .expect("expected valid filter element type")
    904     }
    905 
    906     /// Field element type. In the case of ids, it would be FieldElemType::Id, etc
    907     pub fn tag(&self) -> char {
    908         (unsafe { &*self.elements }.field.tag as u8) as char
    909     }
    910 
    911     pub fn fieldtype(self) -> FilterFieldType {
    912         FilterFieldType::new(unsafe { &*self.elements }.field.type_)
    913             .expect("expected valid fieldtype")
    914     }
    915 }
    916 
    917 impl<'a> FilterIter<'a> {
    918     pub fn new(filter: &'a bindings::ndb_filter) -> Self {
    919         let index = 0;
    920         FilterIter { filter, index }
    921     }
    922 
    923     pub fn done(&self) -> bool {
    924         self.index >= self.filter.num_elements
    925     }
    926 }
    927 
    928 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
    929 pub enum FilterFieldType {
    930     Ids,
    931     Authors,
    932     Kinds,
    933     Tags,
    934     Since,
    935     Until,
    936     Limit,
    937     Search,
    938 }
    939 
    940 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
    941 pub enum FieldElemType {
    942     Str,
    943     Id,
    944     Int,
    945 }
    946 
    947 impl FieldElemType {
    948     pub(crate) fn new(val: bindings::ndb_generic_element_type) -> Option<Self> {
    949         if val == bindings::ndb_generic_element_type_NDB_ELEMENT_UNKNOWN {
    950             None
    951         } else if val == bindings::ndb_generic_element_type_NDB_ELEMENT_STRING {
    952             Some(FieldElemType::Str)
    953         } else if val == bindings::ndb_generic_element_type_NDB_ELEMENT_ID {
    954             Some(FieldElemType::Id)
    955         } else if val == bindings::ndb_generic_element_type_NDB_ELEMENT_INT {
    956             Some(FieldElemType::Int)
    957         } else {
    958             None
    959         }
    960     }
    961 }
    962 
    963 impl FilterFieldType {
    964     pub(crate) fn new(val: bindings::ndb_filter_fieldtype) -> Option<Self> {
    965         if val == bindings::ndb_filter_fieldtype_NDB_FILTER_IDS {
    966             Some(FilterFieldType::Ids)
    967         } else if val == bindings::ndb_filter_fieldtype_NDB_FILTER_AUTHORS {
    968             Some(FilterFieldType::Authors)
    969         } else if val == bindings::ndb_filter_fieldtype_NDB_FILTER_KINDS {
    970             Some(FilterFieldType::Kinds)
    971         } else if val == bindings::ndb_filter_fieldtype_NDB_FILTER_TAGS {
    972             Some(FilterFieldType::Tags)
    973         } else if val == bindings::ndb_filter_fieldtype_NDB_FILTER_SINCE {
    974             Some(FilterFieldType::Since)
    975         } else if val == bindings::ndb_filter_fieldtype_NDB_FILTER_UNTIL {
    976             Some(FilterFieldType::Until)
    977         } else if val == bindings::ndb_filter_fieldtype_NDB_FILTER_LIMIT {
    978             Some(FilterFieldType::Limit)
    979         } else if val == bindings::ndb_filter_fieldtype_NDB_FILTER_SEARCH {
    980             Some(FilterFieldType::Search)
    981         } else {
    982             None
    983         }
    984     }
    985 }
    986 
    987 impl<'a> IntoIterator for &'a Filter {
    988     type Item = FilterField<'a>;
    989     type IntoIter = FilterIter<'a>;
    990 
    991     fn into_iter(self) -> Self::IntoIter {
    992         FilterIter::new(self.to_ref())
    993     }
    994 }
    995 
    996 impl<'a> IntoIterator for &'a FilterBuilder {
    997     type Item = FilterField<'a>;
    998     type IntoIter = FilterIter<'a>;
    999 
   1000     fn into_iter(self) -> Self::IntoIter {
   1001         FilterIter::new(self.to_ref())
   1002     }
   1003 }
   1004 
   1005 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
   1006 pub enum FilterElement<'a> {
   1007     Str(&'a str),
   1008     Id(&'a [u8; 32]),
   1009     Int(u64),
   1010 }
   1011 
   1012 impl<'a> Iterator for FilterIter<'a> {
   1013     type Item = FilterField<'a>;
   1014 
   1015     fn next(&mut self) -> Option<FilterField<'a>> {
   1016         if self.done() {
   1017             return None;
   1018         }
   1019 
   1020         let ind = self.index;
   1021         self.index += 1;
   1022 
   1023         self.filter.field(ind)
   1024     }
   1025 }
   1026 
   1027 impl<'a> Iterator for MutFilterIter<'a> {
   1028     type Item = MutFilterField<'a>;
   1029 
   1030     fn next(&mut self) -> Option<MutFilterField<'a>> {
   1031         if self.done() {
   1032             return None;
   1033         }
   1034 
   1035         while !self.done() {
   1036             let mnext = self.filter.field_mut(self.index);
   1037             self.index += 1;
   1038 
   1039             if mnext.is_some() {
   1040                 return mnext;
   1041             }
   1042         }
   1043 
   1044         None
   1045     }
   1046 }
   1047 
   1048 impl<'a> IntoIterator for FilterIdElements<'a> {
   1049     type Item = &'a [u8; 32];
   1050     type IntoIter = FilterIdElemIter<'a>;
   1051 
   1052     fn into_iter(self) -> Self::IntoIter {
   1053         FilterIdElemIter::new(self)
   1054     }
   1055 }
   1056 
   1057 impl<'a> IntoIterator for FilterIntElements<'a> {
   1058     type Item = u64;
   1059     type IntoIter = FilterIntElemIter<'a>;
   1060 
   1061     fn into_iter(self) -> Self::IntoIter {
   1062         FilterIntElemIter::new(self)
   1063     }
   1064 }
   1065 
   1066 impl Iterator for FilterIntElemIter<'_> {
   1067     type Item = u64;
   1068 
   1069     fn next(&mut self) -> Option<u64> {
   1070         if self.done() {
   1071             return None;
   1072         }
   1073 
   1074         let ind = self.index;
   1075         self.index += 1;
   1076 
   1077         self.ints.get(ind)
   1078     }
   1079 }
   1080 
   1081 impl<'a> Iterator for FilterIdElemIter<'a> {
   1082     type Item = &'a [u8; 32];
   1083 
   1084     fn next(&mut self) -> Option<&'a [u8; 32]> {
   1085         if self.done() {
   1086             return None;
   1087         }
   1088 
   1089         let ind = self.index;
   1090         self.index += 1;
   1091 
   1092         self.ids.get(ind)
   1093     }
   1094 }
   1095 
   1096 impl<'a> IntoIterator for FilterElements<'a> {
   1097     type Item = FilterElement<'a>;
   1098     type IntoIter = FilterElemIter<'a>;
   1099 
   1100     fn into_iter(self) -> Self::IntoIter {
   1101         FilterElemIter::new(self)
   1102     }
   1103 }
   1104 
   1105 impl<'a> Iterator for FilterElemIter<'a> {
   1106     type Item = FilterElement<'a>;
   1107 
   1108     fn next(&mut self) -> Option<FilterElement<'a>> {
   1109         let element = self.elements.get(self.index);
   1110         if element.is_some() {
   1111             self.index += 1;
   1112             element
   1113         } else {
   1114             None
   1115         }
   1116     }
   1117 }
   1118 
   1119 #[derive(Copy, Clone, Debug)]
   1120 pub struct FilterElemIter<'a> {
   1121     elements: FilterElements<'a>,
   1122     index: i32,
   1123 }
   1124 
   1125 impl<'a> FilterElemIter<'a> {
   1126     pub(crate) fn new(elements: FilterElements<'a>) -> Self {
   1127         let index = 0;
   1128         FilterElemIter { elements, index }
   1129     }
   1130 }
   1131 
   1132 #[cfg(test)]
   1133 mod tests {
   1134     use super::*;
   1135 
   1136     #[test]
   1137     fn filter_limit_iter_works() {
   1138         let filter = Filter::new().limit(42).build();
   1139         let mut hit = 0;
   1140         for element in &filter {
   1141             if let FilterField::Limit(42) = element {
   1142                 hit += 1;
   1143             }
   1144         }
   1145         assert!(hit == 1);
   1146     }
   1147 
   1148     #[test]
   1149     fn filter_quick_since_mut_works() {
   1150         let id: [u8; 32] = [
   1151             0xfb, 0x16, 0x5b, 0xe2, 0x2c, 0x7b, 0x25, 0x18, 0xb7, 0x49, 0xaa, 0xbb, 0x71, 0x40,
   1152             0xc7, 0x3f, 0x08, 0x87, 0xfe, 0x84, 0x47, 0x5c, 0x82, 0x78, 0x57, 0x00, 0x66, 0x3b,
   1153             0xe8, 0x5b, 0xa8, 0x59,
   1154         ];
   1155 
   1156         let mut hit = 0;
   1157         let mut filter = Filter::new().ids([&id, &id, &id]).build();
   1158 
   1159         // mutate
   1160         filter = filter.since_mut(3);
   1161 
   1162         for element in &filter {
   1163             if let FilterField::Since(s) = element {
   1164                 hit += 1;
   1165                 assert_eq!(s, 3);
   1166             }
   1167         }
   1168         assert!(hit == 1);
   1169     }
   1170 
   1171     #[test]
   1172     fn filter_since_mut_works() {
   1173         let id: [u8; 32] = [
   1174             0xfb, 0x16, 0x5b, 0xe2, 0x2c, 0x7b, 0x25, 0x18, 0xb7, 0x49, 0xaa, 0xbb, 0x71, 0x40,
   1175             0xc7, 0x3f, 0x08, 0x87, 0xfe, 0x84, 0x47, 0x5c, 0x82, 0x78, 0x57, 0x00, 0x66, 0x3b,
   1176             0xe8, 0x5b, 0xa8, 0x59,
   1177         ];
   1178 
   1179         let mut hit = 0;
   1180         let filter = Filter::new().ids([&id, &id, &id]).since(1);
   1181 
   1182         for element in filter.mut_iter() {
   1183             if let MutFilterField::Since(since_ref) = element {
   1184                 hit += 1;
   1185                 assert_eq!(*since_ref, 1);
   1186                 *since_ref = 2;
   1187             }
   1188         }
   1189         for element in &filter {
   1190             if let FilterField::Since(s) = element {
   1191                 hit += 1;
   1192                 assert_eq!(s, 2);
   1193             }
   1194         }
   1195         assert!(hit == 2);
   1196     }
   1197 
   1198     #[test]
   1199     fn filter_id_iter_works() {
   1200         let id: [u8; 32] = [
   1201             0xfb, 0x16, 0x5b, 0xe2, 0x2c, 0x7b, 0x25, 0x18, 0xb7, 0x49, 0xaa, 0xbb, 0x71, 0x40,
   1202             0xc7, 0x3f, 0x08, 0x87, 0xfe, 0x84, 0x47, 0x5c, 0x82, 0x78, 0x57, 0x00, 0x66, 0x3b,
   1203             0xe8, 0x5b, 0xa8, 0x59,
   1204         ];
   1205 
   1206         let filter = Filter::new().ids([&id, &id, &id]).build();
   1207         let mut hit = 0;
   1208         for element in &filter {
   1209             if let FilterField::Ids(ids) = element {
   1210                 for same_id in ids {
   1211                     hit += 1;
   1212                     assert!(same_id == &id);
   1213                 }
   1214             }
   1215         }
   1216         assert!(hit == 3);
   1217     }
   1218 
   1219     #[test]
   1220     fn filter_int_iter_works() {
   1221         let filter = Filter::new().kinds(vec![1, 2, 3]).build();
   1222         let mut hit = 0;
   1223         for element in &filter {
   1224             if let FilterField::Kinds(ks) = element {
   1225                 hit += 1;
   1226                 assert!(vec![1, 2, 3] == ks.into_iter().collect::<Vec<u64>>());
   1227             }
   1228         }
   1229         assert!(hit == 1);
   1230     }
   1231 
   1232     #[test]
   1233     fn filter_multiple_field_iter_works() {
   1234         let id: [u8; 32] = [
   1235             0xfb, 0x16, 0x5b, 0xe2, 0x2c, 0x7b, 0x25, 0x18, 0xb7, 0x49, 0xaa, 0xbb, 0x71, 0x40,
   1236             0xc7, 0x3f, 0x08, 0x87, 0xfe, 0x84, 0x47, 0x5c, 0x82, 0x78, 0x57, 0x00, 0x66, 0x3b,
   1237             0xe8, 0x5b, 0xa8, 0x59,
   1238         ];
   1239         let filter = Filter::new().event(&id).kinds(vec![1, 2, 3]).build();
   1240         let mut hit = 0;
   1241         for element in &filter {
   1242             if let FilterField::Kinds(ks) = element {
   1243                 hit += 1;
   1244                 assert!(vec![1, 2, 3] == ks.into_iter().collect::<Vec<u64>>());
   1245             } else if let FilterField::Tags('e', ids) = element {
   1246                 for i in ids {
   1247                     hit += 1;
   1248                     assert!(i == FilterElement::Id(&id));
   1249                 }
   1250             }
   1251         }
   1252         assert!(hit == 2);
   1253     }
   1254 }