Implement a new to_wasm macro that uses the WasmAstNodeWrapper.

This commit is contained in:
Tom Alexander 2023-12-29 14:06:10 -05:00
parent a0a4f0eb90
commit cad2be43bf
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 86 additions and 55 deletions

View File

@ -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<WasmAstNode<'s, 'p>>,
// }
// 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<WasmAstNode<'s, 'p>>,
// ) -> WasmAstWrapper<'b, 's, 'p, I> {
// WasmAstWrapper {
// ast_node,
// standard_properties,
// inner,
// children,
// }
// }
// }
#[derive(Debug, Serialize)]
pub struct WasmAstNodeWrapper<I> {
pub(crate) ast_node: String,
#[serde(rename = "standard-properties")]
pub(crate) standard_properties: WasmStandardProperties,
#[serde(rename = "children")]
pub(crate) children: Vec<WasmAstNode>,
#[serde(rename = "properties")]
pub(crate) properties: I,
}
#[derive(Debug, Serialize)]
#[serde(untagged)]
pub enum WasmAstNode {
// Document Nodes
Document(WasmDocument),
Document(WasmAstNodeWrapper<WasmDocument>),
Headline(WasmHeadline),
Section(WasmSection),
// Elements

View File

@ -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<WasmAstNode>,
#[serde(rename = "CATEGORY")]
pub(crate) category: Option<String>,
pub(crate) path: Option<PathBuf>,
}
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::<Result<Vec<_>, _>>()?;
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<WasmAstNode> 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()
}
}

View File

@ -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<Self::Output, crate::error::CustomError> {
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<Self::Output, crate::error::CustomError> {
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<WasmAstNode> 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;