ternary_tree_wasm/
lib.rs

1#![forbid(unsafe_code)]
2
3extern crate ternary_tree;
4extern crate js_sys;
5
6use wasm_bindgen::prelude::*;
7use ternary_tree::{TstIterator, TstCompleteIterator, TstNeighborIterator, TstCrosswordIterator};
8
9
10#[wasm_bindgen]
11pub struct Tst {
12
13    tree: ternary_tree::Tst<JsValue>
14}
15
16#[wasm_bindgen]
17#[derive(PartialEq)]
18pub enum Direction { Forward, Backward }
19
20
21#[wasm_bindgen]
22impl Tst {
23
24    pub fn new() -> Self {
25
26        Tst { tree: ternary_tree::Tst::new() }
27    }
28
29    pub fn insert(&mut self, key: &str, value: JsValue) -> JsValue {
30
31        match self.tree.insert(key, value) {
32
33            None => JsValue::null(), Some(value) => value
34        }
35    }
36
37    pub fn get(&self, key: &str) -> JsValue {
38
39        match self.tree.get(key) {
40
41            None => JsValue::null(), Some(value) => value.clone()
42        }
43    }
44
45    pub fn remove(&mut self, key: &str) -> JsValue {
46
47        match self.tree.remove(key) {
48
49            None => JsValue::null(), Some(value) => value.clone()
50        }
51    }
52
53    pub fn count(&self) -> usize {
54
55       self.tree.len()
56    }
57
58    pub fn clear(&mut self) {
59
60        self.tree.clear()
61    }
62
63    pub fn pretty_print(&self) -> String {
64
65        let mut w = Vec::new();
66
67        self.tree.pretty_print(&mut w);
68
69        match String::from_utf8(w) {
70
71            Ok(s) => s,
72            Err(_) => String::new()
73        }
74    }
75
76    pub fn visit(&self, callback: &js_sys::Function, direction: Direction) {
77
78        let mut it = self.tree.iter();
79        let this = JsValue::NULL;
80        let next_fn = if direction == Direction::Forward { TstIterator::<JsValue>::next } else { TstIterator::<JsValue>::next_back };
81        let key_fn = if direction == Direction::Forward { TstIterator::<JsValue>::current_key } else { TstIterator::<JsValue>::current_key_back };
82
83        while let Some(value) = (next_fn)(&mut it) {
84
85            let key = JsValue::from((key_fn)(&mut it));
86            let should_break = match callback.call2(&this, &key, value) {
87
88                Ok(res) => res.is_truthy(),
89                Err(_) => true
90            };
91
92            if should_break {
93
94                break;
95            }
96        }
97    }
98
99    pub fn complete(&self, prefix: &str, callback: &js_sys::Function, direction: Direction) {
100
101        let mut it = self.tree.iter_complete(prefix);
102        let this = JsValue::NULL;
103        let next_fn = if direction == Direction::Forward { TstCompleteIterator::<JsValue>::next } else { TstCompleteIterator::<JsValue>::next_back };
104        let key_fn = if direction == Direction::Forward { TstCompleteIterator::<JsValue>::current_key } else { TstCompleteIterator::<JsValue>::current_key_back };
105
106        while let Some(value) = (next_fn)(&mut it) {
107
108            let key = JsValue::from((key_fn)(&mut it));
109            let res = callback.call2(&this, &key, value);
110
111            let should_break = match res {
112
113                Ok(val) => val.is_truthy(),
114                Err(_) => true
115            };
116
117            if should_break {
118
119                break;
120            }
121        }
122    }
123
124    pub fn neighbor(&self, neighbor_key: &str, range: usize, callback: &js_sys::Function, direction: Direction) {
125
126        let mut it = self.tree.iter_neighbor(neighbor_key, range);
127        let this = JsValue::NULL;
128        let next_fn = if direction == Direction::Forward { TstNeighborIterator::<JsValue>::next } else { TstNeighborIterator::<JsValue>::next_back };
129        let key_fn = if direction == Direction::Forward { TstNeighborIterator::<JsValue>::current_key } else { TstNeighborIterator::<JsValue>::current_key_back };
130
131        while let Some(value) = (next_fn)(&mut it) {
132
133            let key = JsValue::from((key_fn)(&mut it));
134            let res = callback.call2(&this, &key, value);
135
136            let should_break = match res {
137
138                Ok(val) => val.is_truthy(),
139                Err(_) => true
140            };
141
142            if should_break {
143
144                break;
145            }
146        }
147    }
148
149    pub fn crossword(&self, pattern: &str, joker: char, callback: &js_sys::Function, direction: Direction) {
150
151        let mut it = self.tree.iter_crossword(pattern, joker);
152        let this = JsValue::NULL;
153        let next_fn = if direction == Direction::Forward { TstCrosswordIterator::<JsValue>::next } else { TstCrosswordIterator::<JsValue>::next_back };
154        let key_fn = if direction == Direction::Forward { TstCrosswordIterator::<JsValue>::current_key } else { TstCrosswordIterator::<JsValue>::current_key_back };
155
156        while let Some(value) = (next_fn)(&mut it) {
157
158            let key = JsValue::from((key_fn)(&mut it));
159            let res = callback.call2(&this, &key, value);
160
161            let should_break = match res {
162
163                Ok(val) => val.is_truthy(),
164                Err(_) => true
165            };
166
167            if should_break {
168
169                break;
170            }
171        }
172    }
173}