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}