fst_no_std/map.rs
1#[cfg(feature = "alloc")]
2use core::fmt;
3#[cfg(feature = "std")]
4use core::iter;
5#[cfg(feature = "alloc")]
6use core::iter::FromIterator;
7#[cfg(feature = "std")]
8use std::io;
9
10#[cfg(feature = "alloc")]
11use crate::automaton::{AlwaysMatch, Automaton};
12use crate::raw;
13pub use crate::raw::IndexedValue;
14#[cfg(feature = "alloc")]
15use crate::stream::IntoStreamer;
16use crate::stream::Streamer;
17use crate::Result;
18#[cfg(feature = "alloc")]
19use alloc::{string::String, vec::Vec};
20
21/// Map is a lexicographically ordered map from byte strings to integers.
22///
23/// A `Map` is constructed with the `MapBuilder` type. Alternatively, a `Map`
24/// can be constructed in memory from a lexicographically ordered iterator
25/// of key-value pairs (`Map::from_iter`).
26///
27/// A key feature of `Map` is that it can be serialized to disk compactly. Its
28/// underlying representation is built such that the `Map` can be memory mapped
29/// and searched without necessarily loading the entire map into memory.
30///
31/// It supports most common operations associated with maps, such as key
32/// lookup and search. It also supports set operations on its keys along with
33/// the ability to specify how conflicting values are merged together. Maps
34/// also support range queries and automata based searches (e.g. a regular
35/// expression).
36///
37/// Maps are represented by a finite state transducer where inputs are the keys
38/// and outputs are the values. As such, maps have the following invariants:
39///
40/// 1. Once constructed, a `Map` can never be modified.
41/// 2. Maps must be constructed with lexicographically ordered byte sequences.
42/// There is no restricting on the ordering of values.
43///
44/// # Differences with sets
45///
46/// Maps and sets are represented by the same underlying data structure: the
47/// finite state transducer. The principal difference between them is that
48/// sets always have their output values set to `0`. This has an impact on the
49/// representation size and is reflected in the type system for convenience.
50/// A secondary but subtle difference is that duplicate keys can be added
51/// to a set, but it is an error to do so with maps. That is, a set can have
52/// the same key added sequentially, but a map can't.
53///
54/// # The future
55///
56/// It is regrettable that the output value is fixed to `u64`. Indeed, it is
57/// not necessary, but it was a major simplification in the implementation.
58/// In the future, the value type may become generic to an extent (outputs must
59/// satisfy a basic algebra).
60///
61/// Keys will always be byte strings; however, we may grow more conveniences
62/// around dealing with them (such as a serialization/deserialization step,
63/// although it isn't clear where exactly this should live).
64#[derive(Clone)]
65pub struct Map<D>(raw::Fst<D>);
66
67#[cfg(feature = "alloc")]
68impl Map<Vec<u8>> {
69 /// Create a `Map` from an iterator of lexicographically ordered byte
70 /// strings and associated values.
71 ///
72 /// If the iterator does not yield unique keys in lexicographic order, then
73 /// an error is returned.
74 ///
75 /// Note that this is a convenience function to build a map in memory.
76 /// To build a map that streams to an arbitrary `io::Write`, use
77 /// `MapBuilder`.
78 #[cfg(feature = "std")]
79 pub fn from_iter<K, I>(iter: I) -> Result<Map<Vec<u8>>>
80 where
81 K: AsRef<[u8]>,
82 I: IntoIterator<Item = (K, u64)>,
83 {
84 let mut builder = MapBuilder::memory();
85 builder.extend_iter(iter)?;
86 Map::new(builder.into_inner()?)
87 }
88}
89
90impl<D: AsRef<[u8]>> Map<D> {
91 /// Creates a map from its representation as a raw byte sequence.
92 ///
93 /// This accepts anything that can be cheaply converted to a `&[u8]`. The
94 /// caller is responsible for guaranteeing that the given bytes refer to
95 /// a valid FST. While memory safety will not be violated by invalid input,
96 /// a panic could occur while reading the FST at any point.
97 ///
98 /// # Example
99 ///
100 /// ```no_run
101 /// use fst_no_std::Map;
102 ///
103 /// // File written from a build script using MapBuilder.
104 /// # const IGNORE: &str = stringify! {
105 /// static FST: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/map.fst"));
106 /// # };
107 /// # static FST: &[u8] = &[];
108 ///
109 /// let map = Map::new(FST).unwrap();
110 /// ```
111 pub fn new(data: D) -> Result<Map<D>> {
112 raw::Fst::new(data).map(Map)
113 }
114
115 /// Tests the membership of a single key.
116 ///
117 /// # Example
118 ///
119 /// ```rust
120 /// use fst_no_std::Map;
121 ///
122 /// let map = Map::from_iter(vec![("a", 1), ("b", 2), ("c", 3)]).unwrap();
123 ///
124 /// assert_eq!(map.contains_key("b"), true);
125 /// assert_eq!(map.contains_key("z"), false);
126 /// ```
127 pub fn contains_key<K: AsRef<[u8]>>(&self, key: K) -> bool {
128 self.0.contains_key(key)
129 }
130
131 /// Retrieves the value associated with a key.
132 ///
133 /// If the key does not exist, then `None` is returned.
134 ///
135 /// # Example
136 ///
137 /// ```rust
138 /// use fst_no_std::Map;
139 ///
140 /// let map = Map::from_iter(vec![("a", 1), ("b", 2), ("c", 3)]).unwrap();
141 ///
142 /// assert_eq!(map.get("b"), Some(2));
143 /// assert_eq!(map.get("z"), None);
144 /// ```
145 pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Option<u64> {
146 self.0.get(key).map(raw::Output::value)
147 }
148
149 /// Return a lexicographically ordered stream of all key-value pairs in
150 /// this map.
151 ///
152 /// While this is a stream, it does require heap space proportional to the
153 /// longest key in the map.
154 ///
155 /// If the map is memory mapped, then no further heap space is needed.
156 /// Note though that your operating system may fill your page cache
157 /// (which will cause the resident memory usage of the process to go up
158 /// correspondingly).
159 ///
160 /// # Example
161 ///
162 /// Since streams are not iterators, the traditional `for` loop cannot be
163 /// used. `while let` is useful instead:
164 ///
165 /// ```rust
166 /// use fst_no_std::{IntoStreamer, Streamer, Map};
167 ///
168 /// let map = Map::from_iter(vec![("a", 1), ("b", 2), ("c", 3)]).unwrap();
169 /// let mut stream = map.stream();
170 ///
171 /// let mut kvs = vec![];
172 /// while let Some((k, v)) = stream.next() {
173 /// kvs.push((k.to_vec(), v));
174 /// }
175 /// assert_eq!(kvs, vec![
176 /// (b"a".to_vec(), 1),
177 /// (b"b".to_vec(), 2),
178 /// (b"c".to_vec(), 3),
179 /// ]);
180 /// ```
181 #[inline]
182 #[cfg(feature = "alloc")]
183 pub fn stream(&self) -> Stream<'_> {
184 Stream(self.0.stream())
185 }
186
187 /// Return a lexicographically ordered stream of all keys in this map.
188 ///
189 /// Memory requirements are the same as described on `Map::stream`.
190 ///
191 /// # Example
192 ///
193 /// ```rust
194 /// use fst_no_std::{IntoStreamer, Streamer, Map};
195 ///
196 /// let map = Map::from_iter(vec![("a", 1), ("b", 2), ("c", 3)]).unwrap();
197 /// let mut stream = map.keys();
198 ///
199 /// let mut keys = vec![];
200 /// while let Some(k) = stream.next() {
201 /// keys.push(k.to_vec());
202 /// }
203 /// assert_eq!(keys, vec![b"a", b"b", b"c"]);
204 /// ```
205 #[inline]
206 #[cfg(feature = "alloc")]
207 pub fn keys(&self) -> Keys<'_> {
208 Keys(self.0.stream())
209 }
210
211 /// Return a stream of all values in this map ordered lexicographically
212 /// by each value's corresponding key.
213 ///
214 /// Memory requirements are the same as described on `Map::stream`.
215 ///
216 /// # Example
217 ///
218 /// ```rust
219 /// use fst_no_std::{IntoStreamer, Streamer, Map};
220 ///
221 /// let map = Map::from_iter(vec![("a", 1), ("b", 2), ("c", 3)]).unwrap();
222 /// let mut stream = map.values();
223 ///
224 /// let mut values = vec![];
225 /// while let Some(v) = stream.next() {
226 /// values.push(v);
227 /// }
228 /// assert_eq!(values, vec![1, 2, 3]);
229 /// ```
230 #[inline]
231 #[cfg(feature = "alloc")]
232 pub fn values(&self) -> Values<'_> {
233 Values(self.0.stream())
234 }
235
236 /// Return a builder for range queries.
237 ///
238 /// A range query returns a subset of key-value pairs in this map in a
239 /// range given in lexicographic order.
240 ///
241 /// Memory requirements are the same as described on `Map::stream`.
242 /// Notably, only the keys in the range are read; keys outside the range
243 /// are not.
244 ///
245 /// # Example
246 ///
247 /// Returns only the key-value pairs in the range given.
248 ///
249 /// ```rust
250 /// use fst_no_std::{IntoStreamer, Streamer, Map};
251 ///
252 /// let map = Map::from_iter(vec![
253 /// ("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5),
254 /// ]).unwrap();
255 /// let mut stream = map.range().ge("b").lt("e").into_stream();
256 ///
257 /// let mut kvs = vec![];
258 /// while let Some((k, v)) = stream.next() {
259 /// kvs.push((k.to_vec(), v));
260 /// }
261 /// assert_eq!(kvs, vec![
262 /// (b"b".to_vec(), 2),
263 /// (b"c".to_vec(), 3),
264 /// (b"d".to_vec(), 4),
265 /// ]);
266 /// ```
267 #[inline]
268 #[cfg(feature = "alloc")]
269 pub fn range(&self) -> StreamBuilder<'_> {
270 StreamBuilder(self.0.range())
271 }
272
273 /// Executes an automaton on the keys of this map.
274 ///
275 /// Note that this returns a `StreamBuilder`, which can be used to
276 /// add a range query to the search (see the `range` method).
277 ///
278 /// Memory requirements are the same as described on `Map::stream`.
279 ///
280 /// # Example
281 ///
282 /// An implementation of regular expressions for `Automaton` is available
283 /// in the `regex-automata` crate with the `fst1` feature enabled, which
284 /// can be used to search maps.
285 ///
286 /// # Example
287 ///
288 /// An implementation of subsequence search for `Automaton` can be used
289 /// to search maps:
290 ///
291 /// ```rust
292 /// use fst_no_std::automaton::Subsequence;
293 /// use fst_no_std::{IntoStreamer, Streamer, Map};
294 ///
295 /// # fn main() { example().unwrap(); }
296 /// fn example() -> Result<(), Box<dyn std::error::Error>> {
297 /// let map = Map::from_iter(vec![
298 /// ("a foo bar", 1),
299 /// ("foo", 2),
300 /// ("foo1", 3),
301 /// ("foo2", 4),
302 /// ("foo3", 5),
303 /// ("foobar", 6),
304 /// ]).unwrap();
305 ///
306 /// let matcher = Subsequence::new("for");
307 /// let mut stream = map.search(&matcher).into_stream();
308 ///
309 /// let mut kvs = vec![];
310 /// while let Some((k, v)) = stream.next() {
311 /// kvs.push((String::from_utf8(k.to_vec())?, v));
312 /// }
313 /// assert_eq!(kvs, vec![
314 /// ("a foo bar".to_string(), 1), ("foobar".to_string(), 6),
315 /// ]);
316 ///
317 /// Ok(())
318 /// }
319 /// ```
320 #[cfg(feature = "alloc")]
321 pub fn search<A: Automaton>(&self, aut: A) -> StreamBuilder<'_, A> {
322 StreamBuilder(self.0.search(aut))
323 }
324
325 /// Executes an automaton on the keys of this map and yields matching
326 /// keys along with the corresponding matching states in the given
327 /// automaton.
328 ///
329 /// Note that this returns a `StreamWithStateBuilder`, which can be used to
330 /// add a range query to the search (see the `range` method).
331 ///
332 /// Memory requirements are the same as described on `Map::stream`.
333 ///
334 #[cfg_attr(
335 feature = "levenshtein",
336 doc = r##"
337# Example
338
339An implementation of fuzzy search using Levenshtein automata can be used
340to search maps:
341
342```rust
343use fst_no_std::automaton::Levenshtein;
344use fst_no_std::{IntoStreamer, Streamer, Map};
345
346# fn main() { example().unwrap(); }
347fn example() -> Result<(), Box<dyn std::error::Error>> {
348 let map = Map::from_iter(vec![
349 ("foo", 1),
350 ("foob", 2),
351 ("foobar", 3),
352 ("fozb", 4),
353 ]).unwrap();
354
355 let query = Levenshtein::new("foo", 2)?;
356 let mut stream = map.search_with_state(&query).into_stream();
357
358 let mut kvs = vec![];
359 while let Some((k, v, s)) = stream.next() {
360 kvs.push((String::from_utf8(k.to_vec())?, v, s));
361 }
362 // Currently, there isn't much interesting that you can do with the states.
363 assert_eq!(kvs, vec![
364 ("foo".to_string(), 1, Some(183)),
365 ("foob".to_string(), 2, Some(123)),
366 ("fozb".to_string(), 4, Some(83)),
367 ]);
368
369 Ok(())
370}
371```
372"##
373 )]
374 #[cfg(feature = "alloc")]
375 pub fn search_with_state<A: Automaton>(
376 &self,
377 aut: A,
378 ) -> StreamWithStateBuilder<'_, A> {
379 StreamWithStateBuilder(self.0.search_with_state(aut))
380 }
381
382 /// Returns the number of elements in this map.
383 #[inline]
384 pub fn len(&self) -> usize {
385 self.0.len()
386 }
387
388 /// Returns true if and only if this map is empty.
389 #[inline]
390 pub fn is_empty(&self) -> bool {
391 self.0.is_empty()
392 }
393
394 /// Creates a new map operation with this map added to it.
395 ///
396 /// The `OpBuilder` type can be used to add additional map streams
397 /// and perform set operations like union, intersection, difference and
398 /// symmetric difference on the keys of the map. These set operations also
399 /// allow one to specify how conflicting values are merged in the stream.
400 ///
401 /// # Example
402 ///
403 /// This example demonstrates a union on multiple map streams. Notice that
404 /// the stream returned from the union is not a sequence of key-value
405 /// pairs, but rather a sequence of keys associated with one or more
406 /// values. Namely, a key is associated with each value associated with
407 /// that same key in the all of the streams.
408 ///
409 /// ```rust
410 /// use fst_no_std::{Streamer, Map};
411 /// use fst_no_std::map::IndexedValue;
412 ///
413 /// let map1 = Map::from_iter(vec![
414 /// ("a", 1), ("b", 2), ("c", 3),
415 /// ]).unwrap();
416 /// let map2 = Map::from_iter(vec![
417 /// ("a", 10), ("y", 11), ("z", 12),
418 /// ]).unwrap();
419 ///
420 /// let mut union = map1.op().add(&map2).union();
421 ///
422 /// let mut kvs = vec![];
423 /// while let Some((k, vs)) = union.next() {
424 /// kvs.push((k.to_vec(), vs.to_vec()));
425 /// }
426 /// assert_eq!(kvs, vec![
427 /// (b"a".to_vec(), vec![
428 /// IndexedValue { index: 0, value: 1 },
429 /// IndexedValue { index: 1, value: 10 },
430 /// ]),
431 /// (b"b".to_vec(), vec![IndexedValue { index: 0, value: 2 }]),
432 /// (b"c".to_vec(), vec![IndexedValue { index: 0, value: 3 }]),
433 /// (b"y".to_vec(), vec![IndexedValue { index: 1, value: 11 }]),
434 /// (b"z".to_vec(), vec![IndexedValue { index: 1, value: 12 }]),
435 /// ]);
436 /// ```
437 #[inline]
438 #[cfg(feature = "alloc")]
439 pub fn op(&self) -> OpBuilder<'_> {
440 OpBuilder::new().add(self)
441 }
442
443 /// Returns a reference to the underlying raw finite state transducer.
444 #[inline]
445 pub fn as_fst(&self) -> &raw::Fst<D> {
446 &self.0
447 }
448
449 /// Returns the underlying raw finite state transducer.
450 #[inline]
451 pub fn into_fst(self) -> raw::Fst<D> {
452 self.0
453 }
454
455 /// Maps the underlying data of the fst Map to another data type.
456 ///
457 /// # Example
458 ///
459 /// This example shows that you can map an fst Map based on a `Vec<u8>`
460 /// into an fst Map based on a `Cow<[u8]>`, it can also work with a
461 /// reference counted type (e.g. `Arc`, `Rc`).
462 ///
463 /// ```
464 /// use std::borrow::Cow;
465 ///
466 /// use fst_no_std::Map;
467 ///
468 /// let map: Map<Vec<u8>> = Map::from_iter(
469 /// [("hello", 12), ("world", 42)].iter().cloned(),
470 /// ).unwrap();
471 ///
472 /// let map_on_cow: Map<Cow<[u8]>> = map.map_data(Cow::Owned).unwrap();
473 /// ```
474 #[inline]
475 pub fn map_data<F, T>(self, f: F) -> Result<Map<T>>
476 where
477 F: FnMut(D) -> T,
478 T: AsRef<[u8]>,
479 {
480 self.into_fst().map_data(f).map(Map::from)
481 }
482}
483
484#[cfg(feature = "std")]
485impl Default for Map<Vec<u8>> {
486 #[inline]
487 fn default() -> Map<Vec<u8>> {
488 Map::from_iter(iter::empty::<(&[u8], u64)>()).unwrap()
489 }
490}
491
492#[cfg(feature = "alloc")]
493impl<D: AsRef<[u8]>> fmt::Debug for Map<D> {
494 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
495 write!(f, "Map([")?;
496 let mut stream = self.stream();
497 let mut first = true;
498 while let Some((k, v)) = stream.next() {
499 if !first {
500 write!(f, ", ")?;
501 }
502 first = false;
503 write!(f, "({}, {})", String::from_utf8_lossy(k), v)?;
504 }
505 write!(f, "])")
506 }
507}
508
509// Construct a map from an Fst object.
510impl<D: AsRef<[u8]>> From<raw::Fst<D>> for Map<D> {
511 #[inline]
512 fn from(fst: raw::Fst<D>) -> Map<D> {
513 Map(fst)
514 }
515}
516
517/// Returns the underlying finite state transducer.
518impl<D: AsRef<[u8]>> AsRef<raw::Fst<D>> for Map<D> {
519 #[inline]
520 fn as_ref(&self) -> &raw::Fst<D> {
521 &self.0
522 }
523}
524
525#[cfg(feature = "alloc")]
526impl<'m, 'a, D: AsRef<[u8]>> IntoStreamer<'a> for &'m Map<D> {
527 type Item = (&'a [u8], u64);
528 type Into = Stream<'m>;
529
530 #[inline]
531 fn into_stream(self) -> Stream<'m> {
532 Stream(self.0.stream())
533 }
534}
535
536/// A builder for creating a map.
537///
538/// This is not your average everyday builder. It has two important qualities
539/// that make it a bit unique from what you might expect:
540///
541/// 1. All keys must be added in lexicographic order. Adding a key out of order
542/// will result in an error. Additionally, adding a duplicate key will also
543/// result in an error. That is, once a key is associated with a value,
544/// that association can never be modified or deleted.
545/// 2. The representation of a map is streamed to *any* `io::Write` as it is
546/// built. For an in memory representation, this can be a `Vec<u8>`.
547///
548/// Point (2) is especially important because it means that a map can be
549/// constructed *without storing the entire map in memory*. Namely, since it
550/// works with any `io::Write`, it can be streamed directly to a file.
551///
552/// With that said, the builder does use memory, but **memory usage is bounded
553/// to a constant size**. The amount of memory used trades off with the
554/// compression ratio. Currently, the implementation hard codes this trade off
555/// which can result in about 5-20MB of heap usage during construction. (N.B.
556/// Guaranteeing a maximal compression ratio requires memory proportional to
557/// the size of the map, which defeats some of the benefit of streaming
558/// it to disk. In practice, a small bounded amount of memory achieves
559/// close-to-minimal compression ratios.)
560///
561/// The algorithmic complexity of map construction is `O(n)` where `n` is the
562/// number of elements added to the map.
563///
564/// # Example: build in memory
565///
566/// This shows how to use the builder to construct a map in memory. Note that
567/// `Map::from_iter` provides a convenience function that achieves this same
568/// goal without needing to explicitly use `MapBuilder`.
569///
570/// ```rust
571/// use fst_no_std::{IntoStreamer, Streamer, Map, MapBuilder};
572///
573/// let mut build = MapBuilder::memory();
574/// build.insert("bruce", 1).unwrap();
575/// build.insert("clarence", 2).unwrap();
576/// build.insert("stevie", 3).unwrap();
577///
578/// // You could also call `finish()` here, but since we're building the map in
579/// // memory, there would be no way to get the `Vec<u8>` back.
580/// let bytes = build.into_inner().unwrap();
581///
582/// // At this point, the map has been constructed, but here's how to read it.
583/// let map = Map::new(bytes).unwrap();
584/// let mut stream = map.into_stream();
585/// let mut kvs = vec![];
586/// while let Some((k, v)) = stream.next() {
587/// kvs.push((k.to_vec(), v));
588/// }
589/// assert_eq!(kvs, vec![
590/// (b"bruce".to_vec(), 1),
591/// (b"clarence".to_vec(), 2),
592/// (b"stevie".to_vec(), 3),
593/// ]);
594/// ```
595///
596/// # Example: stream to file
597///
598/// This shows how to do stream construction of a map to a file.
599///
600/// ```rust,no_run
601/// use std::fs::File;
602/// use std::io;
603///
604/// use fst_no_std::{IntoStreamer, Streamer, Map, MapBuilder};
605///
606/// let mut wtr = io::BufWriter::new(File::create("map.fst").unwrap());
607/// let mut build = MapBuilder::new(wtr).unwrap();
608/// build.insert("bruce", 1).unwrap();
609/// build.insert("clarence", 2).unwrap();
610/// build.insert("stevie", 3).unwrap();
611///
612/// // If you want the writer back, then call `into_inner`. Otherwise, this
613/// // will finish construction and call `flush`.
614/// build.finish().unwrap();
615///
616/// // At this point, the map has been constructed, but here's how to read it.
617/// // NOTE: Normally, one would memory map a file instead of reading its
618/// // entire contents on to the heap.
619/// let map = Map::new(std::fs::read("map.fst").unwrap()).unwrap();
620/// let mut stream = map.into_stream();
621/// let mut kvs = vec![];
622/// while let Some((k, v)) = stream.next() {
623/// kvs.push((k.to_vec(), v));
624/// }
625/// assert_eq!(kvs, vec![
626/// (b"bruce".to_vec(), 1),
627/// (b"clarence".to_vec(), 2),
628/// (b"stevie".to_vec(), 3),
629/// ]);
630/// ```
631#[cfg(feature = "std")]
632pub struct MapBuilder<W>(raw::Builder<W>);
633
634#[cfg(feature = "std")]
635impl MapBuilder<Vec<u8>> {
636 /// Create a builder that builds a map in memory.
637 #[inline]
638 #[must_use]
639 pub fn memory() -> MapBuilder<Vec<u8>> {
640 MapBuilder(raw::Builder::memory())
641 }
642
643 /// Finishes the construction of the map and returns it.
644 #[inline]
645 #[must_use]
646 pub fn into_map(self) -> Map<Vec<u8>> {
647 Map(self.0.into_fst())
648 }
649}
650
651#[cfg(feature = "std")]
652impl<W: io::Write> MapBuilder<W> {
653 /// Create a builder that builds a map by writing it to `wtr` in a
654 /// streaming fashion.
655 pub fn new(wtr: W) -> Result<MapBuilder<W>> {
656 raw::Builder::new_type(wtr, 0).map(MapBuilder)
657 }
658
659 /// Insert a new key-value pair into the map.
660 ///
661 /// Keys must be convertible to byte strings. Values must be a `u64`, which
662 /// is a restriction of the current implementation of finite state
663 /// transducers. (Values may one day be expanded to other types.)
664 ///
665 /// If a key is inserted that is less than or equal to any previous key
666 /// added, then an error is returned. Similarly, if there was a problem
667 /// writing to the underlying writer, an error is returned.
668 pub fn insert<K: AsRef<[u8]>>(&mut self, key: K, val: u64) -> Result<()> {
669 self.0.insert(key, val)
670 }
671
672 /// Calls insert on each item in the iterator.
673 ///
674 /// If an error occurred while adding an element, processing is stopped
675 /// and the error is returned.
676 ///
677 /// If a key is inserted that is less than or equal to any previous key
678 /// added, then an error is returned. Similarly, if there was a problem
679 /// writing to the underlying writer, an error is returned.
680 pub fn extend_iter<K, I>(&mut self, iter: I) -> Result<()>
681 where
682 K: AsRef<[u8]>,
683 I: IntoIterator<Item = (K, u64)>,
684 {
685 self.0.extend_iter(
686 iter.into_iter().map(|(k, v)| (k, raw::Output::new(v))),
687 )
688 }
689
690 /// Calls insert on each item in the stream.
691 ///
692 /// Note that unlike `extend_iter`, this is not generic on the items in
693 /// the stream.
694 ///
695 /// If a key is inserted that is less than or equal to any previous key
696 /// added, then an error is returned. Similarly, if there was a problem
697 /// writing to the underlying writer, an error is returned.
698 pub fn extend_stream<'f, I, S>(&mut self, stream: I) -> Result<()>
699 where
700 I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
701 S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
702 {
703 self.0.extend_stream(StreamOutput(stream.into_stream()))
704 }
705
706 /// Finishes the construction of the map and flushes the underlying
707 /// writer. After completion, the data written to `W` may be read using
708 /// one of `Map`'s constructor methods.
709 pub fn finish(self) -> Result<()> {
710 self.0.finish()
711 }
712
713 /// Just like `finish`, except it returns the underlying writer after
714 /// flushing it.
715 pub fn into_inner(self) -> Result<W> {
716 self.0.into_inner()
717 }
718
719 /// Gets a reference to the underlying writer.
720 pub fn get_ref(&self) -> &W {
721 self.0.get_ref()
722 }
723
724 /// Returns the number of bytes written to the underlying writer
725 pub fn bytes_written(&self) -> u64 {
726 self.0.bytes_written()
727 }
728}
729
730/// A lexicographically ordered stream of key-value pairs from a map.
731///
732/// The `A` type parameter corresponds to an optional automaton to filter
733/// the stream. By default, no filtering is done.
734///
735/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
736#[cfg(feature = "alloc")]
737pub struct Stream<'m, A = AlwaysMatch>(raw::Stream<'m, A>)
738where
739 A: Automaton;
740
741#[cfg(feature = "alloc")]
742impl<'a, 'm, A: Automaton> Streamer<'a> for Stream<'m, A> {
743 type Item = (&'a [u8], u64);
744
745 fn next(&'a mut self) -> Option<(&'a [u8], u64)> {
746 self.0.next().map(|(key, out)| (key, out.value()))
747 }
748}
749
750#[cfg(feature = "alloc")]
751impl<'m, A: Automaton> Stream<'m, A> {
752 /// Convert this stream into a vector of byte strings and outputs.
753 ///
754 /// Note that this creates a new allocation for every key in the stream.
755 pub fn into_byte_vec(self) -> Vec<(Vec<u8>, u64)> {
756 self.0.into_byte_vec()
757 }
758
759 /// Convert this stream into a vector of Unicode strings and outputs.
760 ///
761 /// If any key is not valid UTF-8, then iteration on the stream is stopped
762 /// and a UTF-8 decoding error is returned.
763 ///
764 /// Note that this creates a new allocation for every key in the stream.
765 pub fn into_str_vec(self) -> Result<Vec<(String, u64)>> {
766 self.0.into_str_vec()
767 }
768
769 /// Convert this stream into a vector of byte strings.
770 ///
771 /// Note that this creates a new allocation for every key in the stream.
772 pub fn into_byte_keys(self) -> Vec<Vec<u8>> {
773 self.0.into_byte_keys()
774 }
775
776 /// Convert this stream into a vector of Unicode strings.
777 ///
778 /// If any key is not valid UTF-8, then iteration on the stream is stopped
779 /// and a UTF-8 decoding error is returned.
780 ///
781 /// Note that this creates a new allocation for every key in the stream.
782 pub fn into_str_keys(self) -> Result<Vec<String>> {
783 self.0.into_str_keys()
784 }
785
786 /// Convert this stream into a vector of outputs.
787 pub fn into_values(self) -> Vec<u64> {
788 self.0.into_values()
789 }
790}
791
792/// A lexicographically ordered stream of key-value-state triples from a map
793/// and an automaton.
794///
795/// The key-values are from the map while the states are from the automaton.
796///
797/// The `A` type parameter corresponds to an optional automaton to filter
798/// the stream. By default, no filtering is done.
799///
800/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
801#[cfg(feature = "alloc")]
802pub struct StreamWithState<'m, A = AlwaysMatch>(raw::StreamWithState<'m, A>)
803where
804 A: Automaton;
805
806#[cfg(feature = "alloc")]
807impl<'a, 'm, A: 'a + Automaton> Streamer<'a> for StreamWithState<'m, A>
808where
809 A::State: Clone,
810{
811 type Item = (&'a [u8], u64, A::State);
812
813 fn next(&'a mut self) -> Option<(&'a [u8], u64, A::State)> {
814 self.0.next().map(|(key, out, state)| (key, out.value(), state))
815 }
816}
817
818/// A lexicographically ordered stream of keys from a map.
819///
820/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
821#[cfg(feature = "alloc")]
822pub struct Keys<'m>(raw::Stream<'m>);
823
824#[cfg(feature = "alloc")]
825impl<'a, 'm> Streamer<'a> for Keys<'m> {
826 type Item = &'a [u8];
827
828 #[inline]
829 fn next(&'a mut self) -> Option<&'a [u8]> {
830 self.0.next().map(|(key, _)| key)
831 }
832}
833
834/// A stream of values from a map, lexicographically ordered by each value's
835/// corresponding key.
836///
837/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
838#[cfg(feature = "alloc")]
839pub struct Values<'m>(raw::Stream<'m>);
840
841#[cfg(feature = "alloc")]
842impl<'a, 'm> Streamer<'a> for Values<'m> {
843 type Item = u64;
844
845 #[inline]
846 fn next(&'a mut self) -> Option<u64> {
847 self.0.next().map(|(_, out)| out.value())
848 }
849}
850
851/// A builder for constructing range queries on streams.
852///
853/// Once all bounds are set, one should call `into_stream` to get a
854/// `Stream`.
855///
856/// Bounds are not additive. That is, if `ge` is called twice on the same
857/// builder, then the second setting wins.
858///
859/// The `A` type parameter corresponds to an optional automaton to filter
860/// the stream. By default, no filtering is done.
861///
862/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
863#[cfg(feature = "alloc")]
864pub struct StreamBuilder<'m, A = AlwaysMatch>(raw::StreamBuilder<'m, A>);
865
866#[cfg(feature = "alloc")]
867impl<'m, A: Automaton> StreamBuilder<'m, A> {
868 /// Specify a greater-than-or-equal-to bound.
869 pub fn ge<T: AsRef<[u8]>>(self, bound: T) -> StreamBuilder<'m, A> {
870 StreamBuilder(self.0.ge(bound))
871 }
872
873 /// Specify a greater-than bound.
874 pub fn gt<T: AsRef<[u8]>>(self, bound: T) -> StreamBuilder<'m, A> {
875 StreamBuilder(self.0.gt(bound))
876 }
877
878 /// Specify a less-than-or-equal-to bound.
879 pub fn le<T: AsRef<[u8]>>(self, bound: T) -> StreamBuilder<'m, A> {
880 StreamBuilder(self.0.le(bound))
881 }
882
883 /// Specify a less-than bound.
884 pub fn lt<T: AsRef<[u8]>>(self, bound: T) -> StreamBuilder<'m, A> {
885 StreamBuilder(self.0.lt(bound))
886 }
887}
888
889#[cfg(feature = "alloc")]
890
891impl<'m, 'a, A: Automaton> IntoStreamer<'a> for StreamBuilder<'m, A> {
892 type Item = (&'a [u8], u64);
893 type Into = Stream<'m, A>;
894
895 fn into_stream(self) -> Stream<'m, A> {
896 Stream(self.0.into_stream())
897 }
898}
899
900/// A builder for constructing range queries on streams that include automaton
901/// states.
902///
903/// In general, one should use `StreamBuilder` unless you have a specific need
904/// for accessing the states of the underlying automaton that is being used to
905/// filter this stream.
906///
907/// Once all bounds are set, one should call `into_stream` to get a
908/// `Stream`.
909///
910/// Bounds are not additive. That is, if `ge` is called twice on the same
911/// builder, then the second setting wins.
912///
913/// The `A` type parameter corresponds to an optional automaton to filter
914/// the stream. By default, no filtering is done.
915///
916/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
917#[cfg(feature = "alloc")]
918pub struct StreamWithStateBuilder<'m, A = AlwaysMatch>(
919 raw::StreamWithStateBuilder<'m, A>,
920);
921
922#[cfg(feature = "alloc")]
923impl<'m, A: Automaton> StreamWithStateBuilder<'m, A> {
924 /// Specify a greater-than-or-equal-to bound.
925 pub fn ge<T: AsRef<[u8]>>(
926 self,
927 bound: T,
928 ) -> StreamWithStateBuilder<'m, A> {
929 StreamWithStateBuilder(self.0.ge(bound))
930 }
931
932 /// Specify a greater-than bound.
933 pub fn gt<T: AsRef<[u8]>>(
934 self,
935 bound: T,
936 ) -> StreamWithStateBuilder<'m, A> {
937 StreamWithStateBuilder(self.0.gt(bound))
938 }
939
940 /// Specify a less-than-or-equal-to bound.
941 pub fn le<T: AsRef<[u8]>>(
942 self,
943 bound: T,
944 ) -> StreamWithStateBuilder<'m, A> {
945 StreamWithStateBuilder(self.0.le(bound))
946 }
947
948 /// Specify a less-than bound.
949 pub fn lt<T: AsRef<[u8]>>(
950 self,
951 bound: T,
952 ) -> StreamWithStateBuilder<'m, A> {
953 StreamWithStateBuilder(self.0.lt(bound))
954 }
955}
956
957#[cfg(feature = "alloc")]
958impl<'m, 'a, A: 'a + Automaton> IntoStreamer<'a>
959 for StreamWithStateBuilder<'m, A>
960where
961 A::State: Clone,
962{
963 type Item = (&'a [u8], u64, A::State);
964 type Into = StreamWithState<'m, A>;
965
966 fn into_stream(self) -> StreamWithState<'m, A> {
967 StreamWithState(self.0.into_stream())
968 }
969}
970
971/// A builder for collecting map streams on which to perform set operations
972/// on the keys of maps.
973///
974/// Set operations include intersection, union, difference and symmetric
975/// difference. The result of each set operation is itself a stream that emits
976/// pairs of keys and a sequence of each occurrence of that key in the
977/// participating streams. This information allows one to perform set
978/// operations on maps and customize how conflicting output values are handled.
979///
980/// All set operations work efficiently on an arbitrary number of
981/// streams with memory proportional to the number of streams.
982///
983/// The algorithmic complexity of all set operations is `O(n1 + n2 + n3 + ...)`
984/// where `n1, n2, n3, ...` correspond to the number of elements in each
985/// stream.
986///
987/// The `'m` lifetime parameter refers to the lifetime of the underlying set.
988#[cfg(feature = "alloc")]
989pub struct OpBuilder<'m>(raw::OpBuilder<'m>);
990
991#[cfg(feature = "alloc")]
992impl<'m> Default for OpBuilder<'m> {
993 fn default() -> Self {
994 Self::new()
995 }
996}
997
998#[cfg(feature = "alloc")]
999impl<'m> OpBuilder<'m> {
1000 /// Create a new set operation builder.
1001 #[inline]
1002 #[must_use]
1003 pub fn new() -> OpBuilder<'m> {
1004 OpBuilder(raw::OpBuilder::new())
1005 }
1006
1007 /// Add a stream to this set operation.
1008 ///
1009 /// This is useful for a chaining style pattern, e.g.,
1010 /// `builder.add(stream1).add(stream2).union()`.
1011 ///
1012 /// The stream must emit a lexicographically ordered sequence of key-value
1013 /// pairs.
1014 pub fn add<I, S>(mut self, streamable: I) -> OpBuilder<'m>
1015 where
1016 I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
1017 S: 'm + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
1018 {
1019 self.push(streamable);
1020 self
1021 }
1022
1023 /// Add a stream to this set operation.
1024 ///
1025 /// The stream must emit a lexicographically ordered sequence of key-value
1026 /// pairs.
1027 pub fn push<I, S>(&mut self, streamable: I)
1028 where
1029 I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
1030 S: 'm + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
1031 {
1032 self.0.push(StreamOutput(streamable.into_stream()));
1033 }
1034
1035 /// Performs a union operation on all streams that have been added.
1036 ///
1037 /// Note that this returns a stream of `(&[u8], &[IndexedValue])`. The
1038 /// first element of the tuple is the byte string key. The second element
1039 /// of the tuple is a list of all occurrences of that key in participating
1040 /// streams. The `IndexedValue` contains an index and the value associated
1041 /// with that key in that stream. The index uniquely identifies each
1042 /// stream, which is an integer that is auto-incremented when a stream
1043 /// is added to this operation (starting at `0`).
1044 ///
1045 /// # Example
1046 ///
1047 /// ```rust
1048 /// use fst_no_std::{IntoStreamer, Streamer, Map};
1049 /// use fst_no_std::map::IndexedValue;
1050 ///
1051 /// let map1 = Map::from_iter(vec![
1052 /// ("a", 1), ("b", 2), ("c", 3),
1053 /// ]).unwrap();
1054 /// let map2 = Map::from_iter(vec![
1055 /// ("a", 11), ("y", 12), ("z", 13),
1056 /// ]).unwrap();
1057 ///
1058 /// let mut union = map1.op().add(&map2).union();
1059 ///
1060 /// let mut kvs = vec![];
1061 /// while let Some((k, vs)) = union.next() {
1062 /// kvs.push((k.to_vec(), vs.to_vec()));
1063 /// }
1064 /// assert_eq!(kvs, vec![
1065 /// (b"a".to_vec(), vec![
1066 /// IndexedValue { index: 0, value: 1 },
1067 /// IndexedValue { index: 1, value: 11 },
1068 /// ]),
1069 /// (b"b".to_vec(), vec![IndexedValue { index: 0, value: 2 }]),
1070 /// (b"c".to_vec(), vec![IndexedValue { index: 0, value: 3 }]),
1071 /// (b"y".to_vec(), vec![IndexedValue { index: 1, value: 12 }]),
1072 /// (b"z".to_vec(), vec![IndexedValue { index: 1, value: 13 }]),
1073 /// ]);
1074 /// ```
1075 #[inline]
1076 #[must_use]
1077 pub fn union(self) -> Union<'m> {
1078 Union(self.0.union())
1079 }
1080
1081 /// Performs an intersection operation on all streams that have been added.
1082 ///
1083 /// Note that this returns a stream of `(&[u8], &[IndexedValue])`. The
1084 /// first element of the tuple is the byte string key. The second element
1085 /// of the tuple is a list of all occurrences of that key in participating
1086 /// streams. The `IndexedValue` contains an index and the value associated
1087 /// with that key in that stream. The index uniquely identifies each
1088 /// stream, which is an integer that is auto-incremented when a stream
1089 /// is added to this operation (starting at `0`).
1090 ///
1091 /// # Example
1092 ///
1093 /// ```rust
1094 /// use fst_no_std::{IntoStreamer, Streamer, Map};
1095 /// use fst_no_std::map::IndexedValue;
1096 ///
1097 /// let map1 = Map::from_iter(vec![
1098 /// ("a", 1), ("b", 2), ("c", 3),
1099 /// ]).unwrap();
1100 /// let map2 = Map::from_iter(vec![
1101 /// ("a", 11), ("y", 12), ("z", 13),
1102 /// ]).unwrap();
1103 ///
1104 /// let mut intersection = map1.op().add(&map2).intersection();
1105 ///
1106 /// let mut kvs = vec![];
1107 /// while let Some((k, vs)) = intersection.next() {
1108 /// kvs.push((k.to_vec(), vs.to_vec()));
1109 /// }
1110 /// assert_eq!(kvs, vec![
1111 /// (b"a".to_vec(), vec![
1112 /// IndexedValue { index: 0, value: 1 },
1113 /// IndexedValue { index: 1, value: 11 },
1114 /// ]),
1115 /// ]);
1116 /// ```
1117 #[inline]
1118 #[must_use]
1119 pub fn intersection(self) -> Intersection<'m> {
1120 Intersection(self.0.intersection())
1121 }
1122
1123 /// Performs a difference operation with respect to the first stream added.
1124 /// That is, this returns a stream of all elements in the first stream
1125 /// that don't exist in any other stream that has been added.
1126 ///
1127 /// Note that this returns a stream of `(&[u8], &[IndexedValue])`. The
1128 /// first element of the tuple is the byte string key. The second element
1129 /// of the tuple is a list of all occurrences of that key in participating
1130 /// streams. The `IndexedValue` contains an index and the value associated
1131 /// with that key in that stream. The index uniquely identifies each
1132 /// stream, which is an integer that is auto-incremented when a stream
1133 /// is added to this operation (starting at `0`).
1134 ///
1135 /// While the interface is the same for all the operations combining multiple
1136 /// maps, due to the nature of `difference` there's exactly one `IndexValue`
1137 /// for each yielded value.
1138 ///
1139 /// # Example
1140 ///
1141 /// ```rust
1142 /// use fst_no_std::{Streamer, Map};
1143 /// use fst_no_std::map::IndexedValue;
1144 ///
1145 /// let map1 = Map::from_iter(vec![
1146 /// ("a", 1), ("b", 2), ("c", 3),
1147 /// ]).unwrap();
1148 /// let map2 = Map::from_iter(vec![
1149 /// ("a", 11), ("y", 12), ("z", 13),
1150 /// ]).unwrap();
1151 ///
1152 /// let mut difference = map1.op().add(&map2).difference();
1153 ///
1154 /// let mut kvs = vec![];
1155 /// while let Some((k, vs)) = difference.next() {
1156 /// kvs.push((k.to_vec(), vs.to_vec()));
1157 /// }
1158 /// assert_eq!(kvs, vec![
1159 /// (b"b".to_vec(), vec![IndexedValue { index: 0, value: 2 }]),
1160 /// (b"c".to_vec(), vec![IndexedValue { index: 0, value: 3 }]),
1161 /// ]);
1162 /// ```
1163 #[inline]
1164 #[must_use]
1165 pub fn difference(self) -> Difference<'m> {
1166 Difference(self.0.difference())
1167 }
1168
1169 /// Performs a symmetric difference operation on all of the streams that
1170 /// have been added.
1171 ///
1172 /// When there are only two streams, then the keys returned correspond to
1173 /// keys that are in either stream but *not* in both streams.
1174 ///
1175 /// More generally, for any number of streams, keys that occur in an odd
1176 /// number of streams are returned.
1177 ///
1178 /// Note that this returns a stream of `(&[u8], &[IndexedValue])`. The
1179 /// first element of the tuple is the byte string key. The second element
1180 /// of the tuple is a list of all occurrences of that key in participating
1181 /// streams. The `IndexedValue` contains an index and the value associated
1182 /// with that key in that stream. The index uniquely identifies each
1183 /// stream, which is an integer that is auto-incremented when a stream
1184 /// is added to this operation (starting at `0`).
1185 ///
1186 /// # Example
1187 ///
1188 /// ```rust
1189 /// use fst_no_std::{IntoStreamer, Streamer, Map};
1190 /// use fst_no_std::map::IndexedValue;
1191 ///
1192 /// let map1 = Map::from_iter(vec![
1193 /// ("a", 1), ("b", 2), ("c", 3),
1194 /// ]).unwrap();
1195 /// let map2 = Map::from_iter(vec![
1196 /// ("a", 11), ("y", 12), ("z", 13),
1197 /// ]).unwrap();
1198 ///
1199 /// let mut sym_difference = map1.op().add(&map2).symmetric_difference();
1200 ///
1201 /// let mut kvs = vec![];
1202 /// while let Some((k, vs)) = sym_difference.next() {
1203 /// kvs.push((k.to_vec(), vs.to_vec()));
1204 /// }
1205 /// assert_eq!(kvs, vec![
1206 /// (b"b".to_vec(), vec![IndexedValue { index: 0, value: 2 }]),
1207 /// (b"c".to_vec(), vec![IndexedValue { index: 0, value: 3 }]),
1208 /// (b"y".to_vec(), vec![IndexedValue { index: 1, value: 12 }]),
1209 /// (b"z".to_vec(), vec![IndexedValue { index: 1, value: 13 }]),
1210 /// ]);
1211 /// ```
1212 #[inline]
1213 #[must_use]
1214 pub fn symmetric_difference(self) -> SymmetricDifference<'m> {
1215 SymmetricDifference(self.0.symmetric_difference())
1216 }
1217}
1218
1219#[cfg(feature = "alloc")]
1220impl<'f, I, S> Extend<I> for OpBuilder<'f>
1221where
1222 I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
1223 S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
1224{
1225 fn extend<T>(&mut self, it: T)
1226 where
1227 T: IntoIterator<Item = I>,
1228 {
1229 for stream in it {
1230 self.push(stream);
1231 }
1232 }
1233}
1234
1235#[cfg(feature = "alloc")]
1236impl<'f, I, S> FromIterator<I> for OpBuilder<'f>
1237where
1238 I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
1239 S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
1240{
1241 fn from_iter<T>(it: T) -> OpBuilder<'f>
1242 where
1243 T: IntoIterator<Item = I>,
1244 {
1245 let mut op = OpBuilder::new();
1246 op.extend(it);
1247 op
1248 }
1249}
1250
1251/// A stream of set union over multiple map streams in lexicographic order.
1252///
1253/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
1254#[cfg(feature = "alloc")]
1255pub struct Union<'m>(raw::Union<'m>);
1256
1257#[cfg(feature = "alloc")]
1258impl<'a, 'm> Streamer<'a> for Union<'m> {
1259 type Item = (&'a [u8], &'a [IndexedValue]);
1260
1261 #[inline]
1262 fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> {
1263 self.0.next()
1264 }
1265}
1266
1267/// A stream of set intersection over multiple map streams in lexicographic
1268/// order.
1269///
1270/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
1271#[cfg(feature = "alloc")]
1272pub struct Intersection<'m>(raw::Intersection<'m>);
1273
1274#[cfg(feature = "alloc")]
1275impl<'a, 'm> Streamer<'a> for Intersection<'m> {
1276 type Item = (&'a [u8], &'a [IndexedValue]);
1277
1278 #[inline]
1279 fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> {
1280 self.0.next()
1281 }
1282}
1283
1284/// A stream of set difference over multiple map streams in lexicographic
1285/// order.
1286///
1287/// The difference operation is taken with respect to the first stream and the
1288/// rest of the streams. i.e., All elements in the first stream that do not
1289/// appear in any other streams.
1290///
1291/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
1292#[cfg(feature = "alloc")]
1293pub struct Difference<'m>(raw::Difference<'m>);
1294
1295#[cfg(feature = "alloc")]
1296impl<'a, 'm> Streamer<'a> for Difference<'m> {
1297 type Item = (&'a [u8], &'a [IndexedValue]);
1298
1299 #[inline]
1300 fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> {
1301 self.0.next()
1302 }
1303}
1304
1305/// A stream of set symmetric difference over multiple map streams in
1306/// lexicographic order.
1307///
1308/// The `'m` lifetime parameter refers to the lifetime of the underlying map.
1309#[cfg(feature = "alloc")]
1310pub struct SymmetricDifference<'m>(raw::SymmetricDifference<'m>);
1311
1312#[cfg(feature = "alloc")]
1313impl<'a, 'm> Streamer<'a> for SymmetricDifference<'m> {
1314 type Item = (&'a [u8], &'a [IndexedValue]);
1315
1316 #[inline]
1317 fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> {
1318 self.0.next()
1319 }
1320}
1321
1322/// A specialized stream for mapping map streams (`(&[u8], u64)`) to streams
1323/// used by raw fsts (`(&[u8], Output)`).
1324///
1325/// If this were iterators, we could use `iter::Map`, but doing this on streams
1326/// requires HKT, so we need to write out the monomorphization ourselves.
1327struct StreamOutput<S>(S);
1328
1329impl<'a, S> Streamer<'a> for StreamOutput<S>
1330where
1331 S: Streamer<'a, Item = (&'a [u8], u64)>,
1332{
1333 type Item = (&'a [u8], raw::Output);
1334
1335 fn next(&'a mut self) -> Option<(&'a [u8], raw::Output)> {
1336 self.0.next().map(|(k, v)| (k, raw::Output::new(v)))
1337 }
1338}