1use std::convert::{TryFrom, TryInto};23use serde_json::{Map, Number, Value};45use crate::{6 error::{Error::*, LocError, Result},7 throw, ObjValueBuilder, Val,8};910impl TryFrom<&Val> for Value {11 type Error = LocError;12 fn try_from(v: &Val) -> Result<Self> {13 Ok(match v {14 Val::Bool(b) => Self::Bool(*b),15 Val::Null => Self::Null,16 Val::Str(s) => Self::String((s as &str).into()),17 Val::Num(n) => Self::Number(if n.fract() <= f64::EPSILON {18 (*n as i64).into()19 } else {20 Number::from_f64(*n).expect("jsonnet numbers can't be infinite or NaN")21 }),22 Val::Arr(a) => {23 let mut out = Vec::with_capacity(a.len());24 for item in a.iter() {25 out.push(item?.try_into()?);26 }27 Self::Array(out)28 }29 Val::Obj(o) => {30 let mut out = Map::new();31 for key in o.fields() {32 out.insert(33 (&key as &str).into(),34 o.get(key)?35 .expect("key is present in fields, so value should exist")36 .try_into()?,37 );38 }39 Self::Object(out)40 }41 Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),42 })43 }44}45impl TryFrom<Val> for Value {46 type Error = LocError;4748 fn try_from(value: Val) -> Result<Self, Self::Error> {49 <Self as TryFrom<&Val>>::try_from(&value)50 }51}5253impl TryFrom<&Value> for Val {54 type Error = LocError;55 fn try_from(v: &Value) -> Result<Self> {56 Ok(match v {57 Value::Null => Self::Null,58 Value::Bool(v) => Self::Bool(*v),59 Value::Number(n) => Self::Num(n.as_f64().ok_or_else(|| {60 RuntimeError(format!("json number can't be represented as jsonnet: {}", n).into())61 })?),62 Value::String(s) => Self::Str((s as &str).into()),63 Value::Array(a) => {64 let mut out: Vec<Self> = Vec::with_capacity(a.len());65 for v in a {66 out.push(v.try_into()?);67 }68 Self::Arr(out.into())69 }70 Value::Object(o) => {71 let mut builder = ObjValueBuilder::with_capacity(o.len());72 for (k, v) in o {73 builder.member((k as &str).into()).value(v.try_into()?)?;74 }75 Self::Obj(builder.build())76 }77 })78 }79}80impl TryFrom<Value> for Val {81 type Error = LocError;8283 fn try_from(value: Value) -> Result<Self, Self::Error> {84 <Self as TryFrom<&Value>>::try_from(&value)85 }86}