- generate .dex - edditable code format - json serialize with serde - sanity checks - tests - https://source.android.com/docs/core/runtime/dex-format#system-annotation ``` use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::hash::Hash; pub mod vectorize { use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::iter::FromIterator; pub fn serialize<'a, T, K, V, S>(target: T, ser: S) -> Result where S: Serializer, T: IntoIterator, K: Serialize + 'a, V: Serialize + 'a, { let container: Vec<_> = target.into_iter().collect(); serde::Serialize::serialize(&container, ser) } pub fn deserialize<'de, T, K, V, D>(des: D) -> Result where D: Deserializer<'de>, T: FromIterator<(K, V)>, K: Deserialize<'de>, V: Deserialize<'de>, { let container: Vec<_> = serde::Deserialize::deserialize(des)?; Ok(T::from_iter(container.into_iter())) } } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] struct KeyItem { name: String, len: u32, } impl KeyItem { fn new(s: &str) -> Self { Self { name: s.into(), len: s.len() as u32, } } } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] enum ValueItem { String1(String), String2(String), Int(u32), } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] struct ToSerialize { #[serde(with = "vectorize")] map1: HashMap, #[serde(with = "vectorize")] map2: HashMap, } fn main() { let value = ToSerialize { map1: HashMap::from([ (KeyItem::new("plop"), ValueItem::String1("Plop".into())), (KeyItem::new("plip"), ValueItem::String2("Plip".into())), (KeyItem::new("lop"), ValueItem::Int(109)), ]), map2: HashMap::from([( KeyItem::new("run"), ValueItem::String1("Demons run when a good man goes to war".into()), )]), }; let serialized = serde_json::to_string(&value).unwrap(); println!("{serialized}"); assert_eq!( serde_json::from_str::(&serialized).unwrap(), value ); } ``` `cargo add serde -F derive && cargo add serde_json`