@@ -2,7 +2,7 @@ use crate::parsing::*;
2
2
use convert_case:: { Case , Casing } ;
3
3
use proc_macro_crate:: FoundCrate ;
4
4
use proc_macro2:: TokenStream as TokenStream2 ;
5
- use quote:: { format_ident, quote} ;
5
+ use quote:: { format_ident, quote, quote_spanned } ;
6
6
use std:: sync:: atomic:: AtomicU64 ;
7
7
use syn:: punctuated:: Punctuated ;
8
8
use syn:: spanned:: Spanned ;
@@ -193,14 +193,14 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
193
193
let name = & pat_ident. ident ;
194
194
let mut tokens = quote ! ( ) ;
195
195
if let Some ( min) = number_hard_min {
196
- tokens. extend ( quote ! {
197
- let #name = #graphene_core:: num_traits :: clamp_min ( #name, #graphene_core :: num_traits :: FromPrimitive :: from_f64 ( # min) . unwrap ( ) ) ;
196
+ tokens. extend ( quote_spanned ! { min . span ( ) =>
197
+ let #name = #graphene_core:: misc :: Clampable :: clamp_hard_min ( #name, #min) ;
198
198
} ) ;
199
199
}
200
200
201
201
if let Some ( max) = number_hard_max {
202
- tokens. extend ( quote ! {
203
- let #name = #graphene_core:: num_traits :: clamp_max ( #name, #graphene_core :: num_traits :: FromPrimitive :: from_f64 ( # max) . unwrap ( ) ) ;
202
+ tokens. extend ( quote_spanned ! { max . span ( ) =>
203
+ let #name = #graphene_core:: misc :: Clampable :: clamp_hard_max ( #name, #max) ;
204
204
} ) ;
205
205
}
206
206
tokens
@@ -221,13 +221,27 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
221
221
222
222
let input_type = & parsed. input . ty ;
223
223
let mut clauses = Vec :: new ( ) ;
224
+ let mut clampable_clauses = Vec :: new ( ) ;
225
+
224
226
for ( field, name) in fields. iter ( ) . zip ( struct_generics. iter ( ) ) {
225
227
clauses. push ( match ( field, * is_async) {
226
- ( ParsedField :: Regular { ty, .. } , _) => {
228
+ (
229
+ ParsedField :: Regular {
230
+ ty, number_hard_min, number_hard_max, ..
231
+ } ,
232
+ _,
233
+ ) => {
227
234
let all_lifetime_ty = substitute_lifetimes ( ty. clone ( ) , "all" ) ;
228
235
let id = future_idents. len ( ) ;
229
236
let fut_ident = format_ident ! ( "F{}" , id) ;
230
237
future_idents. push ( fut_ident. clone ( ) ) ;
238
+
239
+ // Add Clampable bound if this field uses hard_min or hard_max
240
+ if number_hard_min. is_some ( ) || number_hard_max. is_some ( ) {
241
+ // The bound applies to the Output type of the future, which is #ty
242
+ clampable_clauses. push ( quote ! ( #ty: #graphene_core:: misc:: Clampable ) ) ;
243
+ }
244
+
231
245
quote ! (
232
246
#fut_ident: core:: future:: Future <Output = #ty> + #graphene_core:: WasmNotSend + ' n,
233
247
for <' all> #all_lifetime_ty: #graphene_core:: WasmNotSend ,
@@ -255,6 +269,7 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
255
269
let mut struct_where_clause = where_clause. clone ( ) ;
256
270
let extra_where: Punctuated < WherePredicate , Comma > = parse_quote ! (
257
271
#( #clauses, ) *
272
+ #( #clampable_clauses, ) *
258
273
#output_type: ' n,
259
274
) ;
260
275
struct_where_clause. predicates . extend ( extra_where) ;
@@ -271,6 +286,8 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
271
286
#[ inline]
272
287
fn eval( & ' n self , __input: #input_type) -> Self :: Output {
273
288
Box :: pin( async move {
289
+ use #graphene_core:: misc:: Clampable ;
290
+
274
291
#( #eval_args) *
275
292
#( #min_max_args) *
276
293
self :: #fn_name( __input #( , #field_names) * ) #await_keyword
0 commit comments