Files
organic/src/wasm/additional_property.rs

96 lines
3.3 KiB
Rust
Raw Normal View History

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)]
2023-12-29 10:04:59 -05:00
#[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<WasmAstNode<'s, 'p>>>, Vec<WasmAstNode<'s, 'p>>)>),
}
#[derive(Debug, Serialize, Default)]
pub struct AdditionalProperties<'s, 'p> {
2023-12-29 10:04:59 -05:00
#[serde(flatten)]
pub(crate) properties: HashMap<String, AdditionalPropertyValue<'s, 'p>>,
}
impl<'s, 'p> AdditionalProperties<'s, 'p> {
pub(crate) fn get_elisp_names<'c>(&'c self) -> impl Iterator<Item = String> + '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::<WasmAstNode<'_, '_>>::into)
})
.collect::<Result<Vec<_>, _>>()?,
)
} else {
None
};
let converted_value = value
.iter()
.map(|child| {
child
.to_wasm(wasm_context.clone())
.map(Into::<WasmAstNode<'_, '_>>::into)
})
.collect::<Result<Vec<_>, _>>()?;
ret.push((converted_optval, converted_value));
}
AdditionalPropertyValue::ObjectTree(ret)
}
};
additional_properties
.properties
.insert(name.clone(), converted_val);
}
Ok(additional_properties)
}
);