@@ -1220,9 +1220,9 @@ fn render_callable_consts(callables: &[&CallableDecl]) -> String {
12201220 for param in & callable. params {
12211221 writeln ! (
12221222 & mut out,
1223- " CallableParam {{ name: {:?}, ty: CallableParamType:: {}, optional: {} }}," ,
1223+ " CallableParam {{ name: {:?}, ty: {}, optional: {} }}," ,
12241224 param. name,
1225- callable_param_variant ( & param. ty_label) ,
1225+ callable_param_expr ( & param. ty_label) ,
12261226 param. optional
12271227 )
12281228 . unwrap ( ) ;
@@ -1645,20 +1645,39 @@ fn callable_const_base(callable: &CallableDecl) -> String {
16451645 to_shouty_snake ( & format ! ( "{prefix}_{}" , callable. rust_ident) )
16461646}
16471647
1648- fn callable_param_variant ( label : & str ) -> & ' static str {
1649- let label = label. strip_suffix ( " | null" ) . unwrap_or ( label) ;
1648+ pub ( crate ) fn callable_param_expr ( label : & str ) -> String {
16501649 match label {
1651- "any" => "Any" ,
1652- "null" => "Null" ,
1653- "int" => "Int" ,
1654- "float" => "Float" ,
1655- "bool" => "Bool" ,
1656- "string" => "String" ,
1657- "bytes" => "Bytes" ,
1658- "array" => "Array" ,
1659- "map" => "Map" ,
1660- "number" => "Number" ,
1661- "resource" => "Resource" ,
1650+ "any" => "CallableParamType::Any" . to_string ( ) ,
1651+ "null" => "CallableParamType::Null" . to_string ( ) ,
1652+ "int" => "CallableParamType::Int" . to_string ( ) ,
1653+ "float" => "CallableParamType::Float" . to_string ( ) ,
1654+ "bool" => "CallableParamType::Bool" . to_string ( ) ,
1655+ "string" => "CallableParamType::String" . to_string ( ) ,
1656+ "bytes" => "CallableParamType::Bytes" . to_string ( ) ,
1657+ "array" => "CallableParamType::Array" . to_string ( ) ,
1658+ "map" => "CallableParamType::Map" . to_string ( ) ,
1659+ "number" => "CallableParamType::Number" . to_string ( ) ,
1660+ "resource" => "CallableParamType::Resource" . to_string ( ) ,
1661+ other if other. starts_with ( "fn(" ) => {
1662+ let ( params, result) = other
1663+ . strip_prefix ( "fn(" )
1664+ . and_then ( |value| value. split_once ( ") -> " ) )
1665+ . unwrap_or_else ( || panic ! ( "invalid callable schema '{other}'" ) ) ;
1666+ let params = if params. is_empty ( ) {
1667+ Vec :: new ( )
1668+ } else {
1669+ params
1670+ . split ( ", " )
1671+ . map ( callable_param_expr)
1672+ . collect :: < Vec < _ > > ( )
1673+ } ;
1674+ let result = callable_param_expr ( result) ;
1675+ format ! (
1676+ "CallableParamType::Callable(CallableType {{ params: &[{}], return_type: &{} }})" ,
1677+ params. join( ", " ) ,
1678+ result
1679+ )
1680+ }
16621681 other => panic ! ( "unsupported callable param type '{other}'" ) ,
16631682 }
16641683}
@@ -2280,3 +2299,32 @@ mod tests {
22802299 }
22812300 }
22822301}
2302+
2303+ #[ cfg( test) ]
2304+ mod callable_schema_tests {
2305+ use super :: * ;
2306+ use syn:: parse_quote;
2307+
2308+ #[ test]
2309+ fn build_metadata_renders_typed_callable_parameters ( ) {
2310+ let ty: Type = parse_quote ! ( VmCallable <fn ( VmMap ) -> VmMap >) ;
2311+ assert_eq ! (
2312+ pd_host_schema:: type_label( & ty) . expect( "callable type should parse" ) ,
2313+ "fn(map) -> map"
2314+ ) ;
2315+ assert_eq ! (
2316+ callable_param_expr( "fn(map) -> map" ) ,
2317+ "CallableParamType::Callable(CallableType { params: &[CallableParamType::Map], return_type: &CallableParamType::Map })"
2318+ ) ;
2319+
2320+ let float_ty: Type = parse_quote ! ( VmCallable <fn ( f64 ) -> f64 >) ;
2321+ assert_eq ! (
2322+ pd_host_schema:: type_label( & float_ty) . expect( "callable type should parse" ) ,
2323+ "fn(float) -> float"
2324+ ) ;
2325+ assert_eq ! (
2326+ callable_param_expr( "fn(float) -> float" ) ,
2327+ "CallableParamType::Callable(CallableType { params: &[CallableParamType::Float], return_type: &CallableParamType::Float })"
2328+ ) ;
2329+ }
2330+ }
0 commit comments