Skip to content

Commit 0398fcb

Browse files
committed
feat: implement the Rules::iter() method.
This method returns an iterator that allows to iterate over the compiled rules, and access some information about each rule, like its identifier, namespace, tags, etc.
1 parent 604a0a1 commit 0398fcb

File tree

6 files changed

+394
-352
lines changed

6 files changed

+394
-352
lines changed

lib/src/compiler/rules.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fmt;
22
use std::io::{BufWriter, Read, Write};
3+
use std::slice::Iter;
34
#[cfg(feature = "logging")]
45
use std::time::Instant;
56

@@ -20,7 +21,7 @@ use crate::compiler::{
2021
};
2122
use crate::re::{BckCodeLoc, FwdCodeLoc, RegexpAtom};
2223
use crate::string_pool::{BStringPool, StringPool};
23-
use crate::{re, types};
24+
use crate::{re, types, Rule};
2425

2526
/// A set of YARA rules in compiled form.
2627
///
@@ -201,6 +202,29 @@ impl Rules {
201202
Self::deserialize(bytes)
202203
}
203204

205+
/// Returns an iterator that yields the compiled rules.
206+
///
207+
/// ```rust
208+
/// # use yara_x::Compiler;
209+
/// let mut compiler = Compiler::new();
210+
///
211+
/// assert!(compiler
212+
/// .add_source("rule foo {condition: true}")
213+
/// .unwrap()
214+
/// .add_source("rule bar {condition: true}")
215+
/// .is_ok());
216+
///
217+
/// let rules = compiler.build();
218+
/// let mut iter = rules.iter();
219+
///
220+
/// assert_eq!(iter.len(), 2);
221+
/// assert_eq!(iter.next().map(|r| r.identifier()), Some("foo"));
222+
/// assert_eq!(iter.next().map(|r| r.identifier()), Some("bar"));
223+
/// ```
224+
pub fn iter(&self) -> RulesIter {
225+
RulesIter { rules: self, iterator: self.rules.iter() }
226+
}
227+
204228
/// Returns a [`RuleInfo`] given its [`RuleId`].
205229
///
206230
/// # Panics
@@ -401,6 +425,32 @@ impl Rules {
401425
}
402426
}
403427

428+
/// Iterator that yields the of the compiled rules.
429+
pub struct RulesIter<'a> {
430+
rules: &'a Rules,
431+
iterator: Iter<'a, RuleInfo>,
432+
}
433+
434+
impl<'a> Iterator for RulesIter<'a> {
435+
type Item = Rule<'a, 'a>;
436+
437+
fn next(&mut self) -> Option<Self::Item> {
438+
Some(Rule {
439+
ctx: None,
440+
data: None,
441+
rules: self.rules,
442+
rule_info: self.iterator.next()?,
443+
})
444+
}
445+
}
446+
447+
impl ExactSizeIterator for RulesIter<'_> {
448+
#[inline]
449+
fn len(&self) -> usize {
450+
self.iterator.len()
451+
}
452+
}
453+
404454
fn serialize_wasm_mod<S>(
405455
wasm_mod: &wasmtime::Module,
406456
serializer: S,

lib/src/lib.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ assert_eq!(results.matching_rules().len(), 1);
4646
pub use compiler::compile;
4747
pub use compiler::Compiler;
4848
pub use compiler::Rules;
49+
pub use compiler::RulesIter;
4950
pub use compiler::SourceCode;
50-
51+
pub use models::Match;
52+
pub use models::Matches;
53+
pub use models::MetaValue;
54+
pub use models::Metadata;
55+
pub use models::Pattern;
56+
pub use models::Patterns;
57+
pub use models::Rule;
5158
pub use modules::mods;
52-
pub use scanner::Match;
53-
pub use scanner::Matches;
5459
pub use scanner::MatchingRules;
55-
pub use scanner::MetaValue;
56-
pub use scanner::Metadata;
5760
pub use scanner::ModuleOutputs;
5861
pub use scanner::NonMatchingRules;
59-
pub use scanner::Pattern;
60-
pub use scanner::Patterns;
61-
pub use scanner::Rule;
6262
pub use scanner::ScanError;
6363
pub use scanner::ScanOptions;
6464
pub use scanner::ScanResults;
@@ -75,6 +75,7 @@ mod types;
7575
mod variables;
7676
mod wasm;
7777

78+
mod models;
7879
#[cfg(test)]
7980
mod tests;
8081

0 commit comments

Comments
 (0)