Repository navigation
feat: Evaluate flags that depend on other flags #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
0131309
51052f5
0552139
92e1965
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| [submodule "tests/engine_tests/engine-test-data"] | ||
| path = tests/engine_tests/engine-test-data | ||
| url = https://github.com/flagsmith/engine-test-data.git | ||
| branch = v3.7.0 | ||
| branch = v3.12.1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ use crate::environments::Environment; | |
| use crate::features::{FeatureState, MultivariateFeatureStateValue}; | ||
| use crate::identities::{Identity, Trait}; | ||
| use crate::segments::{Segment, SegmentRule as OldSegmentRule}; | ||
| use indexmap::IndexMap; | ||
| use sha2::{Digest, Sha256}; | ||
| use std::collections::HashMap; | ||
|
|
||
|
|
@@ -24,7 +25,7 @@ pub fn environment_to_context(environment: Environment) -> EngineEvaluationConte | |
| name: environment.name.clone(), | ||
| }, | ||
| features: HashMap::new(), | ||
| segments: HashMap::new(), | ||
| segments: IndexMap::new(), | ||
| identity: None, | ||
| }; | ||
|
|
||
|
|
@@ -91,6 +92,7 @@ fn map_multivariate_values_to_variants( | |
| mv_values | ||
| .iter() | ||
| .map(|mv| FeatureValue { | ||
| key: None, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| value: mv.multivariate_feature_option.value.clone(), | ||
| weight: mv.percentage_allocation as f64, | ||
| priority: None, | ||
|
|
@@ -340,3 +342,36 @@ pub fn add_identity_to_context( | |
| new_context.identity = Some(identity); | ||
| new_context | ||
| } | ||
|
|
||
| /// Gets the context to evaluate environment flags against | ||
| /// | ||
| /// # Arguments | ||
| /// * `context` - The context to evaluate environment flags for | ||
| /// | ||
| /// # Returns | ||
| /// A new context without identity, keeping only segments whose every condition reads the environment or other flags | ||
| pub fn remove_identity_from_context(context: &EngineEvaluationContext) -> EngineEvaluationContext { | ||
| EngineEvaluationContext { | ||
| environment: context.environment.clone(), | ||
| features: context.features.clone(), | ||
| segments: context | ||
| .segments | ||
| .iter() | ||
| .filter(|(_, segment)| is_identity_free(&segment.rules)) | ||
| .map(|(key, segment)| (key.clone(), segment.clone())) | ||
| .collect(), | ||
| identity: None, | ||
| } | ||
| } | ||
|
|
||
| fn is_identity_free(rules: &[SegmentRule]) -> bool { | ||
| const IDENTITY_FREE_PROPERTY_PREFIXES: [&str; 4] = | ||
| ["$.environment.", "$.environment[", "$.flags.", "$.flags["]; | ||
| rules.iter().all(|rule| { | ||
| rule.conditions.iter().all(|condition| { | ||
| IDENTITY_FREE_PROPERTY_PREFIXES | ||
| .iter() | ||
| .any(|prefix| condition.property.starts_with(prefix)) | ||
| }) && is_identity_free(&rule.rules) | ||
| }) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: Flagsmith/flagsmith-rust-flag-engine
Length of output: 1179
Script executed:
Repository: Flagsmith/flagsmith-rust-flag-engine
Length of output: 4334
Web query:
Rust Reference struct expressions all fields must be specified missing field error E0063 external crate non_exhaustiveResult:
Mark the
FeatureValue.keyaddition as a breaking change, or keep the struct closed to external literals.FeatureValueis a public struct with all fields public and no#[non_exhaustive]. Downstream crates that build it with a struct literal now fail to compile, because the newkeyfield is not supplied. Serde'sdefaultdoes not apply to Rust struct literals. The in-repo literal insrc/engine_eval/mappers.rsalready setskey: None, so the crate itself builds. Release tooling derives versions from commit messages (CHANGELOG.mdshows release-please entries), so a non-breakingfeat:commit can ship this break in a compatible version. Mark the change as breaking (feat!:or aBREAKING CHANGE:footer) so the release is versioned as breaking. If source compatibility must be kept, do not add a public field to this struct.No safe localized edit is established, so this comment has no diff.