use crate::IntoPklMap;
use crate::pkl::de::PklVisitor;
use crate::value::{DataSize, PklValue};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize)]
pub(crate) struct ObjectMember(pub String, pub PklValue);
impl ObjectMember {
#[cfg(feature = "codegen")]
#[inline]
pub fn get_ident(&self) -> &str {
self.0.as_str()
}
}
#[cfg(test)]
mod test {
#[test]
fn deserialize_map() {
use crate::{Value, internal::Integer};
let json_data = r#"{"value": 123}"#;
let value: Value = serde_json::from_str(json_data).expect("Failed to deserialize");
let map = value.as_map().expect("Expected a map");
assert_eq!(map.len(), 1);
assert_eq!(
map.get("value").unwrap().as_int().unwrap(),
&Integer::Pos(123)
);
}
#[test]
fn deserialize_array() {
use crate::{Value, internal::Integer};
let json_data = r#"{"value": [123, 456]}"#;
let value: Value = serde_json::from_str(json_data).expect("Failed to deserialize");
let map = value.as_map().expect("Expected a map");
assert_eq!(map.len(), 1);
let actual = map.get("value").unwrap().as_array().unwrap();
assert_eq!(
*actual,
vec![Value::Int(Integer::Pos(123)), Value::Int(Integer::Pos(456))]
);
}
}
impl From<PklPrimitive> for PklValue {
fn from(p: PklPrimitive) -> Self {
match p {
PklPrimitive::Int(i) => PklValue::Int(i),
PklPrimitive::Float(f) => PklValue::Int(Integer::Float(f)),
PklPrimitive::String(s) => PklValue::String(s),
PklPrimitive::Boolean(b) => PklValue::Boolean(b),
PklPrimitive::Null => PklValue::Null,
}
}
}
impl From<PklNonPrimitive> for PklValue {
fn from(np: PklNonPrimitive) -> Self {
match np {
PklNonPrimitive::TypedDynamic(_, _, _, children) => {
PklValue::Map(children.into_pkl_map())
}
PklNonPrimitive::List(_, items) | PklNonPrimitive::Set(_, items) => {
PklValue::List(items.into_iter().collect())
}
PklNonPrimitive::Mapping(_, m) => m,
PklNonPrimitive::Duration(_, d) => PklValue::Duration(d),
PklNonPrimitive::DataSize(_, ds) => PklValue::DataSize(ds),
PklNonPrimitive::Pair(_, a, b) => PklValue::Pair(Box::new(a), Box::new(b)),
PklNonPrimitive::IntSeq(_, start, end, step) => {
PklValue::IntSeq(crate::value::IntSeq { start, end, step })
}
PklNonPrimitive::Regex(_, r) => PklValue::Regex(r),
PklNonPrimitive::Bytes(_, bytes) => PklValue::Bytes(bytes),
}
}
}
impl<'de> Deserialize<'de> for PklValue {
fn deserialize<D>(deserializer: D) -> std::result::Result<PklValue, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(PklVisitor)
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, PartialOrd, Copy)]
#[serde(untagged)]
pub enum Integer {
Pos(u64),
Float(f64),
Neg(i64),
}
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub(crate) enum IPklValue {
Primitive(PklPrimitive),
NonPrimitive(PklNonPrimitive),
}
impl From<IPklValue> for PklValue {
fn from(p: IPklValue) -> Self {
match p {
IPklValue::Primitive(p) => p.into(),
IPklValue::NonPrimitive(np) => np.into(),
}
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum PklPrimitive {
Int(Integer),
Float(f64),
String(String),
Boolean(bool),
Null,
}
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub(crate) enum PklNonPrimitive {
TypedDynamic(u64, String, String, Vec<ObjectMember>),
List(u64, Vec<PklValue>),
Mapping(u64, PklValue),
Set(u64, Vec<PklValue>),
Duration(u64, std::time::Duration),
DataSize(u64, DataSize),
Pair(u64, PklValue, PklValue),
IntSeq(u64, i64, i64, i64),
Regex(u64, String),
Bytes(u64, Vec<u8>),
}
pub type IntSeq = std::ops::Range<i64>;
impl From<PklNonPrimitive> for IPklValue {
fn from(np: PklNonPrimitive) -> Self {
IPklValue::NonPrimitive(np)
}
}
impl From<PklPrimitive> for IPklValue {
fn from(p: PklPrimitive) -> Self {
IPklValue::Primitive(p)
}
}