From cad2be43bf3b7c93eb2e308ed9e704df48d40fc7 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 29 Dec 2023 14:06:10 -0500 Subject: [PATCH] Implement a new to_wasm macro that uses the WasmAstNodeWrapper. --- src/wasm/ast_node.rs | 41 ++++++++++------------------- src/wasm/document.rs | 39 ++++++++-------------------- src/wasm/macros.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 55 deletions(-) diff --git a/src/wasm/ast_node.rs b/src/wasm/ast_node.rs index 69c98b44..79b365c9 100644 --- a/src/wasm/ast_node.rs +++ b/src/wasm/ast_node.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use serde::Serialize; use super::angle_link::WasmAngleLink; @@ -58,39 +60,24 @@ use super::timestamp::WasmTimestamp; use super::underline::WasmUnderline; use super::verbatim::WasmVerbatim; use super::verse_block::WasmVerseBlock; +use super::WasmStandardProperties; -// #[derive(Debug, Serialize)] -// pub(crate) struct WasmAstWrapper<'b, 's, 'p, I> { -// #[serde(rename = "ast-node")] -// pub(crate) ast_node: Cow<'static, str>, -// #[serde(rename = "standard-properties")] -// pub(crate) standard_properties: WasmStandardProperties, -// #[serde(rename = "properties")] -// pub(crate) inner: I, -// pub(crate) children: &'b Vec>, -// } - -// impl<'b, 's, 'p, I> WasmAstWrapper<'b, 's, 'p, I> { -// pub(crate) fn new( -// ast_node: Cow<'s, str>, -// standard_properties: &'b WasmStandardProperties, -// inner: I, -// children: &'b Vec>, -// ) -> WasmAstWrapper<'b, 's, 'p, I> { -// WasmAstWrapper { -// ast_node, -// standard_properties, -// inner, -// children, -// } -// } -// } +#[derive(Debug, Serialize)] +pub struct WasmAstNodeWrapper { + pub(crate) ast_node: String, + #[serde(rename = "standard-properties")] + pub(crate) standard_properties: WasmStandardProperties, + #[serde(rename = "children")] + pub(crate) children: Vec, + #[serde(rename = "properties")] + pub(crate) properties: I, +} #[derive(Debug, Serialize)] #[serde(untagged)] pub enum WasmAstNode { // Document Nodes - Document(WasmDocument), + Document(WasmAstNodeWrapper), Headline(WasmHeadline), Section(WasmSection), // Elements diff --git a/src/wasm/document.rs b/src/wasm/document.rs index 48f6fb84..8235641f 100644 --- a/src/wasm/document.rs +++ b/src/wasm/document.rs @@ -5,8 +5,8 @@ use serde::Serialize; use super::additional_property::AdditionalProperties; use super::additional_property::AdditionalPropertyValue; use super::ast_node::WasmAstNode; +use super::macros::new_to_wasm; use super::macros::to_wasm; -use super::standard_properties::WasmStandardProperties; use super::to_wasm::ToWasm; #[cfg(feature = "wasm_test")] use crate::compare::ElispFact; @@ -14,26 +14,21 @@ use crate::types::Document; use crate::wasm::to_wasm::ToWasmStandardProperties; #[derive(Debug, Serialize)] -#[serde(tag = "__ast_node")] -#[serde(rename = "org-data")] pub struct WasmDocument { - #[serde(rename = "standard-properties")] - pub(crate) standard_properties: WasmStandardProperties, #[serde(flatten)] pub(crate) additional_properties: AdditionalProperties, - #[serde(rename = "__children")] - pub(crate) children: Vec, #[serde(rename = "CATEGORY")] pub(crate) category: Option, pub(crate) path: Option, } -to_wasm!( +new_to_wasm!( WasmDocument, Document<'s>, original, wasm_context, - standard_properties, + { WasmAstNode::Document(original) }, + { "org-data".into() }, { let category = original.category.as_ref().map(String::as_str); let path = original.path.clone(); @@ -63,25 +58,13 @@ to_wasm!( })) .collect::, _>>()?; - Ok(WasmDocument { - standard_properties, - additional_properties, + Ok(( children, - category: category.map(str::to_owned), - path, - }) + WasmDocument { + additional_properties, + category: category.map(str::to_owned), + path, + }, + )) } ); - -impl Into for WasmDocument { - fn into(self) -> WasmAstNode { - WasmAstNode::Document(self) - } -} - -#[cfg(feature = "wasm_test")] -impl<'s> ElispFact<'s> for WasmDocument { - fn get_elisp_name<'b>(&'b self) -> std::borrow::Cow<'s, str> { - "org-data".into() - } -} diff --git a/src/wasm/macros.rs b/src/wasm/macros.rs index 8ed5021f..60e986e5 100644 --- a/src/wasm/macros.rs +++ b/src/wasm/macros.rs @@ -33,3 +33,64 @@ macro_rules! to_wasm { } pub(crate) use to_wasm; + +/// Write the implementation for the intermediate ast node. +/// +/// This exists to make changing the type signature easier. +macro_rules! new_to_wasm { + ($ostruct:ty, $istruct:ty, $original:ident, $wasm_context:ident, $fnbody:tt) => { + impl<'s> ToWasm for $istruct { + type Output = $ostruct; + + fn to_wasm( + &self, + $wasm_context: crate::wasm::to_wasm::ToWasmContext<'_>, + ) -> Result { + let $original = self; + $fnbody + } + } + }; + ($ostruct:ty, $istruct:ty, $original:ident, $wasm_context:ident, $toastnodebody:tt, $elispnamebody:tt, $fnbody:tt) => { + impl<'s> ToWasm for $istruct { + type Output = crate::wasm::ast_node::WasmAstNodeWrapper<$ostruct>; + + fn to_wasm( + &self, + $wasm_context: crate::wasm::to_wasm::ToWasmContext<'_>, + ) -> Result { + let $original = self; + let standard_properties = + self.to_wasm_standard_properties($wasm_context.clone())?; + + $fnbody.map( + |(children, inner)| crate::wasm::ast_node::WasmAstNodeWrapper { + ast_node: inner.get_elisp_name().into_owned(), + standard_properties, + children, + properties: inner, + }, + ) + } + } + + impl Into for crate::wasm::ast_node::WasmAstNodeWrapper<$ostruct> { + fn into(self) -> WasmAstNode { + let $original = self; + let ret = $toastnodebody; + ret + } + } + + #[cfg(feature = "wasm_test")] + impl<'s> ElispFact<'s> for $ostruct { + fn get_elisp_name<'b>(&'b self) -> std::borrow::Cow<'s, str> { + let $original = self; + let ret = $elispnamebody; + ret + } + } + }; +} + +pub(crate) use new_to_wasm;