use std::io;
use tantivy_fst::automaton::AlwaysMatch;
use tantivy_fst::map::{Stream, StreamBuilder};
use tantivy_fst::{Automaton, IntoStreamer, Streamer};
use super::TermDictionary;
use crate::postings::TermInfo;
use crate::termdict::TermOrdinal;
pub struct TermStreamerBuilder<'a, A = AlwaysMatch>
where A: Automaton
{
fst_map: &'a TermDictionary,
stream_builder: StreamBuilder<'a, A>,
}
impl<'a, A> TermStreamerBuilder<'a, A>
where A: Automaton
{
pub(crate) fn new(fst_map: &'a TermDictionary, stream_builder: StreamBuilder<'a, A>) -> Self {
TermStreamerBuilder {
fst_map,
stream_builder,
}
}
pub fn ge<T: AsRef<[u8]>>(mut self, bound: T) -> Self {
self.stream_builder = self.stream_builder.ge(bound);
self
}
pub fn gt<T: AsRef<[u8]>>(mut self, bound: T) -> Self {
self.stream_builder = self.stream_builder.gt(bound);
self
}
pub fn le<T: AsRef<[u8]>>(mut self, bound: T) -> Self {
self.stream_builder = self.stream_builder.le(bound);
self
}
pub fn lt<T: AsRef<[u8]>>(mut self, bound: T) -> Self {
self.stream_builder = self.stream_builder.lt(bound);
self
}
pub fn backward(mut self) -> Self {
self.stream_builder = self.stream_builder.backward();
self
}
pub fn into_stream(self) -> io::Result<TermStreamer<'a, A>> {
Ok(TermStreamer {
fst_map: self.fst_map,
stream: self.stream_builder.into_stream(),
term_ord: 0u64,
current_key: Vec::with_capacity(100),
current_value: TermInfo::default(),
})
}
}
pub struct TermStreamer<'a, A = AlwaysMatch>
where A: Automaton
{
pub(crate) fst_map: &'a TermDictionary,
pub(crate) stream: Stream<'a, A>,
term_ord: TermOrdinal,
current_key: Vec<u8>,
current_value: TermInfo,
}
impl<'a, A> TermStreamer<'a, A>
where A: Automaton
{
pub fn advance(&mut self) -> bool {
if let Some((term, term_ord)) = self.stream.next() {
self.current_key.clear();
self.current_key.extend_from_slice(term);
self.term_ord = term_ord;
self.current_value = self.fst_map.term_info_from_ord(term_ord);
true
} else {
false
}
}
pub fn term_ord(&self) -> TermOrdinal {
self.term_ord
}
pub fn key(&self) -> &[u8] {
&self.current_key
}
pub fn value(&self) -> &TermInfo {
&self.current_value
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<(&[u8], &TermInfo)> {
if self.advance() {
Some((self.key(), self.value()))
} else {
None
}
}
}