use crate::compiler::value;
use crate::compiler::value::parameters::{Parameter, Variable};
use crate::compiler::value::primitives::Primitive;
use crate::compiler::value::values::Value::{
FunctionNameValue, PrimitiveValue, Tuple, TypedValueInstance,
};
use crate::compiler::value::values::{FunctionDefinitionObject, TypedValue};
use crate::runtime::compiled_script::Bytecode;
use crate::store::FunctionValuesObject;
use serde::de::{Error, MapAccess, Visitor};
use serde::ser::SerializeStruct;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::cell::RefCell;
use std::fmt::Formatter;
use std::rc::Rc;
impl Serialize for TypedValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut value = serializer.serialize_struct("TypedValue", 2)?;
value.serialize_field("name", &self.name)?;
value.serialize_field("fields", &self.fields)?;
value.end()
}
}
impl<'de> Deserialize<'de> for TypedValue {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct("TypedValue", &["name", "fields"], TypedValueVisitor)
}
}
struct TypedValueVisitor;
impl<'de> Visitor<'de> for TypedValueVisitor {
type Value = TypedValue;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("struct TypedValue")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut result = TypedValue::default();
while let Some(key) = map.next_key()? {
match key {
"name" => result.name = map.next_value()?,
"fields" => result.fields = map.next_value()?,
some_string => {
return Err(Error::unknown_field(some_string, &["name", "fields"]));
}
}
}
Ok(result)
}
}
impl Serialize for Primitive {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Primitive::Boolean(ref v) => {
serializer.serialize_newtype_variant("Primitive", 1, "Boolean", v)
}
Primitive::Integer(ref v) => {
serializer.serialize_newtype_variant("Primitive", 2, "Integer", v)
}
Primitive::MyString(ref v) => {
serializer.serialize_newtype_variant("Primitive", 3, "MyString", v)
}
}
}
}
impl<'de> Deserialize<'de> for Primitive {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(PrimitiveVisitor)
}
}
struct PrimitiveVisitor;
impl<'de> Visitor<'de> for PrimitiveVisitor {
type Value = Primitive;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("enum Primitive")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
if let Some(key) = map.next_key()? {
match key {
"Integer" => {
let value: i32 = map.next_value()?;
Ok(Primitive::Integer(value))
}
"Boolean" => {
let value: bool = map.next_value()?;
Ok(Primitive::Boolean(value))
}
"MyString" => {
let value: String = map.next_value()?;
Ok(Primitive::MyString(value))
}
any => Err(Error::unknown_variant(
any,
&["Integer", "Nil", "Boolean", "MyString"],
)),
}
} else {
Err(Error::missing_field("type"))
}
}
}
impl Serialize for value::values::Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
PrimitiveValue(v) => serializer.serialize_newtype_variant("Value", 0, "Primitive", &v),
FunctionNameValue(v) => {
serializer.serialize_newtype_variant("Value", 1, "FunctionName", &v)
}
Tuple(v) => serializer.serialize_newtype_variant("Value", 2, "Tuple", &v),
TypedValueInstance(value) => serializer.serialize_newtype_variant(
"Value",
3,
"TypedValueInstance",
&(value.borrow().name.clone(), value.borrow().fields.clone()),
),
}
}
}
impl<'de> Deserialize<'de> for value::values::Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(ValueVisitor)
}
}
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = value::values::Value;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("struct TupleObject")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
if let Some(key) = map.next_key()? {
return match key {
"Primitive" => {
let primitive = map.next_value()?;
Ok(PrimitiveValue(primitive))
}
"FunctionName" => {
let object = map.next_value()?;
Ok(FunctionNameValue(object))
}
"Tuple" => {
let object = map.next_value()?;
Ok(Tuple(object))
}
"TypedValueInstance" => {
let (name, fields) = map.next_value()?;
Ok(TypedValueInstance(Rc::new(RefCell::new(TypedValue {
name,
fields,
}))))
}
any => Err(Error::unknown_variant(
any,
&["Primitive", "FunctionName", "Tuple", "TypedValueInstance"],
)),
};
}
Err(Error::custom(
"expected Primitive or Object, got nothing instead",
))
}
}
impl Serialize for Parameter {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Parameter::Constant(ref primitive) => {
serializer.serialize_newtype_variant("Parameter", 0, "Constant", primitive)
}
Parameter::Variable(ref var) => {
serializer.serialize_newtype_variant("Parameter", 1, "Variable", &var)
}
}
}
}
struct ParameterVisitor;
impl<'de> Deserialize<'de> for Parameter {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(ParameterVisitor)
}
}
impl<'de> Visitor<'de> for ParameterVisitor {
type Value = Parameter;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("enum parameter")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
if let Some(key) = map.next_key()? {
match key {
"Variable" => {
let value: String = map.next_value()?;
Ok(Parameter::Variable(value))
}
"Constant" => {
let value: value::values::Value = map.next_value()?;
Ok(Parameter::Constant(value))
}
any => Err(Error::unknown_variant(
any,
&["Integer", "Nil", "Boolean", "MyString"],
)),
}
} else {
Err(Error::missing_field("type"))
}
}
}
impl Serialize for Variable {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut var = serializer.serialize_struct("Variable", 1)?;
var.serialize_field("name", &self.name)?;
var.end()
}
}
impl<'de> Deserialize<'de> for Variable {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct("Variable", &["name"], VariableVisitor)
}
}
struct VariableVisitor;
impl<'de> Visitor<'de> for VariableVisitor {
type Value = Variable;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("enum Variable")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
if let Some(key) = map.next_key()? {
match key {
"name" => {
let name = map.next_value()?;
Ok(Variable::new(name))
}
some_string => Err(Error::unknown_field(some_string, &[""])),
}
} else {
Err(Error::missing_field("name"))
}
}
}
impl Serialize for Bytecode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut bytecode = serializer.serialize_struct("Bytecode", 3)?;
bytecode.serialize_field("bytes", &self.bytes)?;
bytecode.serialize_field("lines", &self.lines)?;
bytecode.serialize_field("labels", &self.labels)?;
bytecode.end()
}
}
impl<'de> Deserialize<'de> for Bytecode {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct("Bytecode", &["bytes", "lines", "labels"], BytecodeVisitor)
}
}
struct BytecodeVisitor;
impl<'de> Visitor<'de> for BytecodeVisitor {
type Value = Bytecode;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("struct Bytecode")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut result = Bytecode::new();
while let Some(key) = map.next_key()? {
match key {
"bytes" => result.bytes = map.next_value()?,
"lines" => result.lines = map.next_value()?,
"labels" => result.labels = map.next_value()?,
some_string => {
return Err(Error::unknown_field(
some_string,
&["bytes", "lines", "labels"],
));
}
}
}
Ok(result)
}
}
impl Serialize for FunctionDefinitionObject {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut fdo = serializer.serialize_struct("FunctionDefinitionObject", 5)?;
fdo.serialize_field("formal_arguments", &self.formal_arguments)?;
fdo.serialize_field("variables", &self.variables)?;
fdo.serialize_field("constants", &self.constants)?;
fdo.serialize_field("bytecode", &self.bytecode)?;
fdo.serialize_field("name", &self.name)?;
fdo.end()
}
}
impl<'de> Deserialize<'de> for FunctionDefinitionObject {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct(
"FunctionDefinitionObject",
&[
"formal_arguments",
"variables",
"constants",
"bytecode",
"name",
],
FunctionDefinitionVisitor,
)
}
}
struct FunctionDefinitionVisitor;
impl<'de> Visitor<'de> for FunctionDefinitionVisitor {
type Value = FunctionDefinitionObject;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("struct FunctionDefinitionObject")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut result = FunctionDefinitionObject::default();
while let Some(key) = map.next_key()? {
match key {
"formal_arguments" => {
result.formal_arguments = map.next_value()?;
}
"variables" => {
result.variables = map.next_value()?;
}
"constants" => {
result.constants = map.next_value()?;
}
"bytecode" => {
result.bytecode = map.next_value()?;
}
"name" => {
result.name = map.next_value()?;
}
some_string => {
return Err(Error::unknown_field(
some_string,
&["formal_arguments", "variables", "constants", "bytecode"],
));
}
}
}
Ok(result)
}
}
impl Serialize for FunctionValuesObject {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut fo = serializer.serialize_struct("FunctionObject", 1)?;
fo.serialize_field("values", &self.values)?;
fo.end()
}
}
impl<'de> Deserialize<'de> for FunctionValuesObject {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_struct("FunctionObject", &["values"], FunctionObjectVisitor)
}
}
struct FunctionObjectVisitor;
impl<'de> Visitor<'de> for FunctionObjectVisitor {
type Value = FunctionValuesObject;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("struct FunctionObject")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut result = FunctionValuesObject::new();
while let Some(key) = map.next_key()? {
match key {
"values" => result.values = map.next_value()?,
some_string => {
return Err(Error::unknown_field(some_string, &[""]));
}
}
}
Ok(result)
}
}
#[cfg(test)]
mod tests {
use serde::Serialize;
use std::cell::RefCell;
use std::collections::HashMap;
use std::fs::{remove_file, OpenOptions};
use crate::compiler::value::parameters::Parameter;
use crate::compiler::value::parameters::Parameter::Constant;
use crate::compiler::value::primitives::Primitive::{Boolean, Integer, MyString};
use crate::compiler::value::values::Value::{PrimitiveValue, Tuple, TypedValueInstance};
use crate::compiler::value::values::{FunctionDefinitionObject, TypedValue};
use crate::runtime::compiled_script::Bytecode;
use crate::string_to_value;
use serde::de::DeserializeOwned;
use std::fmt::Debug;
use std::io::{Error, Read, Write};
use std::path::PathBuf;
use std::rc::Rc;
fn base_json_test<D>(
data: D,
filename: &str,
delete_on_success: bool,
compare: bool,
) -> Result<D, Error>
where
D: Serialize + DeserializeOwned + Debug + Eq,
{
let s = serde_json::to_string(&data).unwrap();
println!("{}", s);
let mut base_test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
base_test_dir.push("target/tmp");
base_test_dir.push(filename);
println!("working in dir {}", base_test_dir.to_str().unwrap());
let mut file = OpenOptions::new()
.create(true)
.write(true)
.open(base_test_dir.clone())
.unwrap();
file.write(&[s.len() as u8])?;
file.write(s.as_bytes())?;
drop(file);
let mut file = OpenOptions::new()
.read(true)
.open(base_test_dir.clone())
.unwrap();
let mut byte_count = [0 as u8];
file.read_exact(&mut byte_count)?;
let mut read_in_me = vec![0 as u8; byte_count[0] as usize];
file.read_exact(&mut read_in_me)?;
println!("{}", read_in_me.len());
println!("{:?}", read_in_me);
let result: D = serde_json::from_slice(&read_in_me).unwrap();
println!("Result {:?}", result);
if compare {
assert_eq!(data, result);
}
if delete_on_success {
remove_file(base_test_dir)?;
}
return Ok(result);
}
#[test]
fn serialize_u8_array() -> Result<(), Error> {
let j = [1 as u8, 2, 3, 4, 5, 6, 5, 4, 3];
base_json_test(j, "array.data", true, true)?;
Ok(())
}
#[test]
fn serialize_integer_primitive() -> Result<(), Error> {
let prim = Integer(34);
base_json_test(prim, "integer.data", true, true)?;
Ok(())
}
#[test]
fn serialize_variable_parameter() -> Result<(), Error> {
let param = Parameter::Variable("val".to_string());
base_json_test(param, "param-var.data", true, true)?;
Ok(())
}
#[test]
fn serialize_constant_parameter() -> Result<(), Error> {
let param = Constant(PrimitiveValue(Integer(55)));
base_json_test(param, "param-const.data", true, true)?;
Ok(())
}
#[test]
fn serialize_function_definition_object() -> Result<(), Error> {
let mut bytecode = Bytecode::new();
bytecode.bytes = vec![1, 2, 3, 4, 5];
bytecode.lines = vec![0, 0, 0, 0, 0];
let fdo = FunctionDefinitionObject {
formal_arguments: vec![
Parameter::Variable("val".to_string()),
Constant(PrimitiveValue(Integer(12))),
],
constants: vec![],
variables: vec![],
bytecode,
name: "the fdo".to_string(),
};
base_json_test(fdo, "fdo.data", true, true)?;
Ok(())
}
#[test]
fn serialize_tuple_object() -> Result<(), Error> {
let tuple = Tuple(vec![
PrimitiveValue(Integer(-42)),
string_to_value!("forty-two".to_string()),
PrimitiveValue(Boolean(false)),
]);
base_json_test(tuple, "tuple.data", true, true)?;
Ok(())
}
#[test]
fn serialize_boolean_array() -> Result<(), Error> {
let j = [true, false];
base_json_test(j, "bool_array.data", true, true)?;
Ok(())
}
#[test]
fn serialize_custom_type() -> Result<(), Error> {
let fields = HashMap::from([
("field1".to_string(), MyString("value1".to_string())),
("field2".to_string(), MyString("value2".to_string())),
]);
let value = TypedValueInstance(Rc::new(RefCell::new(TypedValue {
name: "MyType".to_string(),
fields,
})));
base_json_test(value, "custom_value.data", true, true)?;
Ok(())
}
}