growthbook_sdk_rust/feature/
use_case.rs

1use std::collections::HashMap;
2
3use crate::dto::{GrowthBookFeature, GrowthBookFeatureRule};
4use crate::model_private::FeatureResult;
5use crate::model_public::GrowthBookAttribute;
6
7impl GrowthBookFeature {
8    pub fn get_value(
9        &self,
10        feature_name: &str,
11        feature_name_decorate: Vec<String>,
12        user_attributes: &Vec<GrowthBookAttribute>,
13        forced_variations: &Option<HashMap<String, i64>>,
14        all_features: HashMap<String, GrowthBookFeature>,
15    ) -> FeatureResult {
16        if let Some(rules) = &self.rules {
17            for rule in rules {
18                match rule {
19                    GrowthBookFeatureRule::Force(it) => {
20                        if let Some(feature) = it.get_match_value(feature_name, user_attributes) {
21                            return feature;
22                        }
23                    },
24                    GrowthBookFeatureRule::Rollout(it) => {
25                        if let Some(feature) = it.get_match_value(feature_name, user_attributes) {
26                            return feature;
27                        }
28                    },
29                    GrowthBookFeatureRule::Experiment(it) => {
30                        if let Some(feature) = it.get_match_value(feature_name, user_attributes, forced_variations) {
31                            return feature;
32                        }
33                    },
34                    GrowthBookFeatureRule::Parent(it) => {
35                        for parent in &it.parent_conditions {
36                            let parent_feature_name = &parent.id;
37                            if feature_name_decorate.contains(parent_feature_name) {
38                                return FeatureResult::cyclic_prerequisite();
39                            }
40
41                            let mut updated_decorate = feature_name_decorate.clone();
42                            updated_decorate.push(String::from(feature_name));
43
44                            let parent_response = if let Some(parent_feature) = all_features.get(parent_feature_name) {
45                                parent_feature.get_value(parent_feature_name, updated_decorate, user_attributes, forced_variations, all_features.clone())
46                            } else {
47                                FeatureResult::unknown_feature()
48                            };
49
50                            if parent_response.source == "cyclicPrerequisite" {
51                                return FeatureResult::cyclic_prerequisite();
52                            }
53
54                            if !parent.is_met(parent_response) {
55                                return FeatureResult::prerequisite();
56                            }
57                        }
58                    },
59                    GrowthBookFeatureRule::Empty(_) => {
60                        continue;
61                    },
62                }
63            }
64        }
65
66        FeatureResult::from_default_value(self.default_value.clone())
67    }
68}