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}43impl TryFrom<Val> for Value {44 type Error = LocError;4546 fn try_from(value: Val) -> Result<Self, Self::Error> {47 <Self as TryFrom<&Val>>::try_from(&value)48 }49}5051impl TryFrom<&Value> for Val {52 type Error = LocError;53 fn try_from(v: &Value) -> Result<Self> {54 Ok(match v {55 Value::Null => Self::Null,56 Value::Bool(v) => Self::Bool(*v),57 Value::Number(n) => Self::Num(n.as_f64().ok_or_else(|| {58 RuntimeError(format!("json number can't be represented as jsonnet: {}", n).into())59 })?),60 Value::String(s) => Self::Str((s as &str).into()),61 Value::Array(a) => {62 let mut out: Vec<Self> = Vec::with_capacity(a.len());63 for v in a {64 out.push(v.try_into()?);65 }66 Self::Arr(out.into())67 }68 Value::Object(o) => {69 let mut builder = ObjValueBuilder::with_capacity(o.len());70 for (k, v) in o {71 builder.member((k as &str).into()).value(v.try_into()?);72 }73 Self::Obj(builder.build())74 }75 })76 }77}78impl TryFrom<Value> for Val {79 type Error = LocError;8081 fn try_from(value: Value) -> Result<Self, Self::Error> {82 <Self as TryFrom<&Value>>::try_from(&value)83 }84}