deterministic_bloom_wasm/
lib.rs1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)]
3#![deny(unreachable_pub, private_in_public)]
4
5use derive_more::{From, Into};
8use deterministic_bloom::const_size::BloomFilter;
9use std::boxed::Box;
10use wasm_bindgen::prelude::{wasm_bindgen, JsError};
11
12#[wasm_bindgen(js_name = "setPanicHook")]
21pub fn set_panic_hook() {
22 #[cfg(feature = "console_error_panic_hook")]
23 console_error_panic_hook::set_once();
24}
25
26macro_rules! gen_bloom {
32 ($name: ident, $n: expr, $k: expr) => {
33 #[doc = concat!("A monomorphic wrapper for [BloomFilter]`s with a size of ", stringify!($n), " bytes and ", stringify!($k), " hash functions.")]
34 #[wasm_bindgen]
35 #[derive(Debug, Default, From, Into)]
36 pub struct $name {
37 pub(crate) boxed: Box<BloomFilter<$n, $k>>,
38 }
39
40 #[wasm_bindgen]
41 impl $name {
42 #[doc = concat!("Initialize a blank [", stringify!($name), "] (i.e. contains no elements).")]
43 #[doc = concat!("use deterministic_bloom_wasm::", stringify!($name), ";")]
48 #[doc = concat!("let blank = ", stringify!($name), "::new();")]
50 #[doc = concat!("assert_eq!(", stringify!($name), "::count_ones(&blank), 0);")]
51 #[wasm_bindgen(constructor)]
53 pub fn new() -> Self {
54 Default::default()
55 }
56
57 #[doc = concat!("Attempt to initialize a [", stringify!($name), "] with a starting array.")]
58 #[doc = concat!("Fails with a [JsError] if the [Vec] is not exactly ", stringify!($n), " bytes long.")]
59 pub fn try_from_vec(vec: Vec<u8>) -> Result<$name, JsError> {
60 $name::try_from(vec).map_err(|e| JsError::new(&e.to_string()))
61 }
62
63 #[doc = concat!("use deterministic_bloom_wasm::", stringify!($name), ";")]
69 #[doc = concat!("let size = ", stringify!($name), "::byte_count();")]
71 #[doc = concat!("assert_eq!(size, ", stringify!($k), ");")]
72 pub fn byte_count() -> usize {
74 $k
75 }
76
77 #[doc = concat!("use deterministic_bloom_wasm::", stringify!($name), ";")]
83 #[doc = concat!("assert_eq!(", stringify!($name), "::hash_count(), ", stringify!($n), ");")]
85 pub fn hash_count() -> usize {
87 $n
88 }
89
90 #[doc = concat!("use deterministic_bloom_wasm::", stringify!($name), ";")]
97 #[doc = concat!("let mut bloom = ", stringify!($name), "::new();")]
99 pub fn insert_vec(&mut self, new_val: Vec<u8>) -> () {
105 self.boxed.insert(&new_val);
106 }
107
108 #[doc = concat!("use deterministic_bloom_wasm::", stringify!($name), ";")]
114 #[doc = concat!("let mut bloom = ", stringify!($name), "::new();")]
116 pub fn contains(&self, item: Vec<u8>) -> bool {
122 self.boxed.contains(&item)
123 }
124
125 #[doc = concat!("use deterministic_bloom_wasm::", stringify!($name), ";")]
131 #[doc = concat!("let mut bloom = ", stringify!($name), "::new();")]
133 #[doc = concat!("assert!(bloom.count_ones() >= ", $k, ");")]
145 #[doc = concat!("assert!(bloom.count_ones() <= 3 * ", $k, ");")]
146 pub fn count_ones(&self) -> usize {
148 self.boxed.count_ones()
149 }
150
151 #[doc = concat!("use deterministic_bloom_wasm::", stringify!($name), ";")]
157 #[doc = concat!("let mut bloom = ", stringify!($name), "::new();")]
159 #[doc = concat!("assert_ne!(bloom.as_bytes(), vec![0; ", $n, "]);")]
162 #[doc = concat!("assert_eq!(bloom.as_bytes().len(), ", $n, ");")]
163 pub fn as_bytes(&self) -> Vec<u8> {
165 self.boxed.as_bytes().to_vec()
166 }
167 }
168
169 impl From<BloomFilter<$n, $k>> for $name {
170 fn from(bloom: BloomFilter<$n, $k>) -> Self {
171 $name {
172 boxed: Box::new(bloom)
173 }
174 }
175 }
176
177 impl TryFrom<Vec<u8>> for $name {
178 type Error = deterministic_bloom::common::Error;
179
180 fn try_from(vec: Vec<u8>) -> Result<Self, deterministic_bloom::common::Error> {
181 <BloomFilter<$n, $k>>::try_from(vec).map($name::from)
182 }
183 }
184 };
185}
186
187gen_bloom!(SmallBloomFilter, 256, 13);
188gen_bloom!(MediumBloomFilter, 4096, 17);
189gen_bloom!(LargeBloomFilter, 1048576, 23);