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 }