Conversation
041fa03 to
f6444c2
Compare
atennak1
approved these changes
Apr 21, 2026
Zee2413
reviewed
Apr 22, 2026
Zee2413
reviewed
Apr 22, 2026
Zee2413
approved these changes
Apr 22, 2026
kddejong
requested changes
Apr 24, 2026
kddejong
left a comment
There was a problem hiding this comment.
Blanket pub visibility is a blocker
The extraction is mechanically sound — CI is green, backward compat is preserved via the re-export bridge. But every pub(crate) was changed to pub without selectivity, exposing 345 items as public API when the stated use cases only need ~30.
Key concerns
libyaml/*is fully exposed, includingpub unsafe fn convert_event. None of this is consumer API.parser.rs: 28 of 30 items are internal nom combinators (comment2,white_space,preceded_by, etc.). Onlyrules_fileneeds to be public.eval.rs: 10 of 12 items are internal dispatch functions. Onlyeval_rules_fileis an entry point.eval/operators.rs: 21 internal comparison structs/traits (LhsRhsPair,QueryIn,Comparator, etc.) no consumer needs.- All struct fields are
pub, freezing internal layout as API. RenamingBlockCheck.at_least_one_matchesor changingMessages.error_messagebecomes a breaking change.
At v1.0.0 this is permanent
Every signature, field, and trait is a semver commitment. Shipping 345 pub items at 1.0.0 means any future cleanup is a breaking change.
Suggestion
Keep modules pub(crate) by default and re-export a curated surface from lib.rs:
pub use parser::rules_file;
pub use eval::eval_rules_file;
pub use eval_context::{simplified_json_from_root, FileReport, RuleReport, ClauseReport};
pub use path_value::{PathAwareValue, Path, Location};
pub use values::{read_from, MarkedValue};
// ~30 items totalOr ship at 0.1.0 to signal the API is unstable and iterate toward a curated 1.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR extracts the core Guard DSL engine (parser, AST, evaluator, path-value system, and built-in functions) from the
guardCLI crate into a new standaloneguard-langlibrary crate. This enables third-party Rust projects to embed the Guard policy-as-code evaluation engine without depending on the CLI binary or its command infrastructure.Motivation
Previously, the Guard DSL internals lived under
guard/src/rules/withpub(crate)visibility, making it impossible for external consumers to programmatically parse rules, evaluate policies, or inspect evaluation results. By extracting these intoguard-lang, users can:parser::rules_file)eval::eval_rules_file)eval_context::simplified_json_from_root)What Changed
1. New crate:
guard-langguard-lang/Cargo.toml(v1.0.0, edition 2018, Apache-2.0) with the same core dependencies asguard(nom, serde, fancy-regex, chrono, etc.)Cargo.toml2. File moves (
guard/src/rules/→guard-lang/src/)eval.rs,eval_context.rs,evaluate.rsparser.rsexprs.rspath_value.rs+path_value/traversal.rsvalues.rserrors.rs,display.rsfunctions/libyaml/3. Visibility changes
All
pub(crate)andpub(in crate::rules)changed topubacross all moved files. This includes structs, enums, traits, functions, and struct fields.4. Import path rewriting
All
crate::rules::Xpaths rewritten tocrate::X:5. Re-export bridge
guard/src/rules/mod.rsreduced to:This maintains backward compatibility for all existing code in the
guardcrate.6.
print_verbose_treemovedThe pretty-print tree function moved from
guard/src/commands/validate.rstoguard-lang/src/eval_context.rs, with the signature generalized from&mut Writerto&mut dyn std::io::Write. Thevalidate.rsbridge delegates to it.7. Disjunction context string fix
eval_conjunction_clausesnow uses the short type name (e.g.,GuardClause) instead of the full path (cfn_guard::rules::exprs::GuardClause) in disjunction context strings. The same fix applied inevaluate.rsusingstd::any::type_namecomparison. Test output.outfiles updated accordingly.Before:
After:
8.
read_file_contentaddedA new
read_file_content(File) -> Result<String>utility added toguard-lang/src/lib.rsso tests inevaluate_tests.rsdon't depend onguard::commands::files.9. Test path sanitization
guard/tests/utils.rsupdated to also replaceCARGO_MANIFEST_DIRin test output sanitization, handling paths outside$HOME.10. Asset files
cfn-lambda.yamlandcfn-template.jsoncopied toguard-lang/assets/for tests that reference them.