vimwiki_macros 0.1.0

Macro library that provides macros to generate vimwiki language at compile time.
Documentation
use crate::tokens::{
    utils::{root_crate, tokenize_cow_str_type, tokenize_hashmap},
    Tokenize, TokenizeContext,
};
use proc_macro2::TokenStream;
use quote::quote;
use vimwiki_core::{Anchor, Description, Link, LinkData};

impl_tokenize!(tokenize_link, Link<'a>, 'a);
fn tokenize_link(ctx: &TokenizeContext, link: &Link) -> TokenStream {
    let root = root_crate();
    match &link {
        Link::Diary { date, data } => {
            let date_t = do_tokenize!(ctx, date);
            let data_t = do_tokenize!(ctx, data);
            quote!(#root::Link::Diary { date: #date_t, data: #data_t })
        }
        Link::IndexedInterWiki { index, data } => {
            let data_t = do_tokenize!(ctx, data);
            quote!(#root::Link::IndexedInterWiki { index: #index, data: #data_t })
        }
        Link::NamedInterWiki { name, data } => {
            let name_t = do_tokenize!(ctx, name);
            let data_t = do_tokenize!(ctx, data);
            quote!(#root::Link::NamedInterWiki { name: #name_t, data: #data_t })
        }
        Link::Raw { data } => {
            let data_t = do_tokenize!(ctx, data);
            quote!(#root::Link::Raw { data: #data_t })
        }
        Link::Transclusion { data } => {
            let data_t = do_tokenize!(ctx, data);
            quote!(#root::Link::Transclusion { data: #data_t })
        }
        Link::Wiki { data } => {
            let data_t = do_tokenize!(ctx, data);
            quote!(#root::Link::Wiki { data: #data_t })
        }
    }
}

impl_tokenize!(tokenize_link_data, LinkData<'a>, 'a);
fn tokenize_link_data(ctx: &TokenizeContext, data: &LinkData) -> TokenStream {
    let root = root_crate();
    let uri_ref_t = do_tokenize!(ctx, &data.uri_ref);
    let description_t = if let Some(d) = data.description.as_ref() {
        let t = tokenize_description(ctx, d);
        quote!(::std::option::Option::Some(#t))
    } else {
        quote!(::std::option::Option::None)
    };
    let properties_t = if let Some(properties) = data.properties.as_ref() {
        let t = tokenize_hashmap(
            properties,
            tokenize_cow_str_type(),
            tokenize_cow_str_type(),
            |x| do_tokenize!(ctx, x),
            |x| do_tokenize!(ctx, x),
        );
        quote!(::std::option::Option::Some(#t))
    } else {
        quote!(::std::option::Option::None)
    };

    quote!(#root::LinkData::new(#uri_ref_t, #description_t, #properties_t))
}

impl_tokenize!(tokenize_description, Description<'a>, 'a);
fn tokenize_description(
    ctx: &TokenizeContext,
    description: &Description,
) -> TokenStream {
    let root = root_crate();
    match &description {
        Description::Text(x) => {
            let t = do_tokenize!(ctx, &x);
            quote! { #root::Description::Text(#t) }
        }
        Description::TransclusionLink(x) => {
            let t = tokenize_link_data(ctx, &x);
            quote! {
                #root::Description::TransclusionLink(::std::boxed::Box::new(#t))
            }
        }
    }
}

impl_tokenize!(tokenize_anchor, Anchor<'a>, 'a);
fn tokenize_anchor(ctx: &TokenizeContext, anchor: &Anchor) -> TokenStream {
    let root = root_crate();
    let elements = anchor.iter().map(|x| do_tokenize!(ctx, x));
    quote!(#root::Anchor::new(::std::vec![#(#elements),*]))
}