asteracea_proc_macro_definitions/
lib.rs1#![forbid(unsafe_code)]
2#![allow(clippy::unneeded_field_pattern)]
3
4extern crate proc_macro;
5
6mod component_declaration;
7mod map_message;
8mod parse_with_context;
9mod part;
10mod try_parse;
11mod yank_any;
12
13use self::{
14 component_declaration::ComponentDeclaration,
15 map_message::MapMessage,
16 part::{GenerateContext, Part},
17 try_parse::TryParse,
18 yank_any::YankAny,
19};
20use lazy_static::lazy_static;
21use proc_macro::TokenStream as TokenStream1;
22use proc_macro2::{Span, TokenStream as TokenStream2};
23use proc_macro_crate::crate_name;
24use quote::{quote, ToTokens};
25use syn::{
26 parse::{Parse, ParseStream},
27 parse_macro_input, Ident, Result,
28};
29
30use syn::Error;
31
32#[proc_macro]
33pub fn component(input: TokenStream1) -> TokenStream1 {
34 let component_declaration = parse_macro_input!(input as ComponentDeclaration);
35 let tokens: TokenStream2 = component_declaration
36 .into_tokens()
37 .unwrap_or_else(|error| error.to_compile_error());
38 tokens.into()
39}
40
41struct BumpFormat {
42 asteracea: Ident,
43 bump_span: Span,
44 input: TokenStream2,
45}
46
47#[proc_macro]
48pub fn bump_format(input: TokenStream1) -> TokenStream1 {
49 let bump_format = parse_macro_input!(input as BumpFormat);
50 quote!(#bump_format).into()
51}
52
53impl Parse for BumpFormat {
54 fn parse(input: ParseStream) -> Result<Self> {
55 let bump_span = input.cursor().span();
58 let asteracea = asteracea_ident(bump_span);
59 Ok(BumpFormat {
60 asteracea,
61 bump_span,
62 input: input.parse()?,
63 })
64 }
65}
66
67impl ToTokens for BumpFormat {
68 fn to_tokens(&self, output: &mut TokenStream2) {
69 let BumpFormat {
70 asteracea,
71 bump_span,
72 input,
73 } = self;
74 let bump = Ident::new("bump", *bump_span);
75 output.extend(quote! {
76 #asteracea::lignin_schema::lignin::Node::Text(
77 #asteracea::lignin_schema::lignin::bumpalo::format!(in #bump, #input)
78 .into_bump_str()
79 )
80 });
81 }
82}
83
84enum FragmentConfiguration {}
85impl Configuration for FragmentConfiguration {
86 const NAME: &'static str = "fragment!";
87 const CAN_CAPTURE: bool = false;
88}
89
90#[proc_macro]
91pub fn fragment(input: TokenStream1) -> TokenStream1 {
92 parse_macro_input!(input as Part<FragmentConfiguration>)
93 .part_tokens(&GenerateContext::default())
94 .unwrap_or_else(|error| error.to_compile_error())
95 .into()
96}
97
98lazy_static! {
100 static ref ASTERACEA_NAME: String =
101 crate_name("asteracea").unwrap_or_else(|_| "asteracea".to_owned());
102}
103fn asteracea_ident(span: Span) -> Ident {
104 Ident::new(&*ASTERACEA_NAME, span)
105}
106
107mod workaround_module {
109 pub trait Configuration {
110 const NAME: &'static str;
111 const CAN_CAPTURE: bool;
112 }
113}
114use workaround_module::Configuration;
115
116fn warn(location: Span, message: &str) -> Result<()> {
117 Err(Error::new(location, message.to_string()))
118}