From 175e3530bc95d8472cdadca3ac7881c6a42002ee Mon Sep 17 00:00:00 2001 From: kevin zhao Date: Thu, 13 Nov 2025 13:42:30 -0500 Subject: [PATCH] move validation logic to rule.rs --- codex-rs/execpolicy2/src/parser.rs | 4 +-- codex-rs/execpolicy2/src/policy.rs | 46 ------------------------------ codex-rs/execpolicy2/src/rule.rs | 46 ++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/codex-rs/execpolicy2/src/parser.rs b/codex-rs/execpolicy2/src/parser.rs index 6654e27429..12eb2ad6c0 100644 --- a/codex-rs/execpolicy2/src/parser.rs +++ b/codex-rs/execpolicy2/src/parser.rs @@ -17,12 +17,12 @@ use std::sync::Arc; use crate::decision::Decision; use crate::error::Error; use crate::error::Result; -use crate::policy::validate_match_examples; -use crate::policy::validate_not_match_examples; use crate::rule::PatternToken; use crate::rule::PrefixPattern; use crate::rule::PrefixRule; use crate::rule::RuleRef; +use crate::rule::validate_match_examples; +use crate::rule::validate_not_match_examples; // todo: support parsing multiple policies pub struct PolicyParser; diff --git a/codex-rs/execpolicy2/src/policy.rs b/codex-rs/execpolicy2/src/policy.rs index 5977d1f4c9..8b17d5add4 100644 --- a/codex-rs/execpolicy2/src/policy.rs +++ b/codex-rs/execpolicy2/src/policy.rs @@ -1,12 +1,9 @@ use crate::decision::Decision; -use crate::error::Error; -use crate::error::Result; use crate::rule::RuleMatch; use crate::rule::RuleRef; use multimap::MultiMap; use serde::Deserialize; use serde::Serialize; -use shlex::try_join; #[derive(Clone, Debug)] pub struct Policy { @@ -58,46 +55,3 @@ impl Evaluation { matches!(self, Self::Match { .. }) } } - -/// Count how many rules match each provided example and error if any example is unmatched. -pub(crate) fn validate_match_examples(rules: &[RuleRef], matches: &[Vec]) -> Result<()> { - let mut unmatched_examples = Vec::new(); - - for example in matches { - if rules.iter().any(|rule| rule.matches(example).is_some()) { - continue; - } - - unmatched_examples.push( - try_join(example.iter().map(String::as_str)) - .unwrap_or_else(|_| "unable to render example".to_string()), - ); - } - - if unmatched_examples.is_empty() { - Ok(()) - } else { - Err(Error::ExampleDidNotMatch { - rules: rules.iter().map(|rule| format!("{rule:?}")).collect(), - examples: unmatched_examples, - }) - } -} - -/// Ensure that no rule matches any provided negative example. -pub(crate) fn validate_not_match_examples( - rules: &[RuleRef], - not_matches: &[Vec], -) -> Result<()> { - for example in not_matches { - if let Some(rule) = rules.iter().find(|rule| rule.matches(example).is_some()) { - return Err(Error::ExampleDidMatch { - rule: format!("{rule:?}"), - example: try_join(example.iter().map(String::as_str)) - .unwrap_or_else(|_| "unable to render example".to_string()), - }); - } - } - - Ok(()) -} diff --git a/codex-rs/execpolicy2/src/rule.rs b/codex-rs/execpolicy2/src/rule.rs index 0336c3159e..191529dea3 100644 --- a/codex-rs/execpolicy2/src/rule.rs +++ b/codex-rs/execpolicy2/src/rule.rs @@ -1,6 +1,9 @@ use crate::decision::Decision; +use crate::error::Error; +use crate::error::Result; use serde::Deserialize; use serde::Serialize; +use shlex::try_join; use std::any::Any; use std::fmt::Debug; use std::sync::Arc; @@ -98,3 +101,46 @@ impl Rule for PrefixRule { }) } } + +/// Count how many rules match each provided example and error if any example is unmatched. +pub(crate) fn validate_match_examples(rules: &[RuleRef], matches: &[Vec]) -> Result<()> { + let mut unmatched_examples = Vec::new(); + + for example in matches { + if rules.iter().any(|rule| rule.matches(example).is_some()) { + continue; + } + + unmatched_examples.push( + try_join(example.iter().map(String::as_str)) + .unwrap_or_else(|_| "unable to render example".to_string()), + ); + } + + if unmatched_examples.is_empty() { + Ok(()) + } else { + Err(Error::ExampleDidNotMatch { + rules: rules.iter().map(|rule| format!("{rule:?}")).collect(), + examples: unmatched_examples, + }) + } +} + +/// Ensure that no rule matches any provided negative example. +pub(crate) fn validate_not_match_examples( + rules: &[RuleRef], + not_matches: &[Vec], +) -> Result<()> { + for example in not_matches { + if let Some(rule) = rules.iter().find(|rule| rule.matches(example).is_some()) { + return Err(Error::ExampleDidMatch { + rule: format!("{rule:?}"), + example: try_join(example.iter().map(String::as_str)) + .unwrap_or_else(|_| "unable to render example".to_string()), + }); + } + } + + Ok(()) +}