diff --git a/src/query/all_query.rs b/src/query/all_query.rs index ce5ac5c29..bfc1fddbf 100644 --- a/src/query/all_query.rs +++ b/src/query/all_query.rs @@ -9,7 +9,7 @@ use Score; /// Query that matches all of the documents. /// /// All of the document get the score 1f32. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct AllQuery; impl Query for AllQuery { diff --git a/src/query/boolean_query/boolean_query.rs b/src/query/boolean_query/boolean_query.rs index 802ba0614..f4fa84c08 100644 --- a/src/query/boolean_query/boolean_query.rs +++ b/src/query/boolean_query/boolean_query.rs @@ -23,6 +23,16 @@ pub struct BooleanQuery { subqueries: Vec<(Occur, Box)>, } +impl Clone for BooleanQuery { + fn clone(&self) -> Self { + self.subqueries + .iter() + .map(|(x, y)| (x.clone(), y.box_clone())) + .collect::>() + .into() + } +} + impl From)>> for BooleanQuery { fn from(subqueries: Vec<(Occur, Box)>) -> BooleanQuery { BooleanQuery { subqueries } @@ -55,4 +65,8 @@ impl BooleanQuery { .collect(); BooleanQuery::from(occur_term_queries) } + + pub fn clauses(&self) -> &[(Occur, Box)] { + &self.subqueries[..] + } } diff --git a/src/query/phrase_query/phrase_query.rs b/src/query/phrase_query/phrase_query.rs index 1f12d9ce9..0834442d1 100644 --- a/src/query/phrase_query/phrase_query.rs +++ b/src/query/phrase_query/phrase_query.rs @@ -21,7 +21,7 @@ use Result; /// Using a `PhraseQuery` on a field requires positions /// to be indexed for this field. /// -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct PhraseQuery { field: Field, phrase_terms: Vec, @@ -47,6 +47,14 @@ impl PhraseQuery { phrase_terms: terms, } } + + pub fn field(&self) -> Field { + self.field + } + + pub fn phrase_terms(&self) -> &[Term] { + &self.phrase_terms[..] + } } impl Query for PhraseQuery { diff --git a/src/query/query.rs b/src/query/query.rs index d59d158f2..a9f3077bb 100644 --- a/src/query/query.rs +++ b/src/query/query.rs @@ -1,6 +1,7 @@ use super::Weight; use collector::Collector; use core::searcher::Searcher; +use downcast; use std::fmt; use Result; use SegmentLocalId; @@ -38,7 +39,7 @@ use SegmentLocalId; /// /// When implementing a new type of `Query`, it is normal to implement a /// dedicated `Query`, `Weight` and `Scorer`. -pub trait Query: fmt::Debug { +pub trait Query: QueryClone + downcast::Any + fmt::Debug { /// Create the weight associated to a query. /// /// If scoring is not required, setting `scoring_enabled` to `false` @@ -77,3 +78,20 @@ pub trait Query: fmt::Debug { Ok(()) } } + +pub trait QueryClone { + fn box_clone(&self) -> Box; +} + +impl QueryClone for T +where T: 'static + Query + Clone +{ + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + +#[allow(missing_docs)] +mod downcast_impl { + downcast!(super::Query); +} \ No newline at end of file diff --git a/src/query/range_query.rs b/src/query/range_query.rs index f875acd86..96f29fe35 100644 --- a/src/query/range_query.rs +++ b/src/query/range_query.rs @@ -80,7 +80,7 @@ fn map_bound Vec>( /// # run().unwrap() /// # } /// ``` -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct RangeQuery { field: Field, value_type: Type, diff --git a/src/query/term_query/term_query.rs b/src/query/term_query/term_query.rs index 854263fd1..82308b7d6 100644 --- a/src/query/term_query/term_query.rs +++ b/src/query/term_query/term_query.rs @@ -16,7 +16,7 @@ use Term; /// * `idf` - inverse document frequency. /// * `term_freq` - number of occurrences of the term in the field /// * `field norm` - number of tokens in the field. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct TermQuery { term: Term, index_record_option: IndexRecordOption, @@ -31,6 +31,10 @@ impl TermQuery { } } + pub fn term(&self) -> &Term { + &self.term + } + /// Returns a weight object. /// /// While `.weight(...)` returns a boxed trait object,