git.delta.rocks / jrsonnet / refs/commits / 8e1facac94b0

difftreelog

source

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