use std::fmt;
use std::io;
use std::iter::FromIterator;
use crate::automaton::{AlwaysMatch, Automaton};
use crate::raw;
pub use crate::raw::IndexedValue;
use crate::raw::Output;
use crate::stream::{IntoStreamer, Streamer};
use crate::Result;
use std::ops::Deref;
pub struct Map<Data>(raw::Fst<Data>);
impl Map<Vec<u8>> {
pub fn from_bytes(bytes: Vec<u8>) -> Result<Map<Vec<u8>>> {
raw::Fst::new(bytes).map(Map)
}
pub fn from_iter<K, I>(iter: I) -> Result<Self>
where
K: AsRef<[u8]>,
I: IntoIterator<Item = (K, u64)>,
{
let mut builder = MapBuilder::memory();
builder.extend_iter(iter)?;
Map::from_bytes(builder.into_inner()?)
}
}
impl<Data: Deref<Target = [u8]>> Map<Data> {
pub fn contains_key<K: AsRef<[u8]>>(&self, key: K) -> bool {
self.0.contains_key(key)
}
pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Option<u64> {
self.0.get(key).map(|output| output.value())
}
#[inline]
pub fn stream(&self) -> Stream {
Stream(self.0.stream())
}
#[inline]
pub fn keys(&self) -> Keys {
Keys(self.0.stream())
}
#[inline]
pub fn values(&self) -> Values {
Values(self.0.stream())
}
#[inline]
pub fn range(&self) -> StreamBuilder {
StreamBuilder(self.0.range())
}
pub fn search<A: Automaton>(&self, aut: A) -> StreamBuilder<A> {
StreamBuilder(self.0.search(aut))
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn op(&self) -> OpBuilder {
OpBuilder::new().add(self)
}
#[inline]
pub fn as_fst(&self) -> &raw::Fst<Data> {
&self.0
}
}
impl<Data: Deref<Target = [u8]>> fmt::Debug for Map<Data> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Map([")?;
let mut stream = self.stream();
let mut first = true;
while let Some((k, v)) = stream.next() {
if !first {
write!(f, ", ")?;
}
first = false;
write!(f, "({}, {})", String::from_utf8_lossy(k), v)?;
}
write!(f, "])")
}
}
impl<Data> From<raw::Fst<Data>> for Map<Data> {
#[inline]
fn from(fst: raw::Fst<Data>) -> Self {
Map(fst)
}
}
impl<Data> AsRef<raw::Fst<Data>> for Map<Data> {
#[inline]
fn as_ref(&self) -> &raw::Fst<Data> {
&self.0
}
}
impl<'m, 'a, Data: Deref<Target = [u8]>> IntoStreamer<'a> for &'m Map<Data> {
type Item = (&'a [u8], u64);
type Into = Stream<'m>;
#[inline]
fn into_stream(self) -> Self::Into {
Stream(self.0.stream())
}
}
pub struct MapBuilder<W>(raw::Builder<W>);
impl MapBuilder<Vec<u8>> {
#[inline]
pub fn memory() -> Self {
MapBuilder(raw::Builder::memory())
}
}
impl<W: io::Write> MapBuilder<W> {
pub fn new(wtr: W) -> Result<MapBuilder<W>> {
raw::Builder::new_type(wtr, 0).map(MapBuilder)
}
pub fn insert<K: AsRef<[u8]>>(&mut self, key: K, val: u64) -> Result<()> {
self.0.insert(key, val)
}
pub fn extend_iter<K, I>(&mut self, iter: I) -> Result<()>
where
K: AsRef<[u8]>,
I: IntoIterator<Item = (K, u64)>,
{
self.0
.extend_iter(iter.into_iter().map(|(k, v)| (k, raw::Output::new(v))))
}
pub fn extend_stream<'f, I, S>(&mut self, stream: I) -> Result<()>
where
I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
{
self.0.extend_stream(StreamOutput(stream.into_stream()))
}
pub fn finish(self) -> Result<()> {
self.0.finish()
}
pub fn into_inner(self) -> Result<W> {
self.0.into_inner()
}
pub fn get_ref(&self) -> &W {
self.0.get_ref()
}
pub fn bytes_written(&self) -> u64 {
self.0.bytes_written()
}
}
pub struct Stream<'m, A = AlwaysMatch>(raw::Stream<'m, A>)
where
A: Automaton;
impl<'a, 'm, A: Automaton> Streamer<'a> for Stream<'m, A> {
type Item = (&'a [u8], u64);
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next().map(|(key, out)| (key, out.value()))
}
}
impl<'m, A: Automaton> Stream<'m, A> {
pub fn into_byte_vec(self) -> Vec<(Vec<u8>, u64)> {
self.0.into_byte_vec()
}
pub fn into_str_vec(self) -> Result<Vec<(String, u64)>> {
self.0.into_str_vec()
}
pub fn into_byte_keys(self) -> Vec<Vec<u8>> {
self.0.into_byte_keys()
}
pub fn into_str_keys(self) -> Result<Vec<String>> {
self.0.into_str_keys()
}
pub fn into_values(self) -> Vec<u64> {
self.0.into_values()
}
}
pub struct Keys<'m>(raw::Stream<'m>);
impl<'a, 'm> Streamer<'a> for Keys<'m> {
type Item = &'a [u8];
#[inline]
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next().map(|(key, _)| key)
}
}
pub struct Values<'m>(raw::Stream<'m>);
impl<'a, 'm> Streamer<'a> for Values<'m> {
type Item = u64;
#[inline]
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next().map(|(_, out)| out.value())
}
}
pub struct StreamBuilder<'m, A = AlwaysMatch>(raw::StreamBuilder<'m, A>);
impl<'m, A: Automaton> StreamBuilder<'m, A> {
pub fn ge<T: AsRef<[u8]>>(self, bound: T) -> Self {
StreamBuilder(self.0.ge(bound))
}
pub fn gt<T: AsRef<[u8]>>(self, bound: T) -> Self {
StreamBuilder(self.0.gt(bound))
}
pub fn le<T: AsRef<[u8]>>(self, bound: T) -> Self {
StreamBuilder(self.0.le(bound))
}
pub fn lt<T: AsRef<[u8]>>(self, bound: T) -> Self {
StreamBuilder(self.0.lt(bound))
}
pub fn backward(self) -> Self {
StreamBuilder(self.0.backward())
}
pub fn with_state(self) -> StreamWithStateBuilder<'m, A> {
StreamWithStateBuilder(self.0.with_state())
}
}
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 {
Stream(self.0.into_stream())
}
}
pub struct StreamWithStateBuilder<'m, A = AlwaysMatch>(raw::StreamWithStateBuilder<'m, A>);
impl<'m, 'a, A: 'a + Automaton> IntoStreamer<'a> for StreamWithStateBuilder<'m, A>
where
A::State: Clone,
{
type Item = (&'a [u8], u64, A::State);
type Into = StreamWithState<'m, A>;
fn into_stream(self) -> Self::Into {
StreamWithState(self.0.into_stream())
}
}
pub struct OpBuilder<'m>(raw::OpBuilder<'m>);
impl<'m> OpBuilder<'m> {
#[inline]
pub fn new() -> Self {
OpBuilder(raw::OpBuilder::default())
}
pub fn add<I, S>(mut self, streamable: I) -> Self
where
I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
S: 'm + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
{
self.push(streamable);
self
}
pub fn push<I, S>(&mut self, streamable: I)
where
I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
S: 'm + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
{
self.0.push(StreamOutput(streamable.into_stream()));
}
#[inline]
pub fn union(self) -> Union<'m> {
Union(self.0.union())
}
#[inline]
pub fn chain(self) -> Chain<'m> {
Chain(self.0.chain())
}
#[inline]
pub fn intersection(self) -> Intersection<'m> {
Intersection(self.0.intersection())
}
#[inline]
pub fn difference(self) -> Difference<'m> {
Difference(self.0.difference())
}
#[inline]
pub fn symmetric_difference(self) -> SymmetricDifference<'m> {
SymmetricDifference(self.0.symmetric_difference())
}
}
impl<'f, I, S> Extend<I> for OpBuilder<'f>
where
I: for<'a> IntoStreamer<'a, Into = S, Item = (&'a [u8], u64)>,
S: 'f + for<'a> Streamer<'a, Item = (&'a [u8], u64)>,
{
fn extend<T>(&mut self, it: T)
where
T: IntoIterator<Item = I>,
{
for stream in it {
self.push(stream);
}
}
}
impl<'f, I, S> FromIterator<I> for OpBuilder<'f>
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<T>(it: T) -> Self
where
T: IntoIterator<Item = I>,
{
let mut op = OpBuilder::new();
op.extend(it);
op
}
}
pub struct Union<'m>(raw::Union<'m>);
impl<'a, 'm> Streamer<'a> for Union<'m> {
type Item = (&'a [u8], &'a [IndexedValue]);
#[inline]
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next()
}
}
pub struct Chain<'m>(raw::Chain<'m>);
impl<'a, 'm> Streamer<'a> for Chain<'m> {
type Item = (&'a [u8], Output);
#[inline]
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next()
}
}
pub struct Intersection<'m>(raw::Intersection<'m>);
impl<'a, 'm> Streamer<'a> for Intersection<'m> {
type Item = (&'a [u8], &'a [IndexedValue]);
#[inline]
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next()
}
}
pub struct Difference<'m>(raw::Difference<'m>);
impl<'a, 'm> Streamer<'a> for Difference<'m> {
type Item = (&'a [u8], &'a [IndexedValue]);
#[inline]
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next()
}
}
pub struct SymmetricDifference<'m>(raw::SymmetricDifference<'m>);
impl<'a, 'm> Streamer<'a> for SymmetricDifference<'m> {
type Item = (&'a [u8], &'a [IndexedValue]);
#[inline]
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next()
}
}
struct StreamOutput<S>(S);
impl<'a, S> Streamer<'a> for StreamOutput<S>
where
S: Streamer<'a, Item = (&'a [u8], u64)>,
{
type Item = (&'a [u8], raw::Output);
fn next(&'a mut self) -> Option<Self::Item> {
self.0.next().map(|(k, v)| (k, raw::Output::new(v)))
}
}
pub struct StreamWithState<'m, A = AlwaysMatch>(raw::StreamWithState<'m, A>)
where
A: Automaton;
impl<'a, 'm, A: 'a + Automaton> Streamer<'a> for StreamWithState<'m, A>
where
A::State: Clone,
{
type Item = (&'a [u8], u64, A::State);
fn next(&'a mut self) -> Option<Self::Item> {
self.0
.next()
.map(|(key, out, state)| (key, out.value(), state))
}
}