#![forbid(unsafe_code)]
#![allow(unused_attributes)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![warn(non_ascii_idents)]
#![warn(noop_method_call)]
#![warn(single_use_lifetimes)]
#![warn(trivial_casts)]
#![warn(unreachable_pub)]
#![warn(unused_crate_dependencies)]
#![warn(unused_extern_crates)]
#![warn(unused_lifetimes)]
#![warn(unused_results)]
#![allow(clippy::many_single_char_names)]
mod compile_error;
mod generate;
mod nate_span;
mod parse;
mod strip;
use std::convert::TryInto;
use std::fs::OpenOptions;
use std::io::Read;
use std::path::Path;
use blake2::{Blake2s256, Digest};
use compile_error::IoOp;
use darling::FromDeriveInput;
use proc_macro::TokenStream;
use quote::quote;
use crate::compile_error::CompileError;
use crate::generate::generate;
use crate::strip::Strip;
#[proc_macro_derive(Nate, attributes(template))]
pub fn derive_nate(input: TokenStream) -> TokenStream {
let err = match generate(input) {
Ok(ts) => return ts,
Err(err) => err,
};
let err = format!("{}", err);
Into::into(quote!(
const _: () = {
::nate::details::std::compile_error!(#err);
};
))
}
#[derive(Debug, Default, FromDeriveInput)]
#[darling(attributes(template))]
struct Settings {
path: String,
#[darling(default)]
generated: Option<String>,
#[darling(default)]
#[allow(unused)] strip: Strip,
}
#[derive(Debug, Default)]
struct Context {
settings: Settings,
strings_hash: Blake2s256,
}
impl Context {
fn load_file(&mut self, path: &Path) -> Result<String, CompileError> {
let mut f = OpenOptions::new()
.read(true)
.open(path)
.map_err(|err| CompileError::IoError(IoOp::Open, path.to_owned(), err))?;
let len = f
.metadata()
.map_err(|err| CompileError::IoError(IoOp::Metadata, path.to_owned(), err))?
.len();
let mut s = String::with_capacity(len.try_into().unwrap_or_default());
let _ = f
.read_to_string(&mut s)
.map_err(|err| CompileError::IoError(IoOp::Read, path.to_owned(), err))?;
self.strings_hash.update((s.len() as u128).to_be_bytes());
self.strings_hash.update(s.as_bytes());
self.strings_hash.update([0xff_u8]);
Ok(s)
}
}
#[doc(hidden)]
#[proc_macro_attribute]
pub fn addr(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}