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 }