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<'s, 'p> { SingleString(&'s str), ListOfStrings(Vec<&'s str>), OptionalPair { optval: Option<&'s str>, val: &'s str, }, ObjectTree(Vec<(Option>>, Vec>)>), } #[derive(Debug, Serialize, Default)] pub struct AdditionalProperties<'s, 'p> { #[serde(flatten)] pub(crate) properties: HashMap>, } impl<'s, 'p> AdditionalProperties<'s, 'p> { pub(crate) fn get_elisp_names<'c>(&'c self) -> impl Iterator + 'c { self.properties.keys().map(move |key| format!(":{}", key)) } } to_wasm!( AdditionalProperties<'s, 'p>, 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) } AffiliatedKeywordValue::ListOfStrings(val) => { AdditionalPropertyValue::ListOfStrings(val.clone()) } AffiliatedKeywordValue::OptionalPair { optval, val } => { AdditionalPropertyValue::OptionalPair { optval: optval.clone(), val: val, } } 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) } );