diff --git a/Cargo.toml b/Cargo.toml index b135a67..f70f108 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ levenshtein = ["utf8-ranges"] utf8-ranges = { version = "1.0.4", optional = true } [dev-dependencies] +doc-comment = "0.3.1" fnv = "1.0.6" memmap = "0.7" quickcheck = { version = "0.9.2", default-features = false } diff --git a/README.md b/README.md index fbf4941..6052082 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,10 @@ Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org). https://docs.rs/fst The -[`fst-regex`](https://docs.rs/fst-regex) -and -[`fst-levenshtein`](https://docs.rs/fst-levenshtein) -crates provide regular expression matching and fuzzy searching on FSTs, -respectively. +[`regex-automata`](https://docs.rs/regex-automata) +crate provides implementations of the `fst::Automata` trait when its +`transducer` feature is enabled. This permits using DFAs compiled by +`regex-automata` to search finite state transducers produced by this crate. ### Installation @@ -36,27 +35,21 @@ Simply add a corresponding entry to your `Cargo.toml` dependency list: ```toml,ignore [dependencies] -fst = "0.3" +fst = "0.4" ``` ### Example This example demonstrates building a set in memory and executing a fuzzy query -against it. You'll need `fst = "0.3"` and `fst-levenshtein = "0.2"` in your -`Cargo.toml`. +against it. You'll need `fst = "0.4"` with the `levenshtein` feature enabled in +your `Cargo.toml`. ```rust -extern crate fst; -extern crate fst_levenshtein; - -use std::error::Error; -use std::process; - use fst::{IntoStreamer, Set}; -use fst_levenshtein::Levenshtein; +use fst::automaton::Levenshtein; -fn try_main() -> Result<(), Box> { +fn main() -> Result<(), Box> { // A convenient way to create sets in memory. let keys = vec!["fa", "fo", "fob", "focus", "foo", "food", "foul"]; let set = Set::from_iter(keys)?; @@ -71,13 +64,13 @@ fn try_main() -> Result<(), Box> { assert_eq!(keys, vec!["fo", "fob", "foo", "food"]); Ok(()) } - -fn main() { - if let Err(err) = try_main() { - eprintln!("{}", err); - process::exit(1); - } -} ``` Check out the documentation for a lot more examples! + + +### Cargo features + +* `levenshtein` - **Disabled** by default. This adds the `Levenshtein` + automaton to the `automaton` sub-module. This includes an additional + dependency on `utf8-ranges`. diff --git a/fst-bin/src/merge.rs b/fst-bin/src/merge.rs index 8e5a692..fe880ff 100644 --- a/fst-bin/src/merge.rs +++ b/fst-bin/src/merge.rs @@ -32,7 +32,7 @@ impl Merger where I: Iterator> + Send + 'static, { - pub fn new(it: T, output: P) -> Self + pub fn new(it: T, output: P) -> Merger where P: AsRef, T: IntoIterator, @@ -49,7 +49,7 @@ where } } - pub fn value_merger(mut self, f: F) -> Self + pub fn value_merger(mut self, f: F) -> Merger where F: Fn(u64, u64) -> u64 + Send + Sync + 'static, { @@ -57,27 +57,27 @@ where self } - pub fn fd_limit(mut self, fd_limit: u32) -> Self { + pub fn fd_limit(mut self, fd_limit: u32) -> Merger { self.fd_limit = fd_limit; self } - pub fn batch_size(mut self, batch_size: u32) -> Self { + pub fn batch_size(mut self, batch_size: u32) -> Merger { self.batch_size = batch_size; self } - pub fn threads(mut self, threads: u32) -> Self { + pub fn threads(mut self, threads: u32) -> Merger { self.threads = threads; self } - pub fn tmp_dir>(mut self, path: P) -> Self { + pub fn tmp_dir>(mut self, path: P) -> Merger { self.tmp_dir = path.as_ref().to_path_buf(); self } - pub fn keep_tmp_dir(mut self, yes: bool) -> Self { + pub fn keep_tmp_dir(mut self, yes: bool) -> Merger { self.keep_tmp_dir = yes; self } @@ -117,7 +117,7 @@ where for (i, union_batch) in batches.into_iter().enumerate() { sorters.create_fst(UnionBatch { tmp_dir: tmp_dir_path.clone(), - gen: gen, + gen, index: i, fsts: union_batch?, value_merger: self.value_merger.clone(), @@ -178,7 +178,7 @@ struct Sorters { } impl Sorters { - fn new(threads: u32) -> Self { + fn new(threads: u32) -> Sorters { let (bsend, brecv) = chan::bounded::(0); let (rsend, rrecv) = chan::bounded(0); for _ in 0..threads { diff --git a/fst-bin/src/util.rs b/fst-bin/src/util.rs index a166529..dfe4970 100644 --- a/fst-bin/src/util.rs +++ b/fst-bin/src/util.rs @@ -103,14 +103,14 @@ type Lines = bstr::io::ByteLines< impl ConcatLines { pub fn new(mut inputs: Vec) -> ConcatLines { inputs.reverse(); // treat it as a stack - ConcatLines { inputs: inputs, cur: None } + ConcatLines { inputs, cur: None } } } impl Iterator for ConcatLines { type Item = io::Result; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option> { loop { if self.cur.is_none() { match self.inputs.pop() { @@ -143,7 +143,7 @@ type Rows = csv::DeserializeRecordsIntoIter; impl ConcatCsv { pub fn new(mut inputs: Vec) -> ConcatCsv { inputs.reverse(); // treat it as a stack - ConcatCsv { inputs: inputs, cur: None } + ConcatCsv { inputs, cur: None } } fn read_row(&mut self) -> Option> { @@ -162,7 +162,7 @@ impl ConcatCsv { impl Iterator for ConcatCsv { type Item = Result<(BString, u64), Error>; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option> { loop { if self.cur.is_none() { match self.inputs.pop() { diff --git a/fst-levenshtein/src/lib.rs b/fst-levenshtein/src/lib.rs index b8e9f84..e5c65f9 100644 --- a/fst-levenshtein/src/lib.rs +++ b/fst-levenshtein/src/lib.rs @@ -1,6 +1,3 @@ - - - use std::cmp; use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; @@ -90,13 +87,13 @@ impl Levenshtein { /// A `Levenshtein` value satisfies the `Automaton` trait, which means it /// can be used with the `search` method of any finite state transducer. #[inline] - pub fn new(query: &str, distance: u32) -> Result { + pub fn new(query: &str, distance: u32) -> Result { let lev = DynamicLevenshtein { query: query.to_owned(), dist: distance as usize, }; let dfa = DfaBuilder::new(lev.clone()).build()?; - Ok(Levenshtein { prog: lev, dfa: dfa }) + Ok(Levenshtein { prog: lev, dfa }) } } @@ -197,10 +194,10 @@ struct DfaBuilder { } impl DfaBuilder { - fn new(lev: DynamicLevenshtein) -> Self { + fn new(lev: DynamicLevenshtein) -> DfaBuilder { DfaBuilder { dfa: Dfa { states: Vec::with_capacity(16) }, - lev: lev, + lev, cache: HashMap::with_capacity(1024), } } @@ -251,9 +248,7 @@ impl DfaBuilder { Entry::Occupied(v) => (*v.get(), true), Entry::Vacant(v) => { let is_match = self.lev.is_match(lev_state); - self.dfa - .states - .push(State { next: [None; 256], is_match: is_match }); + self.dfa.states.push(State { next: [None; 256], is_match }); (*v.insert(self.dfa.states.len() - 1), false) } }) @@ -314,7 +309,7 @@ impl DfaBuilder { } fn new_state(&mut self, is_match: bool) -> usize { - self.dfa.states.push(State { next: [None; 256], is_match: is_match }); + self.dfa.states.push(State { next: [None; 256], is_match }); self.dfa.states.len() - 1 } } diff --git a/src/automaton/levenshtein.rs b/src/automaton/levenshtein.rs index af15f02..9db9748 100644 --- a/src/automaton/levenshtein.rs +++ b/src/automaton/levenshtein.rs @@ -109,7 +109,10 @@ impl Levenshtein { /// A `Levenshtein` value satisfies the `Automaton` trait, which means it /// can be used with the `search` method of any finite state transducer. #[inline] - pub fn new(query: &str, distance: u32) -> Result { + pub fn new( + query: &str, + distance: u32, + ) -> Result { let lev = DynamicLevenshtein { query: query.to_owned(), dist: distance as usize, @@ -216,7 +219,7 @@ struct DfaBuilder { } impl DfaBuilder { - fn new(lev: DynamicLevenshtein) -> Self { + fn new(lev: DynamicLevenshtein) -> DfaBuilder { DfaBuilder { dfa: Dfa { states: Vec::with_capacity(16) }, lev, diff --git a/src/automaton/mod.rs b/src/automaton/mod.rs index 254c8ca..a36392a 100644 --- a/src/automaton/mod.rs +++ b/src/automaton/mod.rs @@ -1,6 +1,5 @@ #[cfg(feature = "levenshtein")] pub use self::levenshtein::{Levenshtein, LevenshteinError}; -use self::StartsWithStateInternal::*; #[cfg(feature = "levenshtein")] mod levenshtein; @@ -109,23 +108,23 @@ pub trait Automaton { impl<'a, T: Automaton> Automaton for &'a T { type State = T::State; - fn start(&self) -> Self::State { + fn start(&self) -> T::State { (*self).start() } - fn is_match(&self, state: &Self::State) -> bool { + fn is_match(&self, state: &T::State) -> bool { (*self).is_match(state) } - fn can_match(&self, state: &Self::State) -> bool { + fn can_match(&self, state: &T::State) -> bool { (*self).can_match(state) } - fn will_always_match(&self, state: &Self::State) -> bool { + fn will_always_match(&self, state: &T::State) -> bool { (*self).will_always_match(state) } - fn accept(&self, state: &Self::State, byte: u8) -> Self::State { + fn accept(&self, state: &T::State, byte: u8) -> T::State { (*self).accept(state, byte) } } @@ -138,13 +137,11 @@ impl<'a, T: Automaton> Automaton for &'a T { /// ```rust /// extern crate fst; /// -/// use std::error::Error; -/// /// use fst::{Automaton, IntoStreamer, Streamer, Set}; /// use fst::automaton::Str; /// /// # fn main() { example().unwrap(); } -/// fn example() -> Result<(), Box> { +/// fn example() -> Result<(), Box> { /// let paths = vec!["/home/projects/bar", "/home/projects/foo", "/tmp/foo"]; /// let set = Set::from_iter(paths)?; /// @@ -212,13 +209,11 @@ impl<'a> Automaton for Str<'a> { /// ```rust /// extern crate fst; /// -/// use std::error::Error; -/// /// use fst::{IntoStreamer, Streamer, Set}; /// use fst::automaton::Subsequence; /// /// # fn main() { example().unwrap(); } -/// fn example() -> Result<(), Box> { +/// fn example() -> Result<(), Box> { /// let paths = vec!["/home/projects/bar", "/home/projects/foo", "/tmp/foo"]; /// let set = Set::from_iter(paths)?; /// @@ -317,9 +312,9 @@ impl Automaton for AlwaysMatch { pub struct StartsWith(A); /// The `Automaton` state for `StartsWith`. -pub struct StartsWithState(StartsWithStateInternal); +pub struct StartsWithState(StartsWithStateKind); -enum StartsWithStateInternal { +enum StartsWithStateKind { Done, Running(A::State), } @@ -331,31 +326,31 @@ impl Automaton for StartsWith { StartsWithState({ let inner = self.0.start(); if self.0.is_match(&inner) { - Done + StartsWithStateKind::Done } else { - Running(inner) + StartsWithStateKind::Running(inner) } }) } fn is_match(&self, state: &StartsWithState) -> bool { match state.0 { - Done => true, - Running(_) => false, + StartsWithStateKind::Done => true, + StartsWithStateKind::Running(_) => false, } } fn can_match(&self, state: &StartsWithState) -> bool { match state.0 { - Done => true, - Running(ref inner) => self.0.can_match(inner), + StartsWithStateKind::Done => true, + StartsWithStateKind::Running(ref inner) => self.0.can_match(inner), } } fn will_always_match(&self, state: &StartsWithState) -> bool { match state.0 { - Done => true, - Running(_) => false, + StartsWithStateKind::Done => true, + StartsWithStateKind::Running(_) => false, } } @@ -365,13 +360,13 @@ impl Automaton for StartsWith { byte: u8, ) -> StartsWithState { StartsWithState(match state.0 { - Done => Done, - Running(ref inner) => { + StartsWithStateKind::Done => StartsWithStateKind::Done, + StartsWithStateKind::Running(ref inner) => { let next_inner = self.0.accept(inner, byte); if self.0.is_match(&next_inner) { - Done + StartsWithStateKind::Done } else { - Running(next_inner) + StartsWithStateKind::Running(next_inner) } } }) diff --git a/src/error.rs b/src/error.rs index 1f68761..dc89955 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,3 @@ -use std::error; use std::fmt; use std::io; @@ -33,20 +32,18 @@ impl From for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use self::Error::*; match *self { - Fst(ref err) => err.fmt(f), - Io(ref err) => err.fmt(f), + Error::Fst(ref err) => err.fmt(f), + Error::Io(ref err) => err.fmt(f), } } } -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - use self::Error::*; +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match *self { - Fst(ref err) => Some(err), - Io(ref err) => Some(err), + Error::Fst(ref err) => Some(err), + Error::Io(ref err) => Some(err), } } } diff --git a/src/lib.rs b/src/lib.rs index 0538fb3..04c3364 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,7 @@ Simply add a corresponding entry to your `Cargo.toml` dependency list: ```ignore [dependencies] -fst = "0.2" +fst = "0.4" ``` The examples in this documentation will show the rest. @@ -52,13 +52,11 @@ This requires the `levenshtein` feature in this crate to be enabled. It is not enabled by default. ```rust -use std::error::Error; - use fst::{IntoStreamer, Streamer, Set}; use fst::automaton::Levenshtein; # fn main() { example().unwrap(); } -fn example() -> Result<(), Box> { +fn example() -> Result<(), Box> { // A convenient way to create sets in memory. let keys = vec!["fa", "fo", "fob", "focus", "foo", "food", "foul"]; let set = Set::from_iter(keys)?; @@ -167,8 +165,8 @@ the `transducer` feature enabled: ```toml [dependencies] -fst = "0.3" -regex-automata = { version = "0.1.9", features = ["transducer"] } +fst = "0.4" +regex-automata = { version = "0.1.8", features = ["transducer"] } ``` # Example: searching multiple sets efficiently @@ -184,14 +182,12 @@ The example below shows how to find all keys that start with `B` or `G`. The example below uses sets, but the same operations are available on maps too. ```rust -use std::error::Error; - use fst::automaton::{Automaton, Str}; use fst::set; use fst::{IntoStreamer, Set, Streamer}; # fn main() { example().unwrap(); } -fn example() -> Result<(), Box> { +fn example() -> Result<(), Box> { let set1 = Set::from_iter(&["AC/DC", "Aerosmith"])?; let set2 = Set::from_iter(&["Bob Seger", "Bruce Springsteen"])?; let set3 = Set::from_iter(&["George Thorogood", "Golden Earring"])?; @@ -305,6 +301,9 @@ data structures found in the standard library, such as `BTreeSet` and #![deny(missing_docs)] +#[cfg(all(feature = "levenshtein", doctest))] +doc_comment::doctest!("../README.md"); + pub use crate::automaton::Automaton; pub use crate::error::{Error, Result}; pub use crate::map::{Map, MapBuilder}; diff --git a/src/map.rs b/src/map.rs index d6e2053..b2b40f5 100644 --- a/src/map.rs +++ b/src/map.rs @@ -576,7 +576,7 @@ pub struct MapBuilder(raw::Builder); impl MapBuilder> { /// Create a builder that builds a map in memory. #[inline] - pub fn memory() -> Self { + pub fn memory() -> MapBuilder> { MapBuilder(raw::Builder::memory()) } @@ -678,7 +678,7 @@ where impl<'a, 'm, A: Automaton> Streamer<'a> for Stream<'m, A> { type Item = (&'a [u8], u64); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], u64)> { self.0.next().map(|(key, out)| (key, out.value())) } } @@ -757,7 +757,7 @@ impl<'a, 'm> Streamer<'a> for Keys<'m> { type Item = &'a [u8]; #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<&'a [u8]> { self.0.next().map(|(key, _)| key) } } @@ -772,7 +772,7 @@ impl<'a, 'm> Streamer<'a> for Values<'m> { type Item = u64; #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option { self.0.next().map(|(_, out)| out.value()) } } @@ -817,7 +817,7 @@ impl<'m, 'a, A: Automaton> IntoStreamer<'a> for StreamBuilder<'m, A> { type Item = (&'a [u8], u64); type Into = Stream<'m, A>; - fn into_stream(self) -> Self::Into { + fn into_stream(self) -> Stream<'m, A> { Stream(self.0.into_stream()) } } @@ -912,7 +912,7 @@ pub struct OpBuilder<'m>(raw::OpBuilder<'m>); impl<'m> OpBuilder<'m> { /// Create a new set operation builder. #[inline] - pub fn new() -> Self { + pub fn new() -> OpBuilder<'m> { OpBuilder(raw::OpBuilder::new()) } @@ -923,7 +923,7 @@ impl<'m> OpBuilder<'m> { /// /// The stream must emit a lexicographically ordered sequence of key-value /// pairs. - pub fn add(mut self, streamable: I) -> Self + pub fn add(mut self, streamable: I) -> OpBuilder<'m> where I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>, S: 'm + for<'a> Streamer<'a, Item = (&'a [u8], u64)>, @@ -1144,7 +1144,7 @@ where I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>, S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], u64)>, { - fn from_iter(it: T) -> Self + fn from_iter(it: T) -> OpBuilder<'f> where T: IntoIterator, { @@ -1163,7 +1163,7 @@ impl<'a, 'm> Streamer<'a> for Union<'m> { type Item = (&'a [u8], &'a [IndexedValue]); #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { self.0.next() } } @@ -1178,7 +1178,7 @@ impl<'a, 'm> Streamer<'a> for Intersection<'m> { type Item = (&'a [u8], &'a [IndexedValue]); #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { self.0.next() } } @@ -1197,7 +1197,7 @@ impl<'a, 'm> Streamer<'a> for Difference<'m> { type Item = (&'a [u8], &'a [IndexedValue]); #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { self.0.next() } } @@ -1212,7 +1212,7 @@ impl<'a, 'm> Streamer<'a> for SymmetricDifference<'m> { type Item = (&'a [u8], &'a [IndexedValue]); #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { self.0.next() } } @@ -1230,7 +1230,7 @@ where { type Item = (&'a [u8], raw::Output); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], raw::Output)> { self.0.next().map(|(k, v)| (k, raw::Output::new(v))) } } diff --git a/src/raw/build.rs b/src/raw/build.rs index 5dc33b0..642fab4 100644 --- a/src/raw/build.rs +++ b/src/raw/build.rs @@ -99,7 +99,7 @@ struct LastTransition { impl Builder> { /// Create a builder that builds an fst in memory. #[inline] - pub fn memory() -> Self { + pub fn memory() -> Builder> { Builder::new(Vec::with_capacity(10 * (1 << 10))).unwrap() } @@ -447,7 +447,7 @@ impl BuilderNodeUnfinished { } impl Clone for BuilderNode { - fn clone(&self) -> Self { + fn clone(&self) -> BuilderNode { BuilderNode { is_final: self.is_final, final_output: self.final_output, @@ -455,7 +455,7 @@ impl Clone for BuilderNode { } } - fn clone_from(&mut self, source: &Self) { + fn clone_from(&mut self, source: &BuilderNode) { self.is_final = source.is_final; self.final_output = source.final_output; self.trans.clear(); @@ -464,7 +464,7 @@ impl Clone for BuilderNode { } impl Default for BuilderNode { - fn default() -> Self { + fn default() -> BuilderNode { BuilderNode { is_final: false, final_output: Output::zero(), diff --git a/src/raw/error.rs b/src/raw/error.rs index 6d2bf05..d4e6d81 100644 --- a/src/raw/error.rs +++ b/src/raw/error.rs @@ -70,10 +70,9 @@ pub enum Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use self::Error::*; match *self { - FromUtf8(ref err) => err.fmt(f), - Version { expected, got } => write!( + Error::FromUtf8(ref err) => err.fmt(f), + Error::Version { expected, got } => write!( f, "\ Error opening FST: expected API version {}, got API version {}. \ @@ -83,24 +82,24 @@ to change the version of the 'fst' crate you're using, or re-generate the FST.", expected, got ), - Format { size } => write!( + Error::Format { size } => write!( f, "\ Error opening FST with size {} bytes: An unknown error occurred. This \ usually means you're trying to read data that isn't actually an encoded FST.", size ), - ChecksumMismatch { expected, got } => write!( + Error::ChecksumMismatch { expected, got } => write!( f, "FST verification failed: expected checksum of {} but got {}", expected, got, ), - DuplicateKey { ref got } => write!( + Error::DuplicateKey { ref got } => write!( f, "Error inserting duplicate key: '{}'.", format_bytes(&*got) ), - OutOfOrder { ref previous, ref got } => write!( + Error::OutOfOrder { ref previous, ref got } => write!( f, "\ Error inserting out-of-order key: '{}'. (Previous key was '{}'.) Keys must be \ @@ -108,7 +107,7 @@ inserted in lexicographic order.", format_bytes(&*got), format_bytes(&*previous) ), - WrongType { expected, got } => write!( + Error::WrongType { expected, got } => write!( f, "\ Error opening FST: expected type '{}', got type '{}'.", @@ -135,7 +134,7 @@ impl std::error::Error for Error { impl From for Error { #[inline] - fn from(err: FromUtf8Error) -> Self { + fn from(err: FromUtf8Error) -> Error { Error::FromUtf8(err) } } diff --git a/src/raw/mod.rs b/src/raw/mod.rs index 62c7a46..1f4c8af 100644 --- a/src/raw/mod.rs +++ b/src/raw/mod.rs @@ -26,10 +26,10 @@ use crate::bytes; use crate::error::Result; use crate::stream::{IntoStreamer, Streamer}; -pub use self::build::Builder; -pub use self::error::Error; -pub use self::node::{Node, Transitions}; -pub use self::ops::{ +pub use crate::raw::build::Builder; +pub use crate::raw::error::Error; +pub use crate::raw::node::{Node, Transitions}; +pub use crate::raw::ops::{ Difference, IndexedValue, Intersection, OpBuilder, SymmetricDifference, Union, }; @@ -621,7 +621,7 @@ impl<'a, 'f, D: AsRef<[u8]>> IntoStreamer<'a> for &'f Fst { type Into = Stream<'f>; #[inline] - fn into_stream(self) -> Self::Into { + fn into_stream(self) -> Stream<'f> { StreamBuilder::new(self.as_ref(), AlwaysMatch).into_stream() } } @@ -761,7 +761,7 @@ pub struct StreamBuilder<'f, A = AlwaysMatch> { } impl<'f, A: Automaton> StreamBuilder<'f, A> { - fn new(fst: FstRef<'f>, aut: A) -> Self { + fn new(fst: FstRef<'f>, aut: A) -> StreamBuilder<'f, A> { StreamBuilder { fst, aut, @@ -1001,7 +1001,7 @@ impl<'f, A: Automaton> Stream<'f, A> { impl<'f, 'a, A: Automaton> Streamer<'a> for Stream<'f, A> { type Item = (&'a [u8], Output); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], Output)> { self.0.next_with(|_| ()).map(|(key, out, _)| (key, out)) } } @@ -1287,7 +1287,7 @@ pub struct Transition { impl Default for Transition { #[inline] - fn default() -> Self { + fn default() -> Transition { Transition { inp: 0, out: Output::zero(), addr: NONE_ADDRESS } } } diff --git a/src/raw/node.rs b/src/raw/node.rs index 0e05bc0..8a9b95b 100644 --- a/src/raw/node.rs +++ b/src/raw/node.rs @@ -57,10 +57,9 @@ impl<'f> Node<'f> { addr: CompiledAddr, data: &[u8], ) -> Node<'_> { - use self::State::*; let state = State::new(data, addr); match state { - EmptyFinal => Node { + State::EmptyFinal => Node { data: &[], version, state: State::EmptyFinal, @@ -71,7 +70,7 @@ impl<'f> Node<'f> { sizes: PackSizes::new(), final_output: Output::zero(), }, - OneTransNext(s) => { + State::OneTransNext(s) => { let data = &data[..addr + 1]; Node { data, @@ -85,7 +84,7 @@ impl<'f> Node<'f> { final_output: Output::zero(), } } - OneTrans(s) => { + State::OneTrans(s) => { let data = &data[..addr + 1]; let sizes = s.sizes(data); Node { @@ -100,7 +99,7 @@ impl<'f> Node<'f> { final_output: Output::zero(), } } - AnyTrans(s) => { + State::AnyTrans(s) => { let data = &data[..addr + 1]; let sizes = s.sizes(data); let ntrans = s.ntrans(data); @@ -162,18 +161,17 @@ impl<'f> Node<'f> { /// Returns the transition address of the `i`th transition. #[inline] pub fn transition_addr(&self, i: usize) -> CompiledAddr { - use self::State::*; match self.state { - OneTransNext(s) => { + State::OneTransNext(s) => { assert!(i == 0); s.trans_addr(self) } - OneTrans(s) => { + State::OneTrans(s) => { assert!(i == 0); s.trans_addr(self) } - AnyTrans(s) => s.trans_addr(self, i), - EmptyFinal => panic!("out of bounds"), + State::AnyTrans(s) => s.trans_addr(self, i), + State::EmptyFinal => panic!("out of bounds"), } } @@ -182,14 +180,13 @@ impl<'f> Node<'f> { /// If no transition for this byte exists, then `None` is returned. #[inline] pub fn find_input(&self, b: u8) -> Option { - use self::State::*; match self.state { - OneTransNext(s) if s.input(self) == b => Some(0), - OneTransNext(_) => None, - OneTrans(s) if s.input(self) == b => Some(0), - OneTrans(_) => None, - AnyTrans(s) => s.find_input(self, b), - EmptyFinal => None, + State::OneTransNext(s) if s.input(self) == b => Some(0), + State::OneTransNext(_) => None, + State::OneTrans(s) if s.input(self) == b => Some(0), + State::OneTrans(_) => None, + State::AnyTrans(s) => s.find_input(self, b), + State::EmptyFinal => None, } } @@ -236,12 +233,11 @@ impl<'f> Node<'f> { #[doc(hidden)] #[inline] pub fn state(&self) -> &'static str { - use self::State::*; match self.state { - OneTransNext(_) => "OTN", - OneTrans(_) => "OT", - AnyTrans(_) => "AT", - EmptyFinal => "EF", + State::OneTransNext(_) => "OTN", + State::OneTrans(_) => "OT", + State::AnyTrans(_) => "AT", + State::EmptyFinal => "EF", } } @@ -303,15 +299,14 @@ struct StateAnyTrans(u8); impl State { fn new(data: &[u8], addr: CompiledAddr) -> State { - use self::State::*; if addr == EMPTY_ADDRESS { - return EmptyFinal; + return State::EmptyFinal; } let v = data[addr]; match (v & 0b11_000000) >> 6 { - 0b11 => OneTransNext(StateOneTransNext(v)), - 0b10 => OneTrans(StateOneTrans(v)), - _ => AnyTrans(StateAnyTrans(v)), + 0b11 => State::OneTransNext(StateOneTransNext(v)), + 0b10 => State::OneTrans(StateOneTrans(v)), + _ => State::AnyTrans(StateAnyTrans(v)), } } } @@ -332,7 +327,7 @@ impl StateOneTransNext { } #[inline] - fn new() -> Self { + fn new() -> StateOneTransNext { StateOneTransNext(0b11_000000) } @@ -401,7 +396,7 @@ impl StateOneTrans { } #[inline] - fn new() -> Self { + fn new() -> StateOneTrans { StateOneTrans(0b10_000000) } @@ -548,7 +543,7 @@ impl StateAnyTrans { } #[inline] - fn new() -> Self { + fn new() -> StateAnyTrans { StateAnyTrans(0b00_000000) } @@ -745,12 +740,12 @@ struct PackSizes(u8); impl PackSizes { #[inline] - fn new() -> Self { + fn new() -> PackSizes { PackSizes(0) } #[inline] - fn decode(v: u8) -> Self { + fn decode(v: u8) -> PackSizes { PackSizes(v) } diff --git a/src/raw/ops.rs b/src/raw/ops.rs index a9e79a1..9baf855 100644 --- a/src/raw/ops.rs +++ b/src/raw/ops.rs @@ -48,7 +48,7 @@ pub struct OpBuilder<'f> { impl<'f> OpBuilder<'f> { /// Create a new set operation builder. #[inline] - pub fn new() -> Self { + pub fn new() -> OpBuilder<'f> { OpBuilder { streams: vec![] } } @@ -59,7 +59,7 @@ impl<'f> OpBuilder<'f> { /// /// The stream must emit a lexicographically ordered sequence of key-value /// pairs. - pub fn add(mut self, stream: I) -> Self + pub fn add(mut self, stream: I) -> OpBuilder<'f> where I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], Output)>, S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], Output)>, @@ -188,7 +188,7 @@ where I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], Output)>, S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], Output)>, { - fn from_iter(it: T) -> Self + fn from_iter(it: T) -> OpBuilder<'f> where T: IntoIterator, { @@ -210,7 +210,7 @@ pub struct Union<'f> { impl<'a, 'f> Streamer<'a> for Union<'f> { type Item = (&'a [u8], &'a [IndexedValue]); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { if let Some(slot) = self.cur_slot.take() { self.heap.refill(slot); } @@ -244,7 +244,7 @@ pub struct Intersection<'f> { impl<'a, 'f> Streamer<'a> for Intersection<'f> { type Item = (&'a [u8], &'a [IndexedValue]); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { if let Some(slot) = self.cur_slot.take() { self.heap.refill(slot); } @@ -290,7 +290,7 @@ pub struct Difference<'f> { impl<'a, 'f> Streamer<'a> for Difference<'f> { type Item = (&'a [u8], &'a [IndexedValue]); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { loop { match self.set.next() { None => return None, @@ -329,7 +329,7 @@ pub struct SymmetricDifference<'f> { impl<'a, 'f> Streamer<'a> for SymmetricDifference<'f> { type Item = (&'a [u8], &'a [IndexedValue]); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(&'a [u8], &'a [IndexedValue])> { if let Some(slot) = self.cur_slot.take() { self.heap.refill(slot); } diff --git a/src/set.rs b/src/set.rs index 412a5d0..3af8538 100644 --- a/src/set.rs +++ b/src/set.rs @@ -411,7 +411,7 @@ impl<'s, 'a, D: AsRef<[u8]>> IntoStreamer<'a> for &'s Set { type Into = Stream<'s>; #[inline] - fn into_stream(self) -> Self::Into { + fn into_stream(self) -> Stream<'s> { Stream(self.0.stream()) } } @@ -518,7 +518,7 @@ pub struct SetBuilder(raw::Builder); impl SetBuilder> { /// Create a builder that builds a set in memory. #[inline] - pub fn memory() -> Self { + pub fn memory() -> SetBuilder> { SetBuilder(raw::Builder::memory()) } @@ -789,7 +789,7 @@ pub struct OpBuilder<'s>(raw::OpBuilder<'s>); impl<'s> OpBuilder<'s> { /// Create a new set operation builder. #[inline] - pub fn new() -> Self { + pub fn new() -> OpBuilder<'s> { OpBuilder(raw::OpBuilder::new()) } @@ -800,7 +800,7 @@ impl<'s> OpBuilder<'s> { /// /// The stream must emit a lexicographically ordered sequence of byte /// strings. - pub fn add(mut self, streamable: I) -> Self + pub fn add(mut self, streamable: I) -> OpBuilder<'s> where I: for<'a> IntoStreamer<'a, Into = S, Item = &'a [u8]>, S: 's + for<'a> Streamer<'a, Item = &'a [u8]>, @@ -943,7 +943,7 @@ where I: for<'a> IntoStreamer<'a, Into = S, Item = &'a [u8]>, S: 'f + for<'a> Streamer<'a, Item = &'a [u8]>, { - fn from_iter(it: T) -> Self + fn from_iter(it: T) -> OpBuilder<'f> where T: IntoIterator, { @@ -962,7 +962,7 @@ impl<'a, 's> Streamer<'a> for Union<'s> { type Item = &'a [u8]; #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<&'a [u8]> { self.0.next().map(|(key, _)| key) } } @@ -976,7 +976,7 @@ impl<'a, 's> Streamer<'a> for Intersection<'s> { type Item = &'a [u8]; #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<&'a [u8]> { self.0.next().map(|(key, _)| key) } } @@ -994,7 +994,7 @@ impl<'a, 's> Streamer<'a> for Difference<'s> { type Item = &'a [u8]; #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<&'a [u8]> { self.0.next().map(|(key, _)| key) } } @@ -1009,7 +1009,7 @@ impl<'a, 's> Streamer<'a> for SymmetricDifference<'s> { type Item = &'a [u8]; #[inline] - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<&'a [u8]> { self.0.next().map(|(key, _)| key) } } @@ -1024,7 +1024,7 @@ struct StreamZeroOutput(S); impl<'a, S: Streamer<'a>> Streamer<'a> for StreamZeroOutput { type Item = (S::Item, raw::Output); - fn next(&'a mut self) -> Option { + fn next(&'a mut self) -> Option<(S::Item, raw::Output)> { self.0.next().map(|key| (key, raw::Output::zero())) } }