git.delta.rocks / jrsonnet / refs/commits / 34fc2f0f1640

difftreelog

source

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