eager2_core/
lib.rs

1//! This library is not meant for public consumption
2
3#![doc(hidden)]
4
5use std::borrow::Cow;
6
7#[cfg(not(feature = "testing"))]
8extern crate proc_macro;
9
10#[cfg(not(feature = "testing"))]
11pub mod pm {
12    pub use proc_macro::{
13        token_stream, Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream,
14        TokenTree,
15    };
16    pub trait ToTokens {
17        fn to_tokens(&self, tokens: &mut TokenStream);
18        fn to_token_stream(&self) -> TokenStream {
19            let mut tokens = TokenStream::new();
20            self.to_tokens(&mut tokens);
21            tokens
22        }
23        fn into_token_stream(self) -> TokenStream
24        where
25            Self: Sized,
26        {
27            self.to_token_stream()
28        }
29    }
30    impl ToTokens for Group {
31        fn to_tokens(&self, tokens: &mut TokenStream) {
32            tokens.extend([TokenTree::from(self.clone())]);
33        }
34    }
35    impl ToTokens for Ident {
36        fn to_tokens(&self, tokens: &mut TokenStream) {
37            tokens.extend([TokenTree::from(self.clone())]);
38        }
39    }
40    impl ToTokens for Punct {
41        fn to_tokens(&self, tokens: &mut TokenStream) {
42            tokens.extend([TokenTree::from(self.clone())]);
43        }
44    }
45    impl ToTokens for Literal {
46        fn to_tokens(&self, tokens: &mut TokenStream) {
47            tokens.extend([TokenTree::from(self.clone())]);
48        }
49    }
50    impl ToTokens for TokenTree {
51        fn to_tokens(&self, tokens: &mut TokenStream) {
52            tokens.extend([self.clone()]);
53        }
54    }
55}
56
57#[cfg(feature = "testing")]
58pub mod pm {
59    pub use proc_macro2::{
60        token_stream, Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream,
61        TokenTree,
62    };
63    pub use quote::ToTokens;
64}
65
66pub struct Error {
67    pub span: pm::Span,
68    pub msg: Cow<'static, str>,
69    pub note: Option<Note>,
70}
71
72pub struct Note {
73    pub span: Option<pm::Span>,
74    pub msg: Cow<'static, str>,
75}
76
77impl pm::ToTokens for Error {
78    fn to_tokens(&self, tokens: &mut pm::TokenStream) {
79        fn ensure_lf(buf: &mut String, s: &str) {
80            if s.ends_with('\n') {
81                buf.push_str(s);
82            } else {
83                buf.push_str(s);
84                buf.push('\n');
85            }
86        }
87
88        let mut message = String::new();
89        ensure_lf(&mut message, &self.msg);
90        message.push('\n');
91
92        if let Some(note) = self.note.as_ref() {
93            message.push_str("  = note: ");
94            ensure_lf(&mut message, &note.msg);
95        }
96        message.push('\n');
97
98        let mut msg = pm::Literal::string(&message);
99        msg.set_span(self.span);
100        let mut group = pm::Group::new(pm::Delimiter::Brace, msg.into_token_stream());
101        group.set_span(self.span);
102
103        pm::Ident::new("compile_error", self.span).to_tokens(tokens);
104        let mut exclamation = pm::Punct::new('!', pm::Spacing::Alone);
105        exclamation.set_span(self.span);
106        exclamation.to_tokens(tokens);
107        group.to_tokens(tokens);
108    }
109}
110
111pub mod consts;
112pub mod egroup;
113pub mod exec;
114pub mod funcs;
115pub mod parse;
116pub mod rules;
117pub mod state;
118pub mod utils;