@@ -11,8 +11,18 @@ mod generate;
11
11
mod parse;
12
12
13
13
use proc_macro2:: { Ident , Span , TokenStream , TokenTree } ;
14
- use proc_macro_error:: proc_macro_error;
14
+ use proc_macro_error:: { abort_call_site , proc_macro_error} ;
15
15
use quote:: quote;
16
+ use std:: {
17
+ env,
18
+ ffi:: OsStr ,
19
+ fmt:: Display ,
20
+ fs:: File ,
21
+ io:: Read ,
22
+ path:: { Path , PathBuf } ,
23
+ str:: FromStr ,
24
+ } ;
25
+ use syn:: { parse_macro_input, LitStr } ;
16
26
17
27
#[ proc_macro]
18
28
#[ proc_macro_error]
@@ -28,6 +38,40 @@ pub fn html_debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
28
38
expr. into ( )
29
39
}
30
40
41
+ #[ proc_macro]
42
+ #[ proc_macro_error]
43
+ pub fn html_file ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
44
+ let orig_path = parse_macro_input ! ( input as LitStr ) ;
45
+ let root = env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap_or ( "." . to_string ( ) ) ;
46
+ let path = Path :: new ( & root) . join ( & orig_path. value ( ) ) ;
47
+
48
+ let file_name = path. file_name ( ) . unwrap_or ( OsStr :: new ( "unknown" ) ) ;
49
+
50
+ let mut file = abort_on_error ( file_name, "error while opening" , || {
51
+ File :: open ( <PathBuf as AsRef < Path > >:: as_ref ( & path) )
52
+ } ) ;
53
+ let mut file_contents = String :: new ( ) ;
54
+ abort_on_error ( file_name, "error while reading" , || {
55
+ file. read_to_string ( & mut file_contents)
56
+ } ) ;
57
+
58
+ expand ( abort_on_error ( file_name, "error while parsing" , || {
59
+ TokenStream :: from_str ( & file_contents)
60
+ } ) )
61
+ . into ( )
62
+ }
63
+
64
+ fn abort_on_error < T , F , E > ( file_name : & OsStr , description : & str , f : F ) -> T
65
+ where
66
+ F : FnOnce ( ) -> Result < T , E > ,
67
+ E : Display ,
68
+ {
69
+ match f ( ) {
70
+ Ok ( result) => result,
71
+ Err ( error) => abort_call_site ! ( "{} {:?}: {}" , description, file_name, error) ,
72
+ }
73
+ }
74
+
31
75
fn expand ( input : TokenStream ) -> TokenStream {
32
76
let output_ident = TokenTree :: Ident ( Ident :: new ( "__maud_output" , Span :: mixed_site ( ) ) ) ;
33
77
// Heuristic: the size of the resulting markup tends to correlate with the
0 commit comments