1use crate::{2 error::{Error::*, LocError, Result},3 throw, LazyBinding, LazyVal, ObjMember, ObjValue, Val,4};5use jrsonnet_parser::Visibility;6use serde_json::{Map, Number, Value};7use std::{8 collections::HashMap,9 convert::{TryFrom, TryInto},10 rc::Rc,11};1213impl TryFrom<&Val> for Value {14 type Error = LocError;15 fn try_from(v: &Val) -> Result<Self> {16 Ok(match v {17 Val::Bool(b) => Self::Bool(*b),18 Val::Null => Self::Null,19 Val::Str(s) => Self::String((s as &str).into()),20 Val::Num(n) => Self::Number(if n.fract() <= f64::EPSILON {21 (*n as i64).into()22 } else {23 Number::from_f64(*n).expect("to json number")24 }),25 Val::Lazy(v) => (&v.evaluate()?).try_into()?,26 Val::Arr(a) => {27 let mut out = Vec::with_capacity(a.len());28 for item in a.iter() {29 out.push(item.try_into()?);30 }31 Self::Array(out)32 }33 Val::Obj(o) => {34 let mut out = Map::new();35 for key in o.visible_fields() {36 out.insert(37 (&key as &str).into(),38 (&o.get(key)?.expect("field exists")).try_into()?,39 );40 }41 Self::Object(out)42 }43 Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),44 })45 }46}4748impl From<&Value> for Val {49 fn from(v: &Value) -> Self {50 match v {51 Value::Null => Self::Null,52 Value::Bool(v) => Self::Bool(*v),53 Value::Number(n) => Self::Num(n.as_f64().expect("as f64")),54 Value::String(s) => Self::Str((s as &str).into()),55 Value::Array(a) => {56 let mut out = Vec::with_capacity(a.len());57 for v in a {58 out.push(v.into());59 }60 Self::Arr(Rc::new(out))61 }62 Value::Object(o) => {63 let mut entries = HashMap::with_capacity(o.len());64 for (k, v) in o {65 entries.insert(66 (k as &str).into(),67 ObjMember {68 add: false,69 visibility: Visibility::Normal,70 invoke: LazyBinding::Bound(LazyVal::new_resolved(v.into())),71 location: None,72 },73 );74 }75 Self::Obj(ObjValue::new(None, Rc::new(entries)))76 }77 }78 }79}