Skip to content

Commit d84ea3d

Browse files
committed
Add ability to read html from file
1 parent 5aa543a commit d84ea3d

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

maud/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ extern crate alloc;
1414
use alloc::{borrow::Cow, boxed::Box, string::String};
1515
use core::fmt::{self, Arguments, Write};
1616

17-
pub use maud_macros::{html, html_debug};
17+
pub use maud_macros::{html, html_debug, html_file};
1818

1919
mod escape;
2020

maud_macros/src/lib.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@ mod generate;
1111
mod parse;
1212

1313
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};
1515
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};
1626

1727
#[proc_macro]
1828
#[proc_macro_error]
@@ -28,6 +38,40 @@ pub fn html_debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
2838
expr.into()
2939
}
3040

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+
3175
fn expand(input: TokenStream) -> TokenStream {
3276
let output_ident = TokenTree::Ident(Ident::new("__maud_output", Span::mixed_site()));
3377
// Heuristic: the size of the resulting markup tends to correlate with the

0 commit comments

Comments
 (0)