use std::borrow::Cow; use std::collections::HashMap; use serde::Serialize; use super::macros::to_wasm; use super::to_wasm::ToWasm; use super::WasmAstNode; use crate::types::AffiliatedKeywordValue; use crate::types::AffiliatedKeywords; #[derive(Debug, Serialize)] #[serde(untagged)] pub enum AdditionalPropertyValue { SingleString(String), ListOfStrings(Vec), OptionalPair { optval: Option, val: String }, ObjectTree(Vec<(Option>, Vec)>), } #[derive(Debug, Serialize, Default)] pub struct AdditionalProperties { #[serde(flatten)] pub(crate) properties: HashMap, } impl AdditionalProperties { pub(crate) fn get_elisp_names<'c>(&'c self) -> impl Iterator + 'c { self.properties.keys().map(move |key| format!(":{}", key)) } } to_wasm!( AdditionalProperties, AffiliatedKeywords<'s>, original, wasm_context, { let mut additional_properties = AdditionalProperties::default(); for (name, val) in original.keywords.iter() { let converted_val = match val { AffiliatedKeywordValue::SingleString(val) => { AdditionalPropertyValue::SingleString((*val).to_owned()) } AffiliatedKeywordValue::ListOfStrings(val) => { AdditionalPropertyValue::ListOfStrings( val.iter().map(|s| (*s).to_owned()).collect(), ) } AffiliatedKeywordValue::OptionalPair { optval, val } => { AdditionalPropertyValue::OptionalPair { optval: optval.map(|s| (*s).to_owned()), val: (*val).to_owned(), } } AffiliatedKeywordValue::ObjectTree(val) => { let mut ret = Vec::with_capacity(val.len()); for (optval, value) in val { let converted_optval = if let Some(optval) = optval { Some( optval .iter() .map(|child| { child .to_wasm(wasm_context.clone()) .map(Into::::into) }) .collect::, _>>()?, ) } else { None }; let converted_value = value .iter() .map(|child| { child .to_wasm(wasm_context.clone()) .map(Into::::into) }) .collect::, _>>()?; ret.push((converted_optval, converted_value)); } AdditionalPropertyValue::ObjectTree(ret) } }; additional_properties .properties .insert(name.clone(), converted_val); } Ok(additional_properties) } );