pub struct Rule(/* private fields */);Expand description
An AST node for $ast
Implementations§
Source§impl Rule
impl Rule
Sourcepub fn new(targets: &[&str], prerequisites: &[&str], recipes: &[&str]) -> Rule
pub fn new(targets: &[&str], prerequisites: &[&str], recipes: &[&str]) -> Rule
Create a new rule with the given targets, prerequisites, and recipes
§Arguments
targets- A slice of target namesprerequisites- A slice of prerequisite names (can be empty)recipes- A slice of recipe lines (can be empty)
§Example
use makefile_lossless::Rule;
let rule = Rule::new(&["all"], &["build", "test"], &["echo Done"]);
assert_eq!(rule.targets().collect::<Vec<_>>(), vec!["all"]);
assert_eq!(rule.prerequisites().collect::<Vec<_>>(), vec!["build", "test"]);
assert_eq!(rule.recipes().collect::<Vec<_>>(), vec!["echo Done"]);Sourcepub fn parent(&self) -> Option<MakefileItem>
pub fn parent(&self) -> Option<MakefileItem>
Get the parent item of this rule, if any
Returns Some(MakefileItem) if this rule has a parent that is a MakefileItem
(e.g., a Conditional), or None if the parent is the root Makefile node.
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = r#"ifdef DEBUG
all:
echo "test"
endif
"#.parse().unwrap();
let cond = makefile.conditionals().next().unwrap();
let rule = cond.if_items().next().unwrap();
// Rule's parent is the conditional
assert!(matches!(rule, makefile_lossless::MakefileItem::Rule(_)));Sourcepub fn targets(&self) -> impl Iterator<Item = String> + '_
pub fn targets(&self) -> impl Iterator<Item = String> + '_
Targets of this rule
§Example
use makefile_lossless::Rule;
let rule: Rule = "rule: dependency\n\tcommand".parse().unwrap();
assert_eq!(rule.targets().collect::<Vec<_>>(), vec!["rule"]);Sourcepub fn prerequisites(&self) -> impl Iterator<Item = String> + '_
pub fn prerequisites(&self) -> impl Iterator<Item = String> + '_
Get the prerequisites in the rule
§Example
use makefile_lossless::Rule;
let rule: Rule = "rule: dependency\n\tcommand".parse().unwrap();
assert_eq!(rule.prerequisites().collect::<Vec<_>>(), vec!["dependency"]);Sourcepub fn recipes(&self) -> impl Iterator<Item = String>
pub fn recipes(&self) -> impl Iterator<Item = String>
Get the commands in the rule
§Example
use makefile_lossless::Rule;
let rule: Rule = "rule: dependency\n\tcommand".parse().unwrap();
assert_eq!(rule.recipes().collect::<Vec<_>>(), vec!["command"]);Sourcepub fn recipe_nodes(&self) -> impl Iterator<Item = Recipe>
pub fn recipe_nodes(&self) -> impl Iterator<Item = Recipe>
Get recipe nodes with line/column information
Returns an iterator over Recipe AST nodes, which support the line(), column(),
and line_col() methods to get position information.
§Example
use makefile_lossless::Rule;
let rule_text = "test:\n\techo line1\n\techo line2\n";
let rule: Rule = rule_text.parse().unwrap();
let recipe_nodes: Vec<_> = rule.recipe_nodes().collect();
assert_eq!(recipe_nodes.len(), 2);
assert_eq!(recipe_nodes[0].text(), "echo line1");
assert_eq!(recipe_nodes[0].line(), 1); // 0-indexed
assert_eq!(recipe_nodes[1].text(), "echo line2");
assert_eq!(recipe_nodes[1].line(), 2);Sourcepub fn items(&self) -> impl Iterator<Item = RuleItem> + '_
pub fn items(&self) -> impl Iterator<Item = RuleItem> + '_
Get all items (recipe lines and conditionals) in the rule’s body
This method iterates through the rule’s body and yields both recipe lines and any conditionals that appear within the rule.
§Example
use makefile_lossless::{Rule, RuleItem};
let rule_text = r#"test:
echo "before"
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
./run-tests
endif
echo "after"
"#;
let rule: Rule = rule_text.parse().unwrap();
let items: Vec<_> = rule.items().collect();
assert_eq!(items.len(), 3); // recipe, conditional, recipe
match &items[0] {
RuleItem::Recipe(r) => assert_eq!(r, "echo \"before\""),
_ => panic!("Expected recipe"),
}
match &items[1] {
RuleItem::Conditional(_) => {},
_ => panic!("Expected conditional"),
}
match &items[2] {
RuleItem::Recipe(r) => assert_eq!(r, "echo \"after\""),
_ => panic!("Expected recipe"),
}Sourcepub fn replace_command(&mut self, i: usize, line: &str) -> bool
pub fn replace_command(&mut self, i: usize, line: &str) -> bool
Replace the command at index i with a new line
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "rule: dependency\n\tcommand".parse().unwrap();
rule.replace_command(0, "new command");
assert_eq!(rule.recipes().collect::<Vec<_>>(), vec!["new command"]);Sourcepub fn push_command(&mut self, line: &str)
pub fn push_command(&mut self, line: &str)
Add a new command to the rule
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "rule: dependency\n\tcommand".parse().unwrap();
rule.push_command("command2");
assert_eq!(rule.recipes().collect::<Vec<_>>(), vec!["command", "command2"]);Sourcepub fn remove_command(&mut self, index: usize) -> bool
pub fn remove_command(&mut self, index: usize) -> bool
Remove command at given index
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "rule:\n\tcommand1\n\tcommand2\n".parse().unwrap();
rule.remove_command(0);
assert_eq!(rule.recipes().collect::<Vec<_>>(), vec!["command2"]);Sourcepub fn insert_command(&mut self, index: usize, line: &str) -> bool
pub fn insert_command(&mut self, index: usize, line: &str) -> bool
Insert command at given index
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "rule:\n\tcommand1\n\tcommand2\n".parse().unwrap();
rule.insert_command(1, "inserted_command");
let recipes: Vec<_> = rule.recipes().collect();
assert_eq!(recipes, vec!["command1", "inserted_command", "command2"]);Sourcepub fn recipe_count(&self) -> usize
pub fn recipe_count(&self) -> usize
Get the number of commands/recipes in this rule
§Example
use makefile_lossless::Rule;
let rule: Rule = "rule:\n\tcommand1\n\tcommand2\n".parse().unwrap();
assert_eq!(rule.recipe_count(), 2);Sourcepub fn clear_commands(&mut self)
pub fn clear_commands(&mut self)
Clear all commands from this rule
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "rule:\n\tcommand1\n\tcommand2\n".parse().unwrap();
rule.clear_commands();
assert_eq!(rule.recipe_count(), 0);Sourcepub fn remove_prerequisite(&mut self, target: &str) -> Result<bool, Error>
pub fn remove_prerequisite(&mut self, target: &str) -> Result<bool, Error>
Remove a prerequisite from this rule
Returns true if the prerequisite was found and removed, false if it wasn’t found.
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "target: dep1 dep2 dep3\n".parse().unwrap();
assert!(rule.remove_prerequisite("dep2").unwrap());
assert_eq!(rule.prerequisites().collect::<Vec<_>>(), vec!["dep1", "dep3"]);
assert!(!rule.remove_prerequisite("nonexistent").unwrap());Sourcepub fn add_prerequisite(&mut self, target: &str) -> Result<(), Error>
pub fn add_prerequisite(&mut self, target: &str) -> Result<(), Error>
Add a prerequisite to this rule
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "target: dep1\n".parse().unwrap();
rule.add_prerequisite("dep2").unwrap();
assert_eq!(rule.prerequisites().collect::<Vec<_>>(), vec!["dep1", "dep2"]);Sourcepub fn set_prerequisites(&mut self, prereqs: Vec<&str>) -> Result<(), Error>
pub fn set_prerequisites(&mut self, prereqs: Vec<&str>) -> Result<(), Error>
Set the prerequisites for this rule, replacing any existing ones
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "target: old_dep\n".parse().unwrap();
rule.set_prerequisites(vec!["new_dep1", "new_dep2"]).unwrap();
assert_eq!(rule.prerequisites().collect::<Vec<_>>(), vec!["new_dep1", "new_dep2"]);Sourcepub fn rename_target(
&mut self,
old_name: &str,
new_name: &str,
) -> Result<bool, Error>
pub fn rename_target( &mut self, old_name: &str, new_name: &str, ) -> Result<bool, Error>
Rename a target in this rule
Returns Ok(true) if the target was found and renamed, Ok(false) if the target was not found.
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "old_target: dependency\n\tcommand".parse().unwrap();
rule.rename_target("old_target", "new_target").unwrap();
assert_eq!(rule.targets().collect::<Vec<_>>(), vec!["new_target"]);Sourcepub fn add_target(&mut self, target: &str) -> Result<(), Error>
pub fn add_target(&mut self, target: &str) -> Result<(), Error>
Add a target to this rule
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "target1: dependency\n\tcommand".parse().unwrap();
rule.add_target("target2").unwrap();
assert_eq!(rule.targets().collect::<Vec<_>>(), vec!["target1", "target2"]);Sourcepub fn set_targets(&mut self, targets: Vec<&str>) -> Result<(), Error>
pub fn set_targets(&mut self, targets: Vec<&str>) -> Result<(), Error>
Set the targets for this rule, replacing any existing ones
Returns an error if the targets list is empty (rules must have at least one target).
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "old_target: dependency\n\tcommand".parse().unwrap();
rule.set_targets(vec!["new_target1", "new_target2"]).unwrap();
assert_eq!(rule.targets().collect::<Vec<_>>(), vec!["new_target1", "new_target2"]);Sourcepub fn has_target(&self, target: &str) -> bool
pub fn has_target(&self, target: &str) -> bool
Check if this rule has a specific target
§Example
use makefile_lossless::Rule;
let rule: Rule = "target1 target2: dependency\n\tcommand".parse().unwrap();
assert!(rule.has_target("target1"));
assert!(rule.has_target("target2"));
assert!(!rule.has_target("target3"));Sourcepub fn remove_target(&mut self, target_name: &str) -> Result<bool, Error>
pub fn remove_target(&mut self, target_name: &str) -> Result<bool, Error>
Remove a target from this rule
Returns Ok(true) if the target was found and removed, Ok(false) if the target was not found.
Returns an error if attempting to remove the last target (rules must have at least one target).
§Example
use makefile_lossless::Rule;
let mut rule: Rule = "target1 target2: dependency\n\tcommand".parse().unwrap();
rule.remove_target("target1").unwrap();
assert_eq!(rule.targets().collect::<Vec<_>>(), vec!["target2"]);Sourcepub fn remove(self) -> Result<(), Error>
pub fn remove(self) -> Result<(), Error>
Remove this rule from its parent Makefile
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let rule = makefile.rules().next().unwrap();
rule.remove().unwrap();
assert_eq!(makefile.rules().count(), 1);This will also remove any preceding comments and up to 1 empty line before the rule. When removing the last rule in a makefile, this will also trim any trailing blank lines from the previous rule to avoid leaving extra whitespace at the end of the file.
Trait Implementations§
impl Eq for Rule
impl StructuralPartialEq for Rule
Auto Trait Implementations§
impl Freeze for Rule
impl !RefUnwindSafe for Rule
impl !Send for Rule
impl !Sync for Rule
impl Unpin for Rule
impl !UnwindSafe for Rule
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)