From 8dab3979b7255dda8c1c7fdc04bef804dac9e811 Mon Sep 17 00:00:00 2001 From: David Teller Date: Mon, 8 Oct 2018 16:54:22 +0200 Subject: [PATCH] Towards making dictionaries serializable This changeset extendes Dictionary<> and KindedStringsPerFile<> to support the generic Serde (de)serialization mechanism. While we have not decided a format for storing dictionaries (that's https://github.com/binast/container-format-spec/issues/7 ), this will let us experiment using a simple, temporary format. --- crates/binjs_io/Cargo.toml | 4 +++- crates/binjs_io/src/entropy/model.rs | 2 +- crates/binjs_io/src/entropy/predict.rs | 4 ++-- crates/binjs_io/src/lib.rs | 4 ++++ crates/binjs_shared/Cargo.toml | 3 +++ crates/binjs_shared/src/ast.rs | 4 ++-- crates/binjs_shared/src/lib.rs | 5 ++++- crates/binjs_shared/src/shared_string.rs | 23 ++++++++++++++++++++++- 8 files changed, 41 insertions(+), 8 deletions(-) diff --git a/crates/binjs_io/Cargo.toml b/crates/binjs_io/Cargo.toml index 0102e5637..a56e74ac5 100644 --- a/crates/binjs_io/Cargo.toml +++ b/crates/binjs_io/Cargo.toml @@ -20,7 +20,9 @@ lzw = "*" log = "*" num_alias = "*" rand = "^0.4" -range-encoding = "0.1.7" +range-encoding = "0.1.8" +serde = "^1.0" +serde_derive = "^1.0" vec_map = "*" xml-rs = "*" diff --git a/crates/binjs_io/src/entropy/model.rs b/crates/binjs_io/src/entropy/model.rs index c56c4644d..fbed3c38b 100644 --- a/crates/binjs_io/src/entropy/model.rs +++ b/crates/binjs_io/src/entropy/model.rs @@ -18,7 +18,7 @@ int_alias!(InstancesInFile, usize); int_alias!(FilesContaining, usize); -#[derive(Debug, Default)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct Dictionary { /// All booleans appearing in the AST, predicted by path. pub bool_by_path: PathPredict, T>, diff --git a/crates/binjs_io/src/entropy/predict.rs b/crates/binjs_io/src/entropy/predict.rs index d0112058b..4461debba 100644 --- a/crates/binjs_io/src/entropy/predict.rs +++ b/crates/binjs_io/src/entropy/predict.rs @@ -20,7 +20,7 @@ pub struct Entry<'a, K, T> where K: 'a, T: 'a { } /// A generic predictor, associating a context and a key to a value. -#[derive(Debug, Default)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct ContextPredict where C: Eq + Hash + Clone, K: Eq + Hash + Clone { by_context: HashMap>, } @@ -95,7 +95,7 @@ impl InstancesToProbabilities for ContextPredict where C: Eq /// limit the prediction depth, e.g. to 0 (don't use any context), /// 1 (use only the parent + child index) or 2 (use parent + /// grand-parent and both child indices). -#[derive(Debug, Default)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct PathPredict where K: Eq + Hash + Clone { context_predict: ContextPredict, } diff --git a/crates/binjs_io/src/lib.rs b/crates/binjs_io/src/lib.rs index 715b33c11..0ee46ad0b 100644 --- a/crates/binjs_io/src/lib.rs +++ b/crates/binjs_io/src/lib.rs @@ -14,6 +14,10 @@ extern crate log; extern crate num_alias; extern crate rand; extern crate range_encoding; +#[macro_use] +extern crate serde_derive; +extern crate serde; + extern crate vec_map; extern crate xml as xml_rs; diff --git a/crates/binjs_shared/Cargo.toml b/crates/binjs_shared/Cargo.toml index 7f03cb489..46b9274ae 100644 --- a/crates/binjs_shared/Cargo.toml +++ b/crates/binjs_shared/Cargo.toml @@ -7,3 +7,6 @@ authors = ["David Teller "] itertools = "*" json = "^0.11" log = "^0.4" +serde = "^1.0" +serde_derive = "^1.0" + diff --git a/crates/binjs_shared/src/ast.rs b/crates/binjs_shared/src/ast.rs index 2b04f45a9..0bacec998 100644 --- a/crates/binjs_shared/src/ast.rs +++ b/crates/binjs_shared/src/ast.rs @@ -44,7 +44,7 @@ use std::fmt::*; /// path.exit_interface("Interface 1"); // Exiting the wrong interface would panic. /// ``` -#[derive(PartialEq, Eq, Hash, Clone, Default)] +#[derive(PartialEq, Eq, Hash, Clone, Default, Deserialize, Serialize)] pub struct Path where I: Debug + PartialEq, F: Debug + PartialEq { /// Some(foo) if we have entered interface foo but no field yet. /// Otherwise, None. @@ -60,7 +60,7 @@ impl From>> for Path where I: Debug + PartialEq, } } -#[derive(Debug, PartialEq, Eq, Hash, Clone)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, Deserialize, Serialize)] pub struct PathItem where I: Debug + PartialEq, F: Debug + PartialEq { pub interface: I, pub field: F, diff --git a/crates/binjs_shared/src/lib.rs b/crates/binjs_shared/src/lib.rs index b25dabeb8..57fe438ca 100644 --- a/crates/binjs_shared/src/lib.rs +++ b/crates/binjs_shared/src/lib.rs @@ -2,6 +2,9 @@ extern crate itertools; extern crate json; #[macro_use] extern crate log; +extern crate serde; +#[macro_use] +extern crate serde_derive; mod json_conversion; pub use json_conversion::*; @@ -44,7 +47,7 @@ shared_string!(pub FieldName); /// A container for f64 values that implements an *arbitrary* /// total order, equality relation, hash. -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Copy, Deserialize, Serialize)] pub struct F64(f64); impl From for F64 { fn from(value: f64) -> F64 { diff --git a/crates/binjs_shared/src/shared_string.rs b/crates/binjs_shared/src/shared_string.rs index b02b05413..3d7c480dc 100644 --- a/crates/binjs_shared/src/shared_string.rs +++ b/crates/binjs_shared/src/shared_string.rs @@ -3,6 +3,8 @@ use std::hash::Hash; use std::ops::Deref; use std::rc::Rc; +use serde::de::{ Deserialize, Deserializer }; +use serde::ser::{ Serialize, Serializer }; /// An implementation of strings that may easily be shared without copies. /// @@ -57,6 +59,25 @@ impl Default for SharedString { SharedString::Static("") } } +/// Shared strings are serialized as strings. This loses any sharing :/ +impl Serialize for SharedString { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer + { + self.deref().serialize(serializer) + } +} +/// Shared strings are deserialized as Dynamic strings. +impl<'de> Deserialize<'de> for SharedString { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de> + { + let dynamic = String::deserialize(deserializer)?; + Ok(SharedString::Dynamic(Rc::new(dynamic))) + } +} impl SharedString { pub fn as_str(&self) -> &str { self.deref() @@ -75,7 +96,7 @@ impl SharedString { #[macro_export] macro_rules! shared_string { (pub $name: ident) => { - #[derive(Clone, Eq, PartialOrd, Ord, Debug, Hash)] + #[derive(Clone, Eq, PartialOrd, Ord, Debug, Hash, Serialize, Deserialize)] pub struct $name(pub shared_string::SharedString); impl $name { pub fn from_str(value: &'static str) -> Self {