git.delta.rocks / jrsonnet / refs/commits / 32a7ddca0d3c

difftreelog

source

crates/jrsonnet-evaluator/src/integrations/serde.rs1.9 KiBsourcehistory
1use crate::{2	error::{Error::*, LocError, Result},3	throw, LazyBinding, LazyVal, ObjMember, ObjValue, Val,4};5use jrsonnet_parser::Visibility;6use serde_json::{Map, Number, Value};7use std::{8	collections::HashMap,9	convert::{TryFrom, TryInto},10	rc::Rc,11};1213impl TryFrom<&Val> for Value {14	type Error = LocError;15	fn try_from(v: &Val) -> Result<Self> {16		Ok(match v {17			Val::Bool(b) => Self::Bool(*b),18			Val::Null => Self::Null,19			Val::Str(s) => Self::String((s as &str).into()),20			Val::Num(n) => Self::Number(if n.fract() <= f64::EPSILON {21				(*n as i64).into()22			} else {23				Number::from_f64(*n).expect("to json number")24			}),25			Val::Lazy(v) => (&v.evaluate()?).try_into()?,26			Val::Arr(a) => {27				let mut out = Vec::with_capacity(a.len());28				for item in a.iter() {29					out.push(item.try_into()?);30				}31				Self::Array(out)32			}33			Val::Obj(o) => {34				let mut out = Map::new();35				for key in o.visible_fields() {36					out.insert(37						(&key as &str).into(),38						(&o.get(key)?.expect("field exists")).try_into()?,39					);40				}41				Self::Object(out)42			}43			Val::Func(_) => throw!(RuntimeError("tried to manifest function".into())),44		})45	}46}4748impl From<&Value> for Val {49	fn from(v: &Value) -> Self {50		match v {51			Value::Null => Self::Null,52			Value::Bool(v) => Self::Bool(*v),53			Value::Number(n) => Self::Num(n.as_f64().expect("as f64")),54			Value::String(s) => Self::Str((s as &str).into()),55			Value::Array(a) => {56				let mut out = Vec::with_capacity(a.len());57				for v in a {58					out.push(v.into());59				}60				Self::Arr(Rc::new(out))61			}62			Value::Object(o) => {63				let mut entries = HashMap::with_capacity(o.len());64				for (k, v) in o {65					entries.insert(66						(k as &str).into(),67						ObjMember {68							add: false,69							visibility: Visibility::Normal,70							invoke: LazyBinding::Bound(LazyVal::new_resolved(v.into())),71							location: None,72						},73					);74				}75				Self::Obj(ObjValue::new(None, Rc::new(entries)))76			}77		}78	}79}