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 #[cfg(feature = "exp-preserve-order")]33 cfg!(feature = "exp-serde-preserve-order"),34 ) {35 out.insert(36 (&key as &str).into(),37 o.get(key)?38 .expect("key is present in fields, so value should exist")39 .try_into()?,40 );41 }42 Self::Object(out)43 }44 Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),45 })46 }47}48impl TryFrom<Val> for Value {49 type Error = LocError;5051 fn try_from(value: Val) -> Result<Self, Self::Error> {52 <Self as TryFrom<&Val>>::try_from(&value)53 }54}5556impl TryFrom<&Value> for Val {57 type Error = LocError;58 fn try_from(v: &Value) -> Result<Self> {59 Ok(match v {60 Value::Null => Self::Null,61 Value::Bool(v) => Self::Bool(*v),62 Value::Number(n) => Self::Num(n.as_f64().ok_or_else(|| {63 RuntimeError(format!("json number can't be represented as jsonnet: {}", n).into())64 })?),65 Value::String(s) => Self::Str((s as &str).into()),66 Value::Array(a) => {67 let mut out: Vec<Self> = Vec::with_capacity(a.len());68 for v in a {69 out.push(v.try_into()?);70 }71 Self::Arr(out.into())72 }73 Value::Object(o) => {74 let mut builder = ObjValueBuilder::with_capacity(o.len());75 for (k, v) in o {76 builder.member((k as &str).into()).value(v.try_into()?)?;77 }78 Self::Obj(builder.build())79 }80 })81 }82}83impl TryFrom<Value> for Val {84 type Error = LocError;8586 fn try_from(value: Value) -> Result<Self, Self::Error> {87 <Self as TryFrom<&Value>>::try_from(&value)88 }89}