pub use miniserde::de::Deserialize;
pub use miniserde::ser::Serialize;
pub use miniserde::json;
mod value;
pub use value::{from_value, replay_value_to_visitor, to_value};
#[cfg(feature = "macros")]
pub use midi_internal::{Deserialize, Serialize};
pub mod with;
pub trait FlattenMap<T>: miniserde::de::Map {
fn accepts_key(&self, k: &str) -> bool;
fn build(&mut self) -> miniserde::Result<T>;
}
pub trait FlattenDeserialize: Sized {
fn create_flatten_map() -> Box<dyn FlattenMap<Self>>;
}
pub trait SerializeMapBuilder {
fn create_ser_map(&self) -> Box<dyn miniserde::ser::Map + '_>;
}
impl<K, V, H> SerializeMapBuilder for std::collections::HashMap<K, V, H>
where
K: std::hash::Hash + Eq + ToString,
V: miniserde::Serialize,
H: std::hash::BuildHasher,
{
fn create_ser_map(&self) -> Box<dyn miniserde::ser::Map + '_> {
match miniserde::Serialize::begin(self) {
miniserde::ser::Fragment::Map(m) => m,
_ => unreachable!("HashMap::begin returns Fragment::Map"),
}
}
}
impl<K, V> SerializeMapBuilder for std::collections::BTreeMap<K, V>
where
K: ToString,
V: miniserde::Serialize,
{
fn create_ser_map(&self) -> Box<dyn miniserde::ser::Map + '_> {
match miniserde::Serialize::begin(self) {
miniserde::ser::Fragment::Map(m) => m,
_ => unreachable!("BTreeMap::begin returns Fragment::Map"),
}
}
}
struct HashMapFlattenMap<V> {
buffer: std::vec::Vec<(std::string::String, miniserde::json::Value)>,
current_key: Option<std::string::String>,
current_value: Option<miniserde::json::Value>,
_marker: std::marker::PhantomData<V>,
}
impl<V> HashMapFlattenMap<V> {
fn new() -> Self {
Self {
buffer: std::vec::Vec::new(),
current_key: None,
current_value: None,
_marker: std::marker::PhantomData,
}
}
fn shift(&mut self) {
if let (Some(k), Some(v)) = (self.current_key.take(), self.current_value.take()) {
self.buffer.push((k, v));
}
}
}
impl<V> miniserde::de::Map for HashMapFlattenMap<V>
where
V: miniserde::de::Deserialize,
{
fn key(&mut self, k: &str) -> miniserde::Result<&mut dyn miniserde::de::Visitor> {
self.shift();
self.current_key = Some(k.to_string());
Ok(miniserde::Deserialize::begin(&mut self.current_value))
}
fn finish(&mut self) -> miniserde::Result<()> {
self.shift();
Ok(())
}
}
impl<V, H> FlattenMap<std::collections::HashMap<std::string::String, V, H>>
for HashMapFlattenMap<V>
where
V: miniserde::de::Deserialize + 'static,
H: std::hash::BuildHasher + Default,
{
fn accepts_key(&self, _k: &str) -> bool {
true
}
fn build(&mut self) -> miniserde::Result<std::collections::HashMap<std::string::String, V, H>> {
let obj = miniserde::json::Object::from_iter(std::mem::take(&mut self.buffer));
from_value(&miniserde::json::Value::Object(obj))
}
}
impl<V, H> FlattenDeserialize for std::collections::HashMap<std::string::String, V, H>
where
V: miniserde::de::Deserialize + 'static,
H: std::hash::BuildHasher + Default,
{
fn create_flatten_map(
) -> Box<dyn FlattenMap<std::collections::HashMap<std::string::String, V, H>>> {
Box::new(HashMapFlattenMap::<V>::new())
}
}
struct BTreeMapFlattenMap<V> {
buffer: std::vec::Vec<(std::string::String, miniserde::json::Value)>,
current_key: Option<std::string::String>,
current_value: Option<miniserde::json::Value>,
_marker: std::marker::PhantomData<V>,
}
impl<V> BTreeMapFlattenMap<V> {
fn new() -> Self {
Self {
buffer: std::vec::Vec::new(),
current_key: None,
current_value: None,
_marker: std::marker::PhantomData,
}
}
fn shift(&mut self) {
if let (Some(k), Some(v)) = (self.current_key.take(), self.current_value.take()) {
self.buffer.push((k, v));
}
}
}
impl<V> miniserde::de::Map for BTreeMapFlattenMap<V>
where
V: miniserde::de::Deserialize,
{
fn key(&mut self, k: &str) -> miniserde::Result<&mut dyn miniserde::de::Visitor> {
self.shift();
self.current_key = Some(k.to_string());
Ok(miniserde::Deserialize::begin(&mut self.current_value))
}
fn finish(&mut self) -> miniserde::Result<()> {
self.shift();
Ok(())
}
}
impl<V> FlattenMap<std::collections::BTreeMap<std::string::String, V>>
for BTreeMapFlattenMap<V>
where
V: miniserde::de::Deserialize + 'static,
{
fn accepts_key(&self, _k: &str) -> bool {
true
}
fn build(&mut self) -> miniserde::Result<std::collections::BTreeMap<std::string::String, V>> {
let obj = miniserde::json::Object::from_iter(std::mem::take(&mut self.buffer));
from_value(&miniserde::json::Value::Object(obj))
}
}
impl<V> FlattenDeserialize for std::collections::BTreeMap<std::string::String, V>
where
V: miniserde::de::Deserialize + 'static,
{
fn create_flatten_map() -> Box<dyn FlattenMap<std::collections::BTreeMap<std::string::String, V>>> {
Box::new(BTreeMapFlattenMap::<V>::new())
}
}