Skip to content

Commit abb5be0

Browse files
committed
better test
1 parent 6d6114f commit abb5be0

File tree

3 files changed

+96
-10
lines changed

3 files changed

+96
-10
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ version = "1.0"
3333

3434
[dev-dependencies]
3535
env_logger = "0.7.1"
36+
serde = { version = "1.0", features = ["derive"] }
3637

3738
[features]
3839
debug = ["duk-sys/debug"]

src/de.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -351,12 +351,22 @@ impl<'de> Deserializer<'de> for DukDe {
351351
duk_sys::DUK_ENUM_OWN_PROPERTIES_ONLY,
352352
);
353353

354-
if duk_sys::duk_next(self.0.ctx, self.0.idx, 1) == 1 {
355-
seed.deserialize(DukDe {
356-
ctx: self.0.ctx,
357-
idx: duk_sys::duk_get_top(self.0.ctx) - 2,
358-
})
359-
.map(|v| (v, VariantAccessor(self.0)))
354+
if duk_sys::duk_next(self.0.ctx, -1, 1) == 1 {
355+
let res = seed
356+
.deserialize(DukDe {
357+
ctx: self.0.ctx,
358+
idx: duk_sys::duk_get_top(self.0.ctx) - 2,
359+
})
360+
.map(|v| {
361+
(
362+
v,
363+
VariantAccessor(DukDe {
364+
ctx: self.0.ctx,
365+
idx: duk_sys::duk_get_top(self.0.ctx) - 1,
366+
}),
367+
)
368+
});
369+
res
360370
} else {
361371
Err(serde::de::Error::invalid_value(
362372
serde::de::Unexpected::Map,
@@ -513,7 +523,7 @@ pub unsafe fn deserialize_from_stack<'de, T: serde::Deserialize<'de>>(
513523
index: i32,
514524
) -> Result<T, Error> {
515525
let _guard = crate::StackRAII::new(ctx);
516-
let top = duk_sys::duk_get_top(ctx) + index;
526+
let top = duk_sys::duk_get_top(ctx);
517527
let idx = if index >= top {
518528
return Err(serde::de::Error::custom("index out of bounds"));
519529
} else if index >= 0 {

src/lib.rs

+78-3
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ pub enum Value {
102102
pub enum Error {
103103
#[fail(display = "Javascript error: {:?}", raw)]
104104
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 },
105111
}
106112

107113
pub type Result<A> = result::Result<A, Error>;
@@ -419,6 +425,12 @@ impl<'a> Reference<'a> {
419425
self.with_value(|| unsafe { Value::get(self.ctx.raw, -1) })
420426
}
421427

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+
422434
/// Gets the property with the specified key, provided that this reference points to something
423435
/// that is object coercible.
424436
pub fn get(&self, name: &str) -> Result<Reference<'a>> {
@@ -958,7 +970,7 @@ pub struct StackRAII {
958970
idx: i32,
959971
}
960972
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 {
962974
let mut res = StackRAII { ctx, idx: 0 };
963975
res.checkpoint();
964976
res
@@ -1434,18 +1446,81 @@ mod tests {
14341446
assert_eq!(Value::Number(3.0), value);
14351447
}
14361448

1437-
#[cfg_attr(feature = "derive", duk_derive::duktape_fn)]
1449+
#[cfg_attr(feature = "derive", duktape_fn)]
14381450
fn test_rust_fn(input: u8) -> String {
14391451
format!("test {}", input)
14401452
}
14411453

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+
14421482
#[test]
14431483
fn call_rs_from_js() {
14441484
let ctx = Context::new();
14451485

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);
14471488

14481489
let val = ctx.eval_string(r#"test_rust_fn(5.5)"#).unwrap().to_value();
14491490
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+
);
14501525
}
14511526
}

0 commit comments

Comments
 (0)