git.delta.rocks / jrsonnet / refs/commits / e53349155ac3

difftreelog

source

crates/jrsonnet-evaluator/src/integrations/serde.rs2.2 KiBsourcehistory
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}