1
1
use once_cell:: sync:: Lazy ;
2
2
use regex:: Regex ;
3
+ use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
3
4
4
5
use super :: grammar:: { unescape, DEFAULT_FIELD } ;
5
6
6
7
/// This enum represents value comparisons that Queries might perform
7
- #[ derive( Debug , Copy , Clone ) ]
8
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
8
9
pub enum Comparison {
9
10
/// Greater than.
10
11
Gt ,
@@ -31,7 +32,7 @@ impl Comparison {
31
32
/// This enum represents the values we might be using in a comparison, whether
32
33
/// they are Strings, Numbers (currently only floating point numbers) or an
33
34
/// Unbounded comparison with no terminating value.
34
- #[ derive( Debug , Clone ) ]
35
+ #[ derive( Clone , Debug , PartialEq ) ]
35
36
pub enum ComparisonValue {
36
37
Unbounded ,
37
38
String ( String ) ,
@@ -80,14 +81,14 @@ impl<T: AsRef<str>> From<T> for ComparisonValue {
80
81
81
82
/// This enum represents the tokens in a range, including "greater than (or equal to)"
82
83
/// for the left bracket, "less than (or equal to) in the right bracket, and range values.
83
- #[ derive( Debug , Clone ) ]
84
+ #[ derive( Clone , Debug , PartialEq ) ]
84
85
pub enum Range {
85
86
Comparison ( Comparison ) ,
86
87
Value ( ComparisonValue ) ,
87
88
}
88
89
89
90
/// This enum represents the AND or OR Boolean operations we might perform on QueryNodes.
90
- #[ derive( Debug , Copy , Clone ) ]
91
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
91
92
pub enum BooleanType {
92
93
And ,
93
94
Or ,
@@ -133,7 +134,7 @@ impl BooleanBuilder {
133
134
}
134
135
135
136
/// QueryNodes represent specific search criteria to be enforced.
136
- #[ derive( Debug , Clone ) ]
137
+ #[ derive( Clone , Debug , PartialEq ) ]
137
138
pub enum QueryNode {
138
139
/// Match all documents.
139
140
MatchAllDocs ,
@@ -344,6 +345,29 @@ impl QueryNode {
344
345
}
345
346
}
346
347
348
+ impl < ' de > Deserialize < ' de > for QueryNode {
349
+ fn deserialize < D > ( deserializer : D ) -> Result < QueryNode , D :: Error >
350
+ where
351
+ D : Deserializer < ' de > ,
352
+ {
353
+ use serde:: de:: Error ;
354
+
355
+ let s = String :: deserialize ( deserializer) ?;
356
+
357
+ s. parse :: < QueryNode > ( )
358
+ . map_err ( |e| D :: Error :: custom ( e. to_string ( ) ) )
359
+ }
360
+ }
361
+
362
+ impl Serialize for QueryNode {
363
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
364
+ where
365
+ S : Serializer ,
366
+ {
367
+ serializer. serialize_str ( self . to_lucene ( ) . as_str ( ) )
368
+ }
369
+ }
370
+
347
371
/// Enum representing Lucene's concept of whether a node should occur.
348
372
#[ derive( Debug ) ]
349
373
pub enum LuceneOccur {
@@ -364,3 +388,29 @@ static ESCAPE_RE: Lazy<Regex> = Lazy::new(|| Regex::new("^\"(.+)\"$").unwrap());
364
388
fn escape_quotes < T : AsRef < str > > ( value : T ) -> String {
365
389
ESCAPE_RE . replace_all ( value. as_ref ( ) , "$1" ) . to_string ( )
366
390
}
391
+
392
+ #[ cfg( test) ]
393
+ mod tests {
394
+ use super :: * ;
395
+
396
+ #[ test]
397
+ fn query_node_serializes_to_string ( ) {
398
+ assert_eq ! (
399
+ serde_json:: to_string( & QueryNode :: AttributeExists {
400
+ attr: "something" . into( )
401
+ } )
402
+ . unwrap( ) ,
403
+ r#""_exists_:something""#
404
+ ) ;
405
+ }
406
+
407
+ #[ test]
408
+ fn query_node_deserializes_from_string ( ) {
409
+ assert_eq ! (
410
+ serde_json:: from_str:: <QueryNode >( r#""_missing_:something_else""# ) . unwrap( ) ,
411
+ QueryNode :: AttributeMissing {
412
+ attr: "something_else" . into( )
413
+ }
414
+ ) ;
415
+ }
416
+ }
0 commit comments