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("jsonnet numbers can't be infinite or NaN")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)?33 .expect("key is present in fields, so value should exist"))34 .try_into()?,35 );36 }37 Self::Object(out)38 }39 Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),40 })41 }42}4344impl TryFrom<&Value> for Val {45 type Error = LocError;46 fn try_from(v: &Value) -> Result<Self> {47 Ok(match v {48 Value::Null => Self::Null,49 Value::Bool(v) => Self::Bool(*v),50 Value::Number(n) => Self::Num(n.as_f64().ok_or_else(|| {51 RuntimeError(format!("json number can't be represented as jsonnet: {}", n).into())52 })?),53 Value::String(s) => Self::Str((s as &str).into()),54 Value::Array(a) => {55 let mut out: Vec<Self> = Vec::with_capacity(a.len());56 for v in a {57 out.push(v.try_into()?);58 }59 Self::Arr(out.into())60 }61 Value::Object(o) => {62 let mut builder = ObjValueBuilder::with_capacity(o.len());63 for (k, v) in o {64 builder.member((k as &str).into()).value(v.try_into()?);65 }66 Self::Obj(builder.build())67 }68 })69 }70}