polite_programming/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/*extern crate regex;
use regex::Regex;
use std::process::{Command, Stdio};
use std::io::{BufRead, BufReader};
pub struct PleaseIgnore {
error_regex: Regex,
please_regex: Regex,
}
impl PleaseIgnore {
pub fn new() -> Self {
PleaseIgnore {
error_regex: Regex::new(r"error(\[E\d+\])?: ").unwrap(),
please_regex: Regex::new(r"\bplease\b").unwrap(),
}
}
pub fn analyze_compilation(&self, args: &[String]) -> std::io::Result<i32> {
let mut child = Command::new("cargo")
.arg("build")
.args(args)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let stderr = child.stderr.take().expect("Failed to capture stderr");
let stderr_reader = BufReader::new(stderr);
let mut in_error = false;
let mut current_error = String::new();
for line in stderr_reader.lines() {
let line = line?;
if self.error_regex.is_match(&line) {
if !current_error.is_empty() {
self.process_error(¤t_error);
}
in_error = true;
current_error.clear();
}
if in_error {
current_error.push_str(&line);
current_error.push('\n');
} else {
println!("{}", line);
}
if line.trim().is_empty() {
in_error = false;
if !current_error.is_empty() {
self.process_error(¤t_error);
}
current_error.clear();
}
}
if !current_error.is_empty() {
self.process_error(¤t_error);
}
let status = child.wait()?;
Ok(status.code().unwrap_or(1))
}
fn process_error(&self, error: &str) {
if self.please_regex.is_match(error) {
println!("Ignoring error due to 'please' usage:");
for line in error.lines() {
println!(" {}", line);
}
} else {
print!("{}", error);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_please_ignore() {
let pi = PleaseIgnore::new();
assert!(pi.please_regex.is_match("please"));
assert!(!pi.please_regex.is_match("no please here"));
}
}
*/
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn};
#[proc_macro_attribute]
pub fn ignore_please(_attr: TokenStream, item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as ItemFn);
let name = &input.sig.ident;
let inputs = &input.sig.inputs;
let output = &input.sig.output;
let body = &input.block;
let result = quote! {
fn #name(#inputs) #output {
let body_str = stringify!(#body);
let filtered_body = body_str.replace("please", "");
let filtered_tokens: proc_macro2::TokenStream = filtered_body.parse().unwrap();
#[filtered_tokens]
}
};
result.into()
}