/// Write the implementation for the intermediate ast node.
///
/// This exists to make changing the type signature easier.
macro_rules! 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> {
                #[allow(unused_variables)]
                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 From<crate::wasm::ast_node::WasmAstNodeWrapper<$ostruct>> for WasmAstNode {
            fn from($original: crate::wasm::ast_node::WasmAstNodeWrapper<$ostruct>) -> Self {
                let ret = $toastnodebody;
                ret
            }
        }

        impl<'s> crate::util::elisp_fact::ElispFact<'s> for $ostruct {
            fn get_elisp_name<'b>(&'b self) -> std::borrow::Cow<'s, str> {
                let ret = $elispnamebody;
                ret
            }
        }
    };
}

pub(crate) use to_wasm;