@@ -102,6 +102,12 @@ pub enum Value {
102
102
pub enum Error {
103
103
#[ fail( display = "Javascript error: {:?}" , raw) ]
104
104
Js { raw : JsError } ,
105
+ #[ cfg( feature = "serde" ) ]
106
+ #[ fail( display = "Deserialization error: {:?}" , raw) ]
107
+ De { raw : de:: Error } ,
108
+ #[ cfg( feature = "serde" ) ]
109
+ #[ fail( display = "Serialization error: {:?}" , raw) ]
110
+ Ser { raw : ser:: Error } ,
105
111
}
106
112
107
113
pub type Result < A > = result:: Result < A , Error > ;
@@ -419,6 +425,12 @@ impl<'a> Reference<'a> {
419
425
self . with_value ( || unsafe { Value :: get ( self . ctx . raw , -1 ) } )
420
426
}
421
427
428
+ #[ cfg( feature = "serde" ) ]
429
+ pub fn to_deserialize < ' de , T : serde:: Deserialize < ' de > > ( & self ) -> Result < T > {
430
+ self . with_value ( || unsafe { deserialize_from_stack ( self . ctx . raw , -1 ) } )
431
+ . map_err ( |e| Error :: De { raw : e } )
432
+ }
433
+
422
434
/// Gets the property with the specified key, provided that this reference points to something
423
435
/// that is object coercible.
424
436
pub fn get ( & self , name : & str ) -> Result < Reference < ' a > > {
@@ -958,7 +970,7 @@ pub struct StackRAII {
958
970
idx : i32 ,
959
971
}
960
972
impl StackRAII {
961
- pub fn new ( ctx : * mut duk_sys:: duk_context ) -> Self {
973
+ pub unsafe fn new ( ctx : * mut duk_sys:: duk_context ) -> Self {
962
974
let mut res = StackRAII { ctx, idx : 0 } ;
963
975
res. checkpoint ( ) ;
964
976
res
@@ -1434,18 +1446,81 @@ mod tests {
1434
1446
assert_eq ! ( Value :: Number ( 3.0 ) , value) ;
1435
1447
}
1436
1448
1437
- #[ cfg_attr( feature = "derive" , duk_derive :: duktape_fn) ]
1449
+ #[ cfg_attr( feature = "derive" , duktape_fn) ]
1438
1450
fn test_rust_fn ( input : u8 ) -> String {
1439
1451
format ! ( "test {}" , input)
1440
1452
}
1441
1453
1454
+ #[ cfg_attr( feature = "derive" , duktape_fn) ]
1455
+ fn test_rust_complex_fn ( input : TestComplexStruct ) -> TestComplexStruct {
1456
+ println ! ( "{:?}" , input) ;
1457
+ input
1458
+ }
1459
+
1460
+ #[ derive( Debug , serde:: Deserialize , serde:: Serialize , PartialEq ) ]
1461
+ enum TestEnum {
1462
+ A ,
1463
+ }
1464
+
1465
+ #[ derive( Debug , serde:: Deserialize , serde:: Serialize , PartialEq ) ]
1466
+ enum TestComplexEnum {
1467
+ A ( i64 , i64 ) ,
1468
+ B { hello : String } ,
1469
+ }
1470
+
1471
+ #[ derive( Debug , serde:: Deserialize , serde:: Serialize , PartialEq ) ]
1472
+ struct TestComplexStruct {
1473
+ a : i64 ,
1474
+ b : String ,
1475
+ c : bool ,
1476
+ d : TestEnum ,
1477
+ e : TestComplexEnum ,
1478
+ f : TestComplexEnum ,
1479
+ g : std:: collections:: HashMap < String , String > ,
1480
+ }
1481
+
1442
1482
#[ test]
1443
1483
fn call_rs_from_js ( ) {
1444
1484
let ctx = Context :: new ( ) ;
1445
1485
1446
- let a = add_global_fn ! ( ctx, test_rust_fn) ;
1486
+ add_global_fn ! ( ctx, test_rust_fn) ;
1487
+ add_global_fn ! ( ctx, test_rust_complex_fn) ;
1447
1488
1448
1489
let val = ctx. eval_string ( r#"test_rust_fn(5.5)"# ) . unwrap ( ) . to_value ( ) ;
1449
1490
assert_eq ! ( Value :: String ( "test 5" . to_owned( ) ) , val) ;
1491
+
1492
+ let reference = ctx
1493
+ . eval_string (
1494
+ r#"test_rust_complex_fn({
1495
+ a: 0,
1496
+ b: "hello",
1497
+ c: true,
1498
+ d: "A",
1499
+ e: { "A": [0, 0] },
1500
+ f: { "B": { hello: "hello" }},
1501
+ g: { "a": "b", "c": "d" }
1502
+ })"# ,
1503
+ )
1504
+ . unwrap ( ) ;
1505
+ let val = reference. to_deserialize ( ) . unwrap ( ) ;
1506
+ assert_eq ! (
1507
+ TestComplexStruct {
1508
+ a: 0 ,
1509
+ b: "hello" . to_owned( ) ,
1510
+ c: true ,
1511
+ d: TestEnum :: A ,
1512
+ e: TestComplexEnum :: A ( 0 , 0 ) ,
1513
+ f: TestComplexEnum :: B {
1514
+ hello: "hello" . to_owned( ) ,
1515
+ } ,
1516
+ g: {
1517
+ let mut map = std:: collections:: HashMap :: new( ) ;
1518
+ map. insert( "a" . to_owned( ) , "b" . to_owned( ) ) ;
1519
+ map. insert( "c" . to_owned( ) , "d" . to_owned( ) ) ;
1520
+ map
1521
+ }
1522
+ } ,
1523
+ val
1524
+ ) ;
1450
1525
}
1451
1526
}
0 commit comments