From 6494d1ed5fb476d59b42536d958663069a6fda51 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 30 Jan 2022 18:23:13 +0100 Subject: [PATCH] Store persistent fields as plain JSON strings On second thought, this is much better. The resulting file size will be much smaller because only double quotes need to be escaped. It's also easier to read at a glance. --- Cargo.lock | 7 ------- Cargo.toml | 1 - nih_plug_derive/src/lib.rs | 4 ++-- src/params.rs | 8 ++++---- src/wrapper/state.rs | 38 +++----------------------------------- 5 files changed, 9 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6a26820..522d533d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,12 +8,6 @@ version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - [[package]] name = "gain" version = "0.1.0" @@ -37,7 +31,6 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" name = "nih_plug" version = "0.1.0" dependencies = [ - "base64", "lazy_static", "nih_plug_derive", "serde", diff --git a/Cargo.toml b/Cargo.toml index e52e8dc1..26400503 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ members = ["nih_plug_derive", "plugins/gain", "xtask"] [dependencies] nih_plug_derive = { path = "nih_plug_derive" } -base64 = "0.13" lazy_static = "1.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/nih_plug_derive/src/lib.rs b/nih_plug_derive/src/lib.rs index a2bb0455..8cf4c701 100644 --- a/nih_plug_derive/src/lib.rs +++ b/nih_plug_derive/src/lib.rs @@ -158,7 +158,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream { param_map } - fn serialize_fields(&self) -> ::std::collections::HashMap> { + fn serialize_fields(&self) -> ::std::collections::HashMap { let mut serialized = ::std::collections::HashMap::new(); #(#field_serialize_tokens)* @@ -166,7 +166,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream { serialized } - fn deserialize_fields(&self, serialized: &::std::collections::HashMap>) { + fn deserialize_fields(&self, serialized: &::std::collections::HashMap) { for (field_name, data) in serialized { match field_name.as_str() { #(#field_deserialize_tokens)* diff --git a/src/params.rs b/src/params.rs index 694a42cc..374f5568 100644 --- a/src/params.rs +++ b/src/params.rs @@ -25,9 +25,9 @@ pub type FloatParam = PlainParam; pub type IntParam = PlainParam; /// Re-export for use in the [Params] proc-macro. -pub use serde_json::from_slice as deserialize_field; +pub use serde_json::from_str as deserialize_field; /// Re-export for use in the [Params] proc-macro. -pub use serde_json::to_vec as serialize_field; +pub use serde_json::to_string as serialize_field; /// The functinoality needed for persisting a field to the plugin's state, and for restoring values /// when loading old state. @@ -357,13 +357,13 @@ pub trait Params { /// Serialize all fields marked with `#[persist = "stable_name"]` into a hash map containing /// JSON-representations of those fields so they can be written to the plugin's state and /// recalled later. This uses [serialize_field] under the hood. - fn serialize_fields(&self) -> HashMap>; + fn serialize_fields(&self) -> HashMap; /// Restore all fields marked with `#[persist = "stable_name"]` from a hashmap created by /// [Self::serialize_fields]. All of thse fields should be wrapped in a [PersistentField] with /// thread safe interior mutability, like an `RwLock` or a `Mutex`. This gets called when the /// plugin's state is being restored. This uses [deserialize_field] under the hood. - fn deserialize_fields(&self, serialized: &HashMap>); + fn deserialize_fields(&self, serialized: &HashMap); } /// Internal pointers to parameters. This is an implementation detail used by the wrappers. diff --git a/src/wrapper/state.rs b/src/wrapper/state.rs index bf40085c..a7515ada 100644 --- a/src/wrapper/state.rs +++ b/src/wrapper/state.rs @@ -16,7 +16,6 @@ //! Utilities for saving a [crate::plugin::Plugin]'s state. -use serde::de::Error; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -40,38 +39,7 @@ pub(crate) struct State { /// on the [Params] struct that's annotated with `#[persist = "stable_name"]` will be persisted /// this way. /// - /// The individual JSON-serialized fields are encoded as base64 strings so they don't take up as - /// much space in the preset. Storing them as a plain JSON string would have also been possible, - /// but that can get messy with escaping since those will likely also contain double quotes. - #[serde(serialize_with = "encode_fields")] - #[serde(deserialize_with = "decode_fields")] - pub fields: HashMap>, -} - -fn encode_fields(bytes: &HashMap>, serializer: S) -> Result -where - S: serde::Serializer, -{ - serializer.collect_map( - bytes - .into_iter() - .map(|(id, json)| (id, base64::encode(json))), - ) -} - -fn decode_fields<'de, D>(deserializer: D) -> Result>, D::Error> -where - D: serde::Deserializer<'de>, -{ - let base64_map: HashMap = HashMap::deserialize(deserializer)?; - let decoded_map: Result>, D::Error> = base64_map - .into_iter() - .map(|(id, base64)| { - base64::decode(base64) - .map(|decoded| (id, decoded)) - .map_err(|err| D::Error::custom(format!("base64 decode failed: {}", err))) - }) - .collect(); - - Ok(decoded_map?) + /// The individual fields are also serialized as JSON so they can safely be restored + /// independently of the other fields. + pub fields: HashMap, }