2023-12-27 18:01:56 -05:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
|
|
use serde::Serialize;
|
|
|
|
|
|
2023-12-27 20:33:02 -05:00
|
|
|
use super::macros::to_wasm;
|
|
|
|
|
use super::to_wasm::ToWasm;
|
2023-12-27 18:01:56 -05:00
|
|
|
use super::WasmAstNode;
|
2023-12-27 20:33:02 -05:00
|
|
|
use crate::types::AffiliatedKeywordValue;
|
|
|
|
|
use crate::types::AffiliatedKeywords;
|
2023-12-27 18:01:56 -05:00
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize)]
|
2023-12-29 10:04:59 -05:00
|
|
|
#[serde(untagged)]
|
2023-12-27 18:01:56 -05:00
|
|
|
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)]
|
2023-12-27 18:01:56 -05:00
|
|
|
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))
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-27 20:33:02 -05:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
);
|