ekege-macros 0.1.0

Procedural macros for Ekege: An E-graph library that's built like a database
Documentation
#![allow(missing_docs)]
//! Procedural macros to be re-exported in [Ekege](https://docs.rs/ekege/).
//!
//! Due to some Rustdoc limitations, the documentation for the macros defined here is
//! in the Ekege crate.
//!
//! <div class="warning">
//!     This crate should not be used directly! It is highly recommended that you
//!     use the macros from Ekege directly instead.
//! </div>
use std::{env, sync::LazyLock};

use equivalence::Equivalence;
use map::MapSignature;
use proc_macro_crate::{FoundCrate, crate_name};
use proc_macro2::Span;
use quote::{ToTokens, TokenStreamExt, quote};
use rewrite::Rewrite;
use rule::TreeRule;
use syn::{Ident, parse_macro_input};
use term::TreeTerm;

mod equivalence;
mod map;
mod rewrite;
mod rule;
mod term;

pub(crate) struct CrateRoot {
    root: LazyLock<String>,
}

impl ToTokens for CrateRoot {
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
        let crate_root = Ident::new(&self.root, Span::call_site());

        tokens.append_all(quote! { ::#crate_root });
    }
}

pub(crate) static CRATE_ROOT: CrateRoot = CrateRoot {
    root: LazyLock::new(|| {
        if env::var("CARGO_PKG_NAME").unwrap() == "ekege" {
            String::from("ekege")
        } else if let FoundCrate::Name(root_name) =
            crate_name("ekege").expect("proc-macro-crate could not detect ekege")
        {
            root_name
        } else {
            unreachable!()
        }
    }),
};

#[proc_macro]
pub fn term(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(tokens as TreeTerm);

    proc_macro::TokenStream::from(input.to_token_stream())
}

#[proc_macro]
pub fn map_signature(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(tokens as MapSignature);

    proc_macro::TokenStream::from(input.to_token_stream())
}

#[proc_macro]
pub fn rule(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(tokens as TreeRule);

    proc_macro::TokenStream::from(input.to_token_stream())
}

#[proc_macro]
pub fn rewrite(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(tokens as Rewrite);

    proc_macro::TokenStream::from(input.to_token_stream())
}

#[proc_macro]
pub fn equivalence(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(tokens as Equivalence);

    proc_macro::TokenStream::from(input.to_token_stream())
}