Use std type conversion traits
This commit is contained in:
parent
79d72c1158
commit
7e247356c7
1 changed files with 74 additions and 56 deletions
130
src/lib.rs
130
src/lib.rs
|
@ -8,14 +8,16 @@ use dukbind::{
|
|||
duk_push_pointer, duk_push_undefined, duk_put_prop, duk_put_prop_lstring, duk_size_t,
|
||||
DUK_ERR_ERROR, DUK_ERR_EVAL_ERROR, DUK_ERR_NONE, DUK_ERR_RANGE_ERROR, DUK_ERR_SYNTAX_ERROR,
|
||||
DUK_ERR_TYPE_ERROR, DUK_ERR_URI_ERROR, DUK_TYPE_BOOLEAN, DUK_TYPE_NONE, DUK_TYPE_NULL,
|
||||
DUK_TYPE_NUMBER, DUK_TYPE_STRING, DUK_TYPE_UNDEFINED,
|
||||
DUK_TYPE_NUMBER, DUK_TYPE_OBJECT, DUK_TYPE_STRING, DUK_TYPE_UNDEFINED,
|
||||
};
|
||||
use std::error::Error;
|
||||
use std::f64;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr::NonNull;
|
||||
use std::convert::TryInto;
|
||||
|
||||
/// An error code representing why an error occurred.
|
||||
#[allow(missing_docs)]
|
||||
|
@ -200,9 +202,7 @@ impl<'a> DukObject<'a> {
|
|||
duk_push_number(ctx, n.as_f64());
|
||||
}
|
||||
}
|
||||
DukValue::Boolean(b) => {
|
||||
duk_push_boolean(ctx, value.as_duk_bool().expect("Not a boolean!"))
|
||||
}
|
||||
DukValue::Boolean(b) => duk_push_boolean(ctx, b as duk_bool_t),
|
||||
DukValue::String(s) => {
|
||||
let t = &s;
|
||||
duk_push_lstring(ctx, t.as_ptr() as *const i8, t.len() as duk_size_t);
|
||||
|
@ -255,41 +255,49 @@ pub enum DukValue<'a> {
|
|||
Object(DukObject<'a>),
|
||||
}
|
||||
|
||||
impl<'a> From<bool> for DukValue<'a> {
|
||||
fn from(value: bool) -> Self {
|
||||
DukValue::Boolean(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<String> for DukValue<'a> {
|
||||
fn from(value: String) -> Self {
|
||||
DukValue::String(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryInto<bool> for DukValue<'a> {
|
||||
type Error = DukError;
|
||||
|
||||
fn try_into(self) -> Result<bool, Self::Error> {
|
||||
if let DukValue::Boolean(b) = self {
|
||||
Ok(b)
|
||||
} else {
|
||||
Err(DukError::from_str("Could not convert value to boolean"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryInto<String> for DukValue<'a> {
|
||||
type Error = DukError;
|
||||
|
||||
fn try_into(self) -> Result<String, Self::Error> {
|
||||
match self {
|
||||
DukValue::Undefined => Ok(String::from("undefined")),
|
||||
DukValue::Null => Ok(String::from("null")),
|
||||
DukValue::Number(n) => Ok(String::from(n.as_str())),
|
||||
DukValue::Boolean(b) => Ok(b.to_string()),
|
||||
DukValue::String(s) => Ok(s.clone()),
|
||||
DukValue::Object(o) => match o.encode() {
|
||||
Some(encoded) => Ok(encoded),
|
||||
None => Err(DukError::from_str("Could not convert object to String")),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DukValue<'a> {
|
||||
/// Return the value as a string.
|
||||
pub fn as_str(&self) -> Option<String> {
|
||||
match self {
|
||||
DukValue::Undefined => Some(String::from("undefined")),
|
||||
DukValue::Null => Some(String::from("null")),
|
||||
DukValue::Number(n) => Some(String::from(n.as_str())),
|
||||
DukValue::Boolean(b) => Some(b.to_string()),
|
||||
DukValue::String(s) => Some(s.clone()),
|
||||
DukValue::Object(o) => o.encode(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the value as a duk_bool_t (u32).
|
||||
pub fn as_duk_bool(&self) -> Option<duk_bool_t> {
|
||||
match self {
|
||||
DukValue::Boolean(b) => {
|
||||
if *b {
|
||||
Some(1)
|
||||
} else {
|
||||
Some(0)
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the value as a bool.
|
||||
pub fn as_bool(&self) -> Option<bool> {
|
||||
match self {
|
||||
DukValue::Boolean(b) => Some(*b),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the value as a DukNumber.
|
||||
pub fn as_number(&self) -> Option<DukNumber> {
|
||||
match self {
|
||||
|
@ -498,14 +506,9 @@ impl DukContext {
|
|||
);
|
||||
let val = self.get_value();
|
||||
duk_pop(self.ctx.as_ptr());
|
||||
match val.as_str() {
|
||||
Some(v) => {
|
||||
use std::mem;
|
||||
let c: DukErrorCode = mem::transmute(code);
|
||||
Err(DukError::from(c, v.as_ref()))
|
||||
}
|
||||
None => Err(DukError::from_code(DukErrorCode::Error)),
|
||||
}
|
||||
let val: String = val.try_into()?;
|
||||
let c: DukErrorCode = mem::transmute(code);
|
||||
Err(DukError::from(c, val.as_ref()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -519,6 +522,7 @@ mod tests {
|
|||
fn test_create_context() {
|
||||
let ctx = DukContext::new();
|
||||
assert!(ctx.is_ok());
|
||||
drop(ctx);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -529,19 +533,35 @@ mod tests {
|
|||
assert_eq!(val, DukNumber::Int(15));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eval_to_bool() {
|
||||
let ctx = DukContext::new().unwrap();
|
||||
let val: bool = ctx.eval_string("true").unwrap().try_into().unwrap();
|
||||
assert_eq!(val, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eval_to_string() {
|
||||
let ctx = DukContext::new().unwrap();
|
||||
let val = ctx.eval_string("'something'.toUpperCase()").unwrap();
|
||||
let val = val.as_str().unwrap();
|
||||
assert_eq!(val, String::from("SOMETHING"));
|
||||
let val: String = ctx.eval_string("'something'.toUpperCase()").unwrap().try_into().unwrap();
|
||||
assert_eq!(val.as_str(), "SOMETHING");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eval_to_object() {
|
||||
let ctx = DukContext::new().unwrap();
|
||||
let val = ctx.eval_string("({\"some\":\"thing\"})").unwrap();
|
||||
let _ = val.as_object().unwrap();
|
||||
assert!(val.as_object().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_obj_prop() {
|
||||
let ctx = DukContext::new().unwrap();
|
||||
let val = ctx.eval_string("({\"some\":\"thing\"})").unwrap();
|
||||
let obj = val.as_object().unwrap();
|
||||
let s = String::from("name");
|
||||
obj.set_prop("other", s.into()).unwrap();
|
||||
assert_eq!(obj.encode().unwrap().as_str(), "{\"some\":\"thing\",\"other\":\"name\"}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -549,18 +569,16 @@ mod tests {
|
|||
let ctx = DukContext::new().unwrap();
|
||||
let val = ctx.eval_string("({\"some\":\"thing\"})").unwrap();
|
||||
let obj = val.as_object().unwrap();
|
||||
assert_eq!(
|
||||
obj.get_prop("some").unwrap().as_str().unwrap(),
|
||||
String::from("thing")
|
||||
);
|
||||
let value: String = obj.get_prop("some").unwrap().try_into().unwrap();
|
||||
assert_eq!(value.as_str(), "thing");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eval_ret() {
|
||||
// Create a new context
|
||||
let mut ctx = DukContext::new().unwrap();
|
||||
let ctx = DukContext::new().unwrap();
|
||||
// Obtain array value from eval
|
||||
let mut val = ctx.eval_string("([1,2,3])").unwrap();
|
||||
let val = ctx.eval_string("([1,2,3])").unwrap();
|
||||
// Get the array as an object
|
||||
let obj = val.as_object().expect("WAS NOT AN OBJECT");
|
||||
// Set index 3 as 4
|
||||
|
|
Loading…
Reference in a new issue