diff options
Diffstat (limited to 'src/makefile/inference_rules.rs')
| -rw-r--r-- | src/makefile/inference_rules.rs | 55 | 
1 files changed, 49 insertions, 6 deletions
| diff --git a/src/makefile/inference_rules.rs b/src/makefile/inference_rules.rs index 3d18730..dfbb07c 100644 --- a/src/makefile/inference_rules.rs +++ b/src/makefile/inference_rules.rs @@ -1,19 +1,62 @@  use std::fmt; -use crate::makefile::command_line::CommandLine; +use eyre::{eyre, Result}; +use regex::Captures; + +use super::command_line::CommandLine; +use super::pattern::r#match;  #[derive(PartialEq, Eq, Clone, Debug)]  pub struct InferenceRule { -    /// POSIX calls this ".s1" but that's not useful. -    pub product: String, -    /// POSIX calls this ".s2" but that's not useful. -    pub prereq: String, +    pub products: Vec<String>, +    pub prerequisites: Vec<String>,      pub commands: Vec<CommandLine>,  } +impl InferenceRule { +    /// s1 is the product, s2 is the prereq +    pub fn new_suffix(s1: String, s2: String, commands: Vec<CommandLine>) -> Self { +        Self { +            products: vec![format!("%.{}", s1)], +            prerequisites: vec![format!("%.{}", s2)], +            commands, +        } +    } + +    fn first_match<'s, 't: 's>(&'s self, target_name: &'t str) -> Result<Option<Captures<'t>>> { +        self.products +            .iter() +            .map(|pattern| r#match(pattern, target_name)) +            .try_fold(None, |x, y| y.map(|y| x.or(y))) +    } + +    pub fn matches(&self, target_name: &str) -> Result<bool> { +        self.first_match(target_name).map(|x| x.is_some()) +    } + +    pub fn prereqs<'s>( +        &'s self, +        target_name: &'s str, +    ) -> Result<impl Iterator<Item = String> + 's> { +        let capture = self +            .first_match(target_name)? +            .ok_or_else(|| eyre!("asked non-matching inference rule for prerequisites"))?; +        let percent_expansion = capture.get(1).expect("should've matched the %").as_str(); +        Ok(self +            .prerequisites +            .iter() +            .map(move |p| p.replace('%', percent_expansion))) +    } +} +  impl fmt::Display for InferenceRule {      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -        writeln!(f, "{}{}:", &self.prereq, &self.product)?; +        writeln!( +            f, +            "{}: {}", +            self.products.join(" "), +            self.prerequisites.join(" ") +        )?;          for command in &self.commands {              writeln!(f, "\t{}", command)?;          } |