git.delta.rocks / jrsonnet / refs/commits / 80f37a416bf7

difftreelog

source

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