feat(napi): From Serde JSON Error for Error

This commit is contained in:
LongYinan 2020-12-24 11:59:42 +08:00
parent 530359421c
commit 26a2c01cd6
No known key found for this signature in database
GPG key ID: A3FFE134A3E20881
3 changed files with 59 additions and 1 deletions

View file

@ -8,6 +8,8 @@ use std::os::raw::{c_char, c_void};
#[cfg(feature = "serde-json")] #[cfg(feature = "serde-json")]
use serde::{de, ser}; use serde::{de, ser};
#[cfg(feature = "serde-json")]
use serde_json::Error as SerdeJSONError;
use crate::{sys, Status}; use crate::{sys, Status};
@ -38,6 +40,13 @@ impl de::Error for Error {
} }
} }
#[cfg(feature = "serde-json")]
impl From<SerdeJSONError> for Error {
fn from(value: SerdeJSONError) -> Self {
Error::new(Status::InvalidArg, format!("{}", value))
}
}
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.reason.is_empty() { if !self.reason.is_empty() {

View file

@ -0,0 +1,28 @@
import test from 'ava'
const bindings = require('../../index.node')
const ValidObject = {
a: 1,
b: [-1.2, 1.1, 2.2, 3.3],
c: 'Hi',
}
const InValidObject = {
a: -1,
b: [-1, 1.1, 2.2, 3.3],
c: 'Hello',
}
test('should from json string', (t) => {
t.throws(() => bindings.from_json_string(JSON.stringify(InValidObject)))
t.deepEqual(
ValidObject,
bindings.from_json_string(JSON.stringify(ValidObject)),
)
})
test('should convert to json string', (t) => {
t.throws(() => bindings.json_to_string(InValidObject))
t.deepEqual(JSON.stringify(ValidObject), bindings.json_to_string(ValidObject))
})

View file

@ -1,4 +1,6 @@
use napi::{CallContext, JsObject, JsUndefined, JsUnknown, Result}; use napi::{CallContext, JsObject, JsString, JsUndefined, JsUnknown, Result};
use serde_json::{from_str, to_string};
#[derive(Serialize, Debug, Deserialize)] #[derive(Serialize, Debug, Deserialize)]
struct AnObject { struct AnObject {
@ -162,6 +164,23 @@ fn roundtrip_object(ctx: CallContext) -> Result<JsUnknown> {
ctx.env.to_js_value(&de_serialized) ctx.env.to_js_value(&de_serialized)
} }
#[js_function(1)]
fn from_json_string(ctx: CallContext) -> Result<JsUnknown> {
let arg0 = ctx.get::<JsString>(0)?.into_utf8()?;
let de_serialized: AnObject = from_str(arg0.as_str()?)?;
ctx.env.to_js_value(&de_serialized)
}
#[js_function(1)]
fn json_to_string(ctx: CallContext) -> Result<JsString> {
let arg0 = ctx.get::<JsObject>(0)?;
let de_serialized: AnObject = ctx.env.from_js_value(arg0)?;
let json_string = to_string(&de_serialized)?;
ctx.env.create_string_from_std(json_string)
}
pub fn register_js(exports: &mut JsObject) -> Result<()> { pub fn register_js(exports: &mut JsObject) -> Result<()> {
exports.create_named_method("make_num_77", make_num_77)?; exports.create_named_method("make_num_77", make_num_77)?;
exports.create_named_method("make_num_32", make_num_32)?; exports.create_named_method("make_num_32", make_num_32)?;
@ -178,5 +197,7 @@ pub fn register_js(exports: &mut JsObject) -> Result<()> {
exports.create_named_method("expect_buffer", expect_buffer)?; exports.create_named_method("expect_buffer", expect_buffer)?;
exports.create_named_method("roundtrip_object", roundtrip_object)?; exports.create_named_method("roundtrip_object", roundtrip_object)?;
exports.create_named_method("from_json_string", from_json_string)?;
exports.create_named_method("json_to_string", json_to_string)?;
Ok(()) Ok(())
} }