1use crate::{2 error::{Error::*, LocError, Result},3 throw, ObjValueBuilder, Val,4};5use serde_json::{Map, Number, Value};6use std::convert::{TryFrom, TryInto};78impl TryFrom<&Val> for Value {9 type Error = LocError;10 fn try_from(v: &Val) -> Result<Self> {11 Ok(match v {12 Val::Bool(b) => Self::Bool(*b),13 Val::Null => Self::Null,14 Val::Str(s) => Self::String((s as &str).into()),15 Val::Num(n) => Self::Number(if n.fract() <= f64::EPSILON {16 (*n as i64).into()17 } else {18 Number::from_f64(*n).expect("to json number")19 }),20 Val::Arr(a) => {21 let mut out = Vec::with_capacity(a.len());22 for item in a.iter() {23 out.push((&item?).try_into()?);24 }25 Self::Array(out)26 }27 Val::Obj(o) => {28 let mut out = Map::new();29 for key in o.fields() {30 out.insert(31 (&key as &str).into(),32 (&o.get(key)?.expect("field exists")).try_into()?,33 );34 }35 Self::Object(out)36 }37 Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),38 })39 }40}4142impl From<&Value> for Val {43 fn from(v: &Value) -> Self {44 match v {45 Value::Null => Self::Null,46 Value::Bool(v) => Self::Bool(*v),47 Value::Number(n) => Self::Num(n.as_f64().expect("as f64")),48 Value::String(s) => Self::Str((s as &str).into()),49 Value::Array(a) => {50 let mut out: Vec<Self> = Vec::with_capacity(a.len());51 for v in a {52 out.push(v.into());53 }54 Self::Arr(out.into())55 }56 Value::Object(o) => {57 let mut builder = ObjValueBuilder::with_capacity(o.len());58 for (k, v) in o {59 builder.member((k as &str).into()).value(v.into());60 }61 Self::Obj(builder.build())62 }63 }64 }65}