Implement a wrapper type for AST nodes.

This is to make it impossible to have a collision for attribute names that are real attributes vs attributes I've added for structure (like children and ast_node).
This commit is contained in:
Tom Alexander 2023-12-29 11:56:28 -05:00
parent 77e0dbb42e
commit 9f4f8e79ce
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 47 additions and 3 deletions

View File

@ -1,3 +1,5 @@
use std::borrow::Cow;
use serde::Serialize; use serde::Serialize;
use super::angle_link::WasmAngleLink; use super::angle_link::WasmAngleLink;
@ -58,6 +60,34 @@ use super::timestamp::WasmTimestamp;
use super::underline::WasmUnderline; use super::underline::WasmUnderline;
use super::verbatim::WasmVerbatim; use super::verbatim::WasmVerbatim;
use super::verse_block::WasmVerseBlock; 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<'s, str>,
#[serde(rename = "standard-properties")]
pub(crate) standard_properties: &'b 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)] #[derive(Debug, Serialize)]
#[serde(untagged)] #[serde(untagged)]

View File

@ -5,6 +5,7 @@ use serde::Serialize;
use super::additional_property::AdditionalProperties; use super::additional_property::AdditionalProperties;
use super::additional_property::AdditionalPropertyValue; use super::additional_property::AdditionalPropertyValue;
use super::ast_node::WasmAstNode; use super::ast_node::WasmAstNode;
use super::ast_node::WasmAstWrapper;
use super::macros::to_wasm; use super::macros::to_wasm;
use super::standard_properties::WasmStandardProperties; use super::standard_properties::WasmStandardProperties;
use super::to_wasm::ToWasm; use super::to_wasm::ToWasm;
@ -14,7 +15,7 @@ use crate::types::Document;
use crate::wasm::to_wasm::ToWasmStandardProperties; use crate::wasm::to_wasm::ToWasmStandardProperties;
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(tag = "__ast_node")] #[serde(tag = "ast_node")]
#[serde(rename = "org-data")] #[serde(rename = "org-data")]
pub struct WasmDocument<'s, 'p> { pub struct WasmDocument<'s, 'p> {
#[serde(rename = "standard-properties")] #[serde(rename = "standard-properties")]
@ -85,3 +86,16 @@ impl<'s, 'p> ElispFact<'s> for WasmDocument<'s, 'p> {
"org-data".into() "org-data".into()
} }
} }
impl<'b, 's, 'p> Into<WasmAstWrapper<'b, 's, 'p, &'b WasmDocument<'s, 'p>>>
for &'b WasmDocument<'s, 'p>
{
fn into(self) -> WasmAstWrapper<'b, 's, 'p, &'b WasmDocument<'s, 'p>> {
WasmAstWrapper::new(
self.get_elisp_name(),
&self.standard_properties,
self,
&self.children,
)
}
}

View File

@ -87,7 +87,7 @@ fn compare_json_value<'b, 's>(
emacs: &'b Token<'s>, emacs: &'b Token<'s>,
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> { ) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
match (value, emacs) { match (value, emacs) {
(serde_json::Value::Object(wasm), Token::List(el)) if wasm.contains_key("__ast_node") => { (serde_json::Value::Object(wasm), Token::List(el)) if wasm.contains_key("ast_node") => {
// We hit a regular ast node. // We hit a regular ast node.
compare_ast_node(source, el, wasm) compare_ast_node(source, el, wasm)
} }
@ -133,7 +133,7 @@ fn compare_ast_node<'b, 's, 'p>(
.ok_or("Should have a name as the first child.")? .ok_or("Should have a name as the first child.")?
.as_atom()?; .as_atom()?;
let wasm_name = wasm let wasm_name = wasm
.get("__ast_node") .get("ast_node")
.ok_or("Should have a ast node type.")? .ok_or("Should have a ast node type.")?
.as_str() .as_str()
.ok_or("Ast node type should be a string.")?; .ok_or("Ast node type should be a string.")?;