@@ -15,12 +15,19 @@ use crate::tools::SchemaDict;
15
15
16
16
use super :: { BuildValidator , CombinedValidator , Definitions , DefinitionsBuilder , Extra , Validator } ;
17
17
18
+ #[ derive( Debug , Clone ) ]
19
+ struct BoolLiteral {
20
+ pub true_id : Option < usize > ,
21
+ pub false_id : Option < usize > ,
22
+ }
23
+
18
24
#[ derive( Debug , Clone ) ]
19
25
pub struct LiteralLookup < T : Clone + Debug > {
20
- // Specialized lookups for ints and strings because they
26
+ // Specialized lookups for ints, bools and strings because they
21
27
// (1) are easy to convert between Rust and Python
22
28
// (2) hashing them in Rust is very fast
23
29
// (3) are the most commonly used things in Literal[...]
30
+ expected_bool : Option < BoolLiteral > ,
24
31
expected_int : Option < AHashMap < i64 , usize > > ,
25
32
expected_str : Option < AHashMap < String , usize > > ,
26
33
// Catch all for Enum and bytes (the latter only because it is seldom used)
@@ -31,12 +38,23 @@ pub struct LiteralLookup<T: Clone + Debug> {
31
38
impl < T : Clone + Debug > LiteralLookup < T > {
32
39
pub fn new < ' py > ( py : Python < ' py > , expected : impl Iterator < Item = ( & ' py PyAny , T ) > ) -> PyResult < Self > {
33
40
let mut expected_int = AHashMap :: new ( ) ;
34
- let mut expected_str = AHashMap :: new ( ) ;
41
+ let mut expected_str: AHashMap < String , usize > = AHashMap :: new ( ) ;
42
+ let mut expected_bool = BoolLiteral {
43
+ true_id : None ,
44
+ false_id : None ,
45
+ } ;
35
46
let expected_py = PyDict :: new ( py) ;
36
47
let mut values = Vec :: new ( ) ;
37
48
for ( k, v) in expected {
38
49
let id = values. len ( ) ;
39
50
values. push ( v) ;
51
+ if let Ok ( bool) = k. strict_bool ( ) {
52
+ if bool {
53
+ expected_bool. true_id = Some ( id) ;
54
+ } else {
55
+ expected_bool. false_id = Some ( id) ;
56
+ }
57
+ }
40
58
if let Ok ( either_int) = k. exact_int ( ) {
41
59
let int = either_int
42
60
. into_i64 ( py)
@@ -53,6 +71,10 @@ impl<T: Clone + Debug> LiteralLookup<T> {
53
71
}
54
72
55
73
Ok ( Self {
74
+ expected_bool : match expected_bool. true_id . is_some ( ) || expected_bool. false_id . is_some ( ) {
75
+ true => Some ( expected_bool) ,
76
+ false => None ,
77
+ } ,
56
78
expected_int : match expected_int. is_empty ( ) {
57
79
true => None ,
58
80
false => Some ( expected_int) ,
@@ -74,7 +96,17 @@ impl<T: Clone + Debug> LiteralLookup<T> {
74
96
py : Python < ' data > ,
75
97
input : & ' data I ,
76
98
) -> ValResult < ' data , Option < ( & ' data I , & T ) > > {
77
- // dbg!(input.to_object(py).as_ref(py).repr().unwrap());
99
+ if let Some ( expected_bool) = & self . expected_bool {
100
+ if let Ok ( bool_value) = input. strict_bool ( ) {
101
+ if bool_value {
102
+ if let Some ( true_value) = & expected_bool. true_id {
103
+ return Ok ( Some ( ( input, & self . values [ * true_value] ) ) ) ;
104
+ }
105
+ } else if let Some ( false_value) = & expected_bool. false_id {
106
+ return Ok ( Some ( ( input, & self . values [ * false_value] ) ) ) ;
107
+ }
108
+ }
109
+ }
78
110
if let Some ( expected_ints) = & self . expected_int {
79
111
if let Ok ( either_int) = input. exact_int ( ) {
80
112
let int = either_int. into_i64 ( py) ?;
0 commit comments