@@ -5,6 +5,7 @@ use crate::context::context::Context;
55use crate :: context:: macros:: args;
66use crate :: context:: registry:: { HandlerFn , HandlerFunctionEntry , IntoFunctionEntry } ;
77use crate :: context:: signal:: Signal ;
8+ use crate :: runtime:: error:: RuntimeError ;
89use crate :: value:: value_from_i64;
910
1011pub fn collect_object_functions ( ) -> Vec < ( & ' static str , HandlerFunctionEntry ) > {
@@ -16,6 +17,7 @@ pub fn collect_object_functions() -> Vec<(&'static str, HandlerFunctionEntry)> {
1617 ( "std::object::keys" , HandlerFn :: eager( keys, 1 ) ) ,
1718 ( "std::object::size" , HandlerFn :: eager( size, 1 ) ) ,
1819 ( "std::object::set" , HandlerFn :: eager( set, 3 ) ) ,
20+ ( "std::object::get" , HandlerFn :: eager( get, 2 ) ) ,
1921 ]
2022}
2123
@@ -74,6 +76,22 @@ fn set(
7476 kind : Some ( Kind :: StructValue ( new_object) ) ,
7577 } )
7678}
79+
80+ fn get (
81+ args : & [ Argument ] ,
82+ _ctx : & mut Context ,
83+ _run : & mut dyn FnMut ( i64 , & mut Context ) -> Signal ,
84+ ) -> Signal {
85+ args ! ( args => object: Struct , key: String ) ;
86+ match object. fields . get ( & key) {
87+ Some ( v) => Signal :: Success ( v. clone ( ) ) ,
88+ None => Signal :: Failure ( RuntimeError :: simple (
89+ "FieldNotPresent" ,
90+ format ! ( "field {} not present" , key) ,
91+ ) ) ,
92+ }
93+ }
94+
7795#[ cfg( test) ]
7896mod tests {
7997 use super :: * ;
@@ -410,4 +428,94 @@ mod tests {
410428 assert_eq ! ( orig_clone. fields. len( ) , original_len) ;
411429 assert ! ( !orig_clone. fields. contains_key( "new_key" ) ) ;
412430 }
431+
432+ #[ test]
433+ fn test_get_success_string_field ( ) {
434+ let mut ctx = Context :: default ( ) ;
435+ let mut run = dummy_run;
436+ let args = vec ! [ a_struct( s_test( ) ) , a_string( "name" ) ] ;
437+
438+ let signal = get ( & args, & mut ctx, & mut run) ;
439+ let v = match signal {
440+ Signal :: Success ( v) => v,
441+ s => panic ! ( "Expected Success, got {:?}" , s) ,
442+ } ;
443+
444+ match v. kind {
445+ Some ( Kind :: StringValue ( s) ) => assert_eq ! ( s, "John" ) ,
446+ _ => panic ! ( "Expected StringValue" ) ,
447+ }
448+ }
449+
450+ #[ test]
451+ fn test_get_success_nested_struct_field ( ) {
452+ let mut ctx = Context :: default ( ) ;
453+ let nested = {
454+ let mut nf = HashMap :: new ( ) ;
455+ nf. insert ( "street" . to_string ( ) , v_string ( "123 Main St" ) ) ;
456+ v_struct ( nf)
457+ } ;
458+ let object = s_from ( vec ! [ ( "address" , nested) ] ) ;
459+ let mut run = dummy_run;
460+ let args = vec ! [ a_struct( object) , a_string( "address" ) ] ;
461+
462+ let signal = get ( & args, & mut ctx, & mut run) ;
463+ let v = match signal {
464+ Signal :: Success ( v) => v,
465+ s => panic ! ( "Expected Success, got {:?}" , s) ,
466+ } ;
467+
468+ match v. kind {
469+ Some ( Kind :: StructValue ( st) ) => {
470+ match st. fields . get ( "street" ) {
471+ Some ( Value {
472+ kind : Some ( Kind :: StringValue ( s) ) ,
473+ ..
474+ } ) => assert_eq ! ( s, "123 Main St" ) ,
475+ _ => panic ! ( "Expected nested 'street' string" ) ,
476+ }
477+ }
478+ _ => panic ! ( "Expected StructValue" ) ,
479+ }
480+ }
481+
482+ #[ test]
483+ fn test_get_missing_field_returns_field_not_present ( ) {
484+ let mut ctx = Context :: default ( ) ;
485+ let mut run = dummy_run;
486+ let args = vec ! [ a_struct( s_test( ) ) , a_string( "email" ) ] ;
487+
488+ let signal = get ( & args, & mut ctx, & mut run) ;
489+ let err = match signal {
490+ Signal :: Failure ( err) => err,
491+ s => panic ! ( "Expected Failure, got {:?}" , s) ,
492+ } ;
493+
494+ assert_eq ! ( err. name, "FieldNotPresent" ) ;
495+ assert_eq ! ( err. message, "field email not present" ) ;
496+ }
497+
498+ #[ test]
499+ fn test_collect_object_functions_registers_get_handler ( ) {
500+ let mut ctx = Context :: default ( ) ;
501+ let mut run = dummy_run;
502+ let args = vec ! [ a_struct( s_test( ) ) , a_string( "age" ) ] ;
503+
504+ let entry = collect_object_functions ( )
505+ . into_iter ( )
506+ . find ( |( id, _) | * id == "std::object::get" )
507+ . map ( |( _, entry) | entry)
508+ . expect ( "std::object::get should be registered" ) ;
509+
510+ let signal = ( entry. handler ) ( & args, & mut ctx, & mut run) ;
511+ let v = match signal {
512+ Signal :: Success ( v) => v,
513+ s => panic ! ( "Expected Success, got {:?}" , s) ,
514+ } ;
515+
516+ match v. kind {
517+ Some ( Kind :: NumberValue ( n) ) => assert_eq ! ( number_to_f64( & n) . unwrap_or_default( ) , 30.0 ) ,
518+ _ => panic ! ( "Expected NumberValue" ) ,
519+ }
520+ }
413521}
0 commit comments