nostrdb-rs

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

filter.rs (7283B)


      1 use crate::bindings;
      2 use crate::Note;
      3 use std::ffi::CString;
      4 use std::os::raw::c_char;
      5 use std::ptr::null_mut;
      6 use tracing::debug;
      7 
      8 #[derive(Debug)]
      9 pub struct FilterBuilder {
     10     pub data: bindings::ndb_filter,
     11 }
     12 
     13 #[derive(Debug)]
     14 pub struct Filter {
     15     pub data: bindings::ndb_filter,
     16 }
     17 
     18 impl Clone for Filter {
     19     fn clone(&self) -> Self {
     20         let mut new_filter: bindings::ndb_filter = Default::default();
     21         unsafe {
     22             bindings::ndb_filter_clone(
     23                 new_filter.as_mut_ptr(),
     24                 self.as_ptr() as *mut bindings::ndb_filter,
     25             );
     26         };
     27         Filter { data: new_filter }
     28     }
     29 }
     30 
     31 impl bindings::ndb_filter {
     32     fn as_ptr(&self) -> *const bindings::ndb_filter {
     33         self as *const bindings::ndb_filter
     34     }
     35 
     36     fn as_mut_ptr(&mut self) -> *mut bindings::ndb_filter {
     37         self as *mut bindings::ndb_filter
     38     }
     39 }
     40 
     41 impl Default for bindings::ndb_filter {
     42     fn default() -> Self {
     43         let null = null_mut();
     44         let mut filter_data = bindings::ndb_filter {
     45             finalized: 0,
     46             elem_buf: bindings::cursor {
     47                 start: null,
     48                 p: null,
     49                 end: null,
     50             },
     51             data_buf: bindings::cursor {
     52                 start: null,
     53                 p: null,
     54                 end: null,
     55             },
     56             num_elements: 0,
     57             current: -1,
     58             elements: [0, 0, 0, 0, 0, 0, 0],
     59         };
     60 
     61         unsafe {
     62             bindings::ndb_filter_init(filter_data.as_mut_ptr());
     63         };
     64 
     65         filter_data
     66     }
     67 }
     68 
     69 impl Filter {
     70     #[allow(clippy::new_ret_no_self)]
     71     pub fn new() -> FilterBuilder {
     72         FilterBuilder {
     73             data: Default::default(),
     74         }
     75     }
     76 
     77     pub fn matches(&self, note: &Note) -> bool {
     78         unsafe {
     79             bindings::ndb_filter_matches(self.as_ptr() as *mut bindings::ndb_filter, note.as_ptr())
     80                 != 0
     81         }
     82     }
     83 
     84     pub fn as_ptr(&self) -> *const bindings::ndb_filter {
     85         self.data.as_ptr()
     86     }
     87 
     88     pub fn as_mut_ptr(&mut self) -> *mut bindings::ndb_filter {
     89         self.data.as_mut_ptr()
     90     }
     91 }
     92 
     93 impl Default for FilterBuilder {
     94     fn default() -> Self {
     95         FilterBuilder::new()
     96     }
     97 }
     98 
     99 impl FilterBuilder {
    100     pub fn new() -> FilterBuilder {
    101         Self {
    102             data: Default::default(),
    103         }
    104     }
    105 
    106     pub fn as_ptr(&self) -> *const bindings::ndb_filter {
    107         self.data.as_ptr()
    108     }
    109 
    110     pub fn as_mut_ptr(&mut self) -> *mut bindings::ndb_filter {
    111         self.data.as_mut_ptr()
    112     }
    113 
    114     fn add_int_element(&mut self, i: u64) {
    115         unsafe { bindings::ndb_filter_add_int_element(self.as_mut_ptr(), i) };
    116     }
    117 
    118     fn add_str_element(&mut self, s: &str) {
    119         let c_str = CString::new(s).expect("string to cstring conversion failed");
    120         unsafe {
    121             bindings::ndb_filter_add_str_element(self.as_mut_ptr(), c_str.as_ptr());
    122         };
    123     }
    124 
    125     fn add_id_element(&mut self, id: &[u8; 32]) {
    126         let ptr: *const ::std::os::raw::c_uchar = id.as_ptr() as *const ::std::os::raw::c_uchar;
    127         unsafe {
    128             bindings::ndb_filter_add_id_element(self.as_mut_ptr(), ptr);
    129         };
    130     }
    131 
    132     fn start_field(&mut self, field: bindings::ndb_filter_fieldtype) {
    133         unsafe { bindings::ndb_filter_start_field(self.as_mut_ptr(), field) };
    134     }
    135 
    136     fn start_tags_field(&mut self, tag: char) {
    137         unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
    138     }
    139 
    140     fn start_kinds_field(&mut self) {
    141         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_KINDS);
    142     }
    143 
    144     fn start_authors_field(&mut self) {
    145         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_AUTHORS);
    146     }
    147 
    148     fn start_since_field(&mut self) {
    149         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_SINCE);
    150     }
    151 
    152     fn start_until_field(&mut self) {
    153         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_UNTIL);
    154     }
    155 
    156     fn start_limit_field(&mut self) {
    157         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_LIMIT);
    158     }
    159 
    160     fn start_ids_field(&mut self) {
    161         self.start_field(bindings::ndb_filter_fieldtype_NDB_FILTER_IDS);
    162     }
    163 
    164     #[allow(dead_code)]
    165     fn start_events_field(&mut self) {
    166         self.start_tags_field('e');
    167     }
    168 
    169     fn start_pubkeys_field(&mut self) {
    170         self.start_tags_field('p');
    171     }
    172 
    173     fn start_tag_field(&mut self, tag: char) {
    174         unsafe { bindings::ndb_filter_start_tag_field(self.as_mut_ptr(), tag as u8 as c_char) };
    175     }
    176 
    177     fn end_field(&mut self) {
    178         unsafe { bindings::ndb_filter_end_field(self.as_mut_ptr()) }
    179     }
    180 
    181     pub fn events(&mut self, events: Vec<[u8; 32]>) -> &mut Self {
    182         self.start_tag_field('e');
    183         for ref id in events {
    184             self.add_id_element(id);
    185         }
    186         self.end_field();
    187         self
    188     }
    189 
    190     pub fn event(&mut self, id: &[u8; 32]) -> &mut Self {
    191         self.start_tag_field('e');
    192         self.add_id_element(id);
    193         self.end_field();
    194         self
    195     }
    196 
    197     pub fn ids(&mut self, ids: Vec<[u8; 32]>) -> &mut Self {
    198         self.start_ids_field();
    199         for ref id in ids {
    200             self.add_id_element(id);
    201         }
    202         self.end_field();
    203         self
    204     }
    205 
    206     pub fn pubkeys(&mut self, pubkeys: Vec<[u8; 32]>) -> &mut Self {
    207         self.start_tag_field('p');
    208         for ref pk in pubkeys {
    209             self.add_id_element(pk);
    210         }
    211         self.end_field();
    212         self
    213     }
    214 
    215     pub fn authors(&mut self, authors: Vec<[u8; 32]>) -> &mut Self {
    216         self.start_authors_field();
    217         for author in authors {
    218             self.add_id_element(&author);
    219         }
    220         self.end_field();
    221         self
    222     }
    223 
    224     pub fn kinds(&mut self, kinds: Vec<u64>) -> &mut Self {
    225         self.start_kinds_field();
    226         for kind in kinds {
    227             self.add_int_element(kind);
    228         }
    229         self.end_field();
    230         self
    231     }
    232 
    233     pub fn pubkey(&mut self, pubkeys: Vec<[u8; 32]>) -> &mut Self {
    234         self.start_pubkeys_field();
    235         for ref pubkey in pubkeys {
    236             self.add_id_element(pubkey);
    237         }
    238         self.end_field();
    239         self
    240     }
    241 
    242     pub fn tags(&mut self, tags: Vec<String>, tag: char) -> &mut Self {
    243         self.start_tag_field(tag);
    244         for tag in tags {
    245             self.add_str_element(&tag);
    246         }
    247         self.end_field();
    248         self
    249     }
    250 
    251     pub fn since(&mut self, since: u64) -> &mut Self {
    252         self.start_since_field();
    253         self.add_int_element(since);
    254         self.end_field();
    255         self
    256     }
    257 
    258     pub fn until(&mut self, until: u64) -> &mut Self {
    259         self.start_until_field();
    260         self.add_int_element(until);
    261         self.end_field();
    262         self
    263     }
    264 
    265     pub fn limit(&mut self, limit: u64) -> &mut Self {
    266         self.start_limit_field();
    267         self.add_int_element(limit);
    268         self.end_field();
    269         self
    270     }
    271 
    272     pub fn build(&mut self) -> Filter {
    273         unsafe {
    274             bindings::ndb_filter_end(self.as_mut_ptr());
    275         };
    276         Filter { data: self.data }
    277     }
    278 }
    279 
    280 impl Drop for Filter {
    281     fn drop(&mut self) {
    282         debug!("dropping filter {:?}", self);
    283         unsafe { bindings::ndb_filter_destroy(self.as_mut_ptr()) };
    284     }
    285 }