Skip to content

Commit

Permalink
Add ability to read html from file
Browse files Browse the repository at this point in the history
  • Loading branch information
alexkazik committed May 30, 2022
1 parent 5aa543a commit 7b95c65
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
2 changes: 1 addition & 1 deletion maud/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern crate alloc;
use alloc::{borrow::Cow, boxed::Box, string::String};
use core::fmt::{self, Arguments, Write};

pub use maud_macros::{html, html_debug};
pub use maud_macros::{html, html_debug, html_file};

mod escape;

Expand Down
46 changes: 45 additions & 1 deletion maud_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,18 @@ mod generate;
mod parse;

use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use proc_macro_error::proc_macro_error;
use proc_macro_error::{abort_call_site, proc_macro_error};
use quote::quote;
use std::{
env,
ffi::OsStr,
fmt::Display,
fs::File,
io::Read,
path::{Path, PathBuf},
str::FromStr,
};
use syn::{parse_macro_input, LitStr};

#[proc_macro]
#[proc_macro_error]
Expand All @@ -28,6 +38,40 @@ pub fn html_debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
expr.into()
}

#[proc_macro]
#[proc_macro_error]
pub fn html_file(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let orig_path = parse_macro_input!(input as LitStr);
let root = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string());
let path = Path::new(&root).join(&orig_path.value());

let file_name = path.file_name().unwrap_or_else(|| OsStr::new("unknown"));

let mut file = abort_on_error(file_name, "error while opening", || {
File::open(<PathBuf as AsRef<Path>>::as_ref(&path))
});
let mut file_contents = String::new();
abort_on_error(file_name, "error while reading", || {
file.read_to_string(&mut file_contents)
});

expand(abort_on_error(file_name, "error while parsing", || {
TokenStream::from_str(&file_contents)
}))
.into()
}

fn abort_on_error<T, F, E>(file_name: &OsStr, description: &str, f: F) -> T
where
F: FnOnce() -> Result<T, E>,
E: Display,
{
match f() {
Ok(result) => result,
Err(error) => abort_call_site!("{} {:?}: {}", description, file_name, error),
}
}

fn expand(input: TokenStream) -> TokenStream {
let output_ident = TokenTree::Ident(Ident::new("__maud_output", Span::mixed_site()));
// Heuristic: the size of the resulting markup tends to correlate with the
Expand Down

0 comments on commit 7b95c65

Please sign in to comment.