1
+ use std:: path:: Path ;
2
+
1
3
use convert_case:: { Case , Casing } ;
2
4
use proc_macro2:: TokenStream ;
3
5
use quote:: format_ident;
@@ -39,31 +41,43 @@ impl Operator {
39
41
40
42
fn gen_helper ( & self ) -> TokenStream {
41
43
let name_text = & self . name ;
42
- let name_ident = format_ident ! ( "{}" , name_text. to_case( Case :: Pascal ) ) ;
43
- let constr_ident = format_ident ! ( "{}" , name_text. to_case( Case :: Snake ) ) ;
44
+ let ident_base = match name_text. as_str ( ) {
45
+ "in" => "searchIn" ,
46
+ _ => name_text,
47
+ } ;
48
+ let name_ident = format_ident ! ( "{}" , ident_base. to_case( Case :: Pascal ) ) ;
49
+ let constr_ident = format_ident ! ( "{}" , ident_base. to_case( Case :: Snake ) ) ;
44
50
45
51
let mut required_args = TokenStream :: new ( ) ;
52
+ let mut required_arg_names = TokenStream :: new ( ) ;
46
53
let mut init_doc = TokenStream :: new ( ) ;
47
54
let mut setters = TokenStream :: new ( ) ;
48
55
49
56
for arg in & self . arguments {
50
- let ident = format_ident ! ( "{}" , arg. name. to_case( Case :: Snake ) ) ;
51
- let rust_type = arg. rust_type ( ) ;
57
+ let ident = format_ident ! (
58
+ "{}" ,
59
+ match arg. name. as_str( ) {
60
+ // `box` is a reserved word
61
+ "box" => "geo_box" . to_owned( ) ,
62
+ _ => arg. name. to_case( Case :: Snake ) ,
63
+ }
64
+ ) ;
65
+ let rust_type = arg. rust_type ( & self . name ) ;
52
66
let type_ = rust_type. tokens ( ) ;
53
67
let arg_name = & arg. name ;
54
68
let init_expr = rust_type. bson_expr ( & ident) ;
55
69
56
70
if arg. optional . unwrap_or ( false ) {
57
- let tvars = rust_type. variables ( ) ;
58
71
setters. push ( parse_quote ! {
59
72
#[ allow( missing_docs) ]
60
- pub fn #ident<#tvars> ( mut self , #ident: #type_) -> Self {
61
- self . stage . insert( #arg_name, #init_expr) ;
73
+ pub fn #ident( mut self , #ident: #type_) -> Self {
74
+ self . spec . insert( #arg_name, #init_expr) ;
62
75
self
63
76
}
64
77
} ) ;
65
78
} else {
66
79
required_args. push ( parse_quote ! { #ident : #type_, } ) ;
80
+ required_arg_names. push ( parse_quote ! { #ident, } ) ;
67
81
init_doc. push ( parse_quote ! { #arg_name : #init_expr, } ) ;
68
82
}
69
83
}
@@ -73,21 +87,27 @@ impl Operator {
73
87
"For more details, see the [{name_text} operator reference]({})." ,
74
88
self . link
75
89
) ;
90
+ let struct_doc = format ! (
91
+ "`{name_text}` Atlas Search operator. Construct with \
92
+ [`{constr_ident}`]({constr_ident}())."
93
+ ) ;
76
94
parse_quote ! {
77
- #[ allow ( missing_docs ) ]
95
+ #[ doc = #struct_doc ]
78
96
pub struct #name_ident;
79
97
80
- impl AtlasSearch <#name_ident> {
81
- #[ doc = #desc]
82
- #[ doc = "" ]
83
- #[ doc = #link]
84
- pub fn #constr_ident( #required_args) -> Self {
85
- AtlasSearch {
86
- name: #name_text,
87
- stage: doc! { #init_doc } ,
88
- _t: PhantomData ,
89
- }
90
- }
98
+ #[ doc = #desc]
99
+ #[ doc = "" ]
100
+ #[ doc = #link]
101
+ #[ options_doc( #constr_ident, "into_stage" ) ]
102
+ pub fn #constr_ident( #required_args) -> SearchOperator <#name_ident> {
103
+ SearchOperator :: new(
104
+ #name_text,
105
+ doc! { #init_doc } ,
106
+ )
107
+ }
108
+
109
+ #[ export_doc( #constr_ident) ]
110
+ impl SearchOperator <#name_ident> {
91
111
#setters
92
112
}
93
113
}
@@ -107,80 +127,114 @@ struct Argument {
107
127
#[ derive( Debug , Deserialize ) ]
108
128
#[ serde( rename_all = "camelCase" ) ]
109
129
enum ArgumentType {
110
- String ,
111
- Object ,
112
- SearchScore ,
113
- SearchPath ,
114
- SearchOperator ,
130
+ Any ,
115
131
Array ,
132
+ BinData ,
133
+ Bool ,
134
+ Date ,
135
+ Geometry ,
116
136
Int ,
137
+ Null ,
138
+ Number ,
139
+ Object ,
140
+ ObjectId ,
141
+ SearchOperator ,
142
+ SearchPath ,
143
+ SearchScore ,
144
+ String ,
117
145
}
118
146
119
- static QUERY : & str = "query" ;
120
- static TOKEN_ORDER : & str = "tokenOrder" ;
121
- static MATCH_CRITERIA : & str = "matchCriteria" ;
122
-
123
147
impl Argument {
124
- fn rust_type ( & self ) -> ArgumentRustType {
125
- if self . name == QUERY {
126
- return ArgumentRustType :: StringOrArray ;
127
- }
128
- if self . name == TOKEN_ORDER {
129
- return ArgumentRustType :: TokenOrder ;
130
- }
131
- if self . name == MATCH_CRITERIA {
132
- return ArgumentRustType :: MatchCriteria ;
148
+ fn rust_type ( & self , operator : & str ) -> ArgumentRustType {
149
+ match ( operator, self . name . as_str ( ) ) {
150
+ ( "autocomplete" | "text" , "query" ) => return ArgumentRustType :: StringOrArray ,
151
+ ( "autocomplete" , "tokenOrder" ) => return ArgumentRustType :: TokenOrder ,
152
+ ( "text" , "matchCriteria" ) => return ArgumentRustType :: MatchCriteria ,
153
+ ( "equals" , "value" ) => return ArgumentRustType :: IntoBson ,
154
+ ( "geoShape" , "relation" ) => return ArgumentRustType :: Relation ,
155
+ ( "range" , "gt" | "gte" | "lt" | "lte" ) => return ArgumentRustType :: RangeValue ,
156
+ ( "near" , "origin" ) => return ArgumentRustType :: NearOrigin ,
157
+ _ => ( ) ,
133
158
}
159
+ use ArgumentType :: * ;
134
160
match self . type_ . as_slice ( ) {
135
- [ ArgumentType :: String ] => ArgumentRustType :: String ,
136
- [ ArgumentType :: Object ] => ArgumentRustType :: Document ,
137
- [ ArgumentType :: SearchScore ] => ArgumentRustType :: Document ,
138
- [ ArgumentType :: SearchPath ] => ArgumentRustType :: StringOrArray ,
139
- [ ArgumentType :: SearchOperator , ArgumentType :: Array ] => ArgumentRustType :: Operator ,
140
- [ ArgumentType :: Int ] => ArgumentRustType :: I32 ,
161
+ [ String ] => ArgumentRustType :: String ,
162
+ [ Object ] => ArgumentRustType :: Document ,
163
+ [ SearchScore ] => ArgumentRustType :: Document ,
164
+ [ SearchPath ] => ArgumentRustType :: StringOrArray ,
165
+ [ SearchOperator ] => ArgumentRustType :: SearchOperator ,
166
+ [ SearchOperator , Array ] => ArgumentRustType :: SeachOperatorIter ,
167
+ [ Int ] => ArgumentRustType :: I32 ,
168
+ [ Geometry ] => ArgumentRustType :: Document ,
169
+ [ Any , Array ] => ArgumentRustType :: IntoBson ,
170
+ [ Object , Array ] => ArgumentRustType :: DocumentOrArray ,
171
+ [ Number ] => ArgumentRustType :: BsonNumber ,
172
+ [ String , Array ] => ArgumentRustType :: StringOrArray ,
173
+ [ Bool ] => ArgumentRustType :: Bool ,
141
174
_ => panic ! ( "Unexpected argument types: {:?}" , self . type_) ,
142
175
}
143
176
}
144
177
}
145
178
146
179
enum ArgumentRustType {
147
- String ,
180
+ Bool ,
181
+ BsonNumber ,
148
182
Document ,
183
+ DocumentOrArray ,
184
+ I32 ,
185
+ IntoBson ,
186
+ MatchCriteria ,
187
+ NearOrigin ,
188
+ RangeValue ,
189
+ Relation ,
190
+ SearchOperator ,
191
+ SeachOperatorIter ,
192
+ String ,
149
193
StringOrArray ,
150
194
TokenOrder ,
151
- MatchCriteria ,
152
- Operator ,
153
- I32 ,
154
195
}
155
196
156
197
impl ArgumentRustType {
157
198
fn tokens ( & self ) -> syn:: Type {
158
199
match self {
159
- Self :: String => parse_quote ! { impl AsRef <str > } ,
200
+ Self :: Bool => parse_quote ! { bool } ,
201
+ Self :: BsonNumber => parse_quote ! { impl BsonNumber } ,
160
202
Self :: Document => parse_quote ! { Document } ,
203
+ Self :: DocumentOrArray => parse_quote ! { impl DocumentOrArray } ,
204
+ Self :: I32 => parse_quote ! { i32 } ,
205
+ Self :: IntoBson => parse_quote ! { impl Into <Bson > } ,
206
+ Self :: MatchCriteria => parse_quote ! { MatchCriteria } ,
207
+ Self :: NearOrigin => parse_quote ! { impl NearOrigin } ,
208
+ Self :: RangeValue => parse_quote ! { impl RangeValue } ,
209
+ Self :: Relation => parse_quote ! { Relation } ,
210
+ Self :: SearchOperator => parse_quote ! { impl SearchOperatorParam } ,
211
+ Self :: SeachOperatorIter => {
212
+ parse_quote ! { impl IntoIterator <Item = impl SearchOperatorParam > }
213
+ }
214
+ Self :: String => parse_quote ! { impl AsRef <str > } ,
161
215
Self :: StringOrArray => parse_quote ! { impl StringOrArray } ,
162
216
Self :: TokenOrder => parse_quote ! { TokenOrder } ,
163
- Self :: MatchCriteria => parse_quote ! { MatchCriteria } ,
164
- Self :: Operator => parse_quote ! { impl IntoIterator <Item = AtlasSearch <T >> } ,
165
- Self :: I32 => parse_quote ! { i32 } ,
166
- }
167
- }
168
-
169
- fn variables ( & self ) -> TokenStream {
170
- match self {
171
- Self :: Operator => parse_quote ! { T } ,
172
- _ => parse_quote ! { } ,
173
217
}
174
218
}
175
219
176
220
fn bson_expr ( & self , ident : & syn:: Ident ) -> syn:: Expr {
177
221
match self {
222
+ Self :: Document | Self :: I32 | Self :: Bool => parse_quote ! { #ident } ,
223
+ Self :: IntoBson => parse_quote ! { #ident. into( ) } ,
224
+ Self :: SeachOperatorIter => {
225
+ parse_quote ! { #ident. into_iter( ) . map( |o| o. to_bson( ) ) . collect:: <Vec <_>>( ) }
226
+ }
178
227
Self :: String => parse_quote ! { #ident. as_ref( ) } ,
179
- Self :: StringOrArray => parse_quote ! { #ident. to_bson( ) } ,
180
- Self :: TokenOrder | Self :: MatchCriteria => parse_quote ! { #ident. name( ) } ,
181
- Self :: Document | Self :: I32 => parse_quote ! { #ident } ,
182
- Self :: Operator => {
183
- parse_quote ! { #ident. into_iter( ) . map( Document :: from) . collect:: <Vec <_>>( ) }
228
+ Self :: StringOrArray
229
+ | Self :: DocumentOrArray
230
+ | Self :: SearchOperator
231
+ | Self :: NearOrigin
232
+ | Self :: RangeValue
233
+ | Self :: BsonNumber => {
234
+ parse_quote ! { #ident. to_bson( ) }
235
+ }
236
+ Self :: TokenOrder | Self :: MatchCriteria | Self :: Relation => {
237
+ parse_quote ! { #ident. name( ) }
184
238
}
185
239
}
186
240
}
@@ -200,11 +254,14 @@ impl TokenStreamExt for TokenStream {
200
254
201
255
fn main ( ) {
202
256
let mut operators = TokenStream :: new ( ) ;
203
- for path in [
204
- "yaml/search/autocomplete.yaml" ,
205
- "yaml/search/text.yaml" ,
206
- "yaml/search/compound.yaml" ,
207
- ] {
257
+ let mut paths = Path :: new ( "yaml/search" )
258
+ . read_dir ( )
259
+ . unwrap ( )
260
+ . map ( |e| e. unwrap ( ) . path ( ) )
261
+ . filter ( |p| p. extension ( ) . is_some_and ( |e| e == "yaml" ) )
262
+ . collect :: < Vec < _ > > ( ) ;
263
+ paths. sort ( ) ;
264
+ for path in paths {
208
265
let contents = std:: fs:: read_to_string ( path) . unwrap ( ) ;
209
266
let parsed = serde_yaml:: from_str :: < Operator > ( & contents)
210
267
. unwrap ( )
@@ -215,6 +272,7 @@ fn main() {
215
272
let file = parse_quote ! {
216
273
//! This file was autogenerated. Do not manually edit.
217
274
use super :: * ;
275
+ use mongodb_internal_macros:: { export_doc, options_doc} ;
218
276
219
277
#operators
220
278
} ;
0 commit comments