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