diff --git a/Cargo.lock b/Cargo.lock index 7167034..1e57c5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -777,7 +777,7 @@ dependencies = [ [[package]] name = "feature-probe-server-sdk" -version = "2.2.0" +version = "2.3.0" dependencies = [ "anyhow", "approx", diff --git a/Cargo.toml b/Cargo.toml index a0e85a2..d6c08f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "feature-probe-server-sdk" -version = "2.2.0" +version = "2.3.0" license = "Apache-2.0" authors = ["maintain@featureprobe.com"] description = "FeatureProbe Server Side SDK for Rust" diff --git a/resources/fixtures/spec b/resources/fixtures/spec index 8cbca35..b271dce 160000 --- a/resources/fixtures/spec +++ b/resources/fixtures/spec @@ -1 +1 @@ -Subproject commit 8cbca353a9cc2c5cc1a99182c473a1c51123a678 +Subproject commit b271dce3831a053d018cdbd4ea9ecc89285a6cc7 diff --git a/src/evaluate.rs b/src/evaluate.rs index 45cda75..7c0886e 100644 --- a/src/evaluate.rs +++ b/src/evaluate.rs @@ -184,31 +184,22 @@ impl Toggle { match self.do_eval(&eval_param, deep) { Ok(eval) => eval, - Err(e) => self.default_variation(&eval_param, Some(e.to_string())), + Err(e) => self.disabled_variation(&eval_param, Some(e.to_string())), } } fn do_eval( &self, eval_param: &EvalParams, - max_deep: u8, + max_depth: u8, ) -> Result, PrerequisiteError> { if !self.enabled { - let v = self.disabled_serve.select_variation(eval_param).ok(); - return Ok(self.serve_variation( - v, - "disabled".to_owned(), - None, - eval_param.debug_until_time, - )); + return Ok(self.disabled_variation(eval_param, None)) } - match self.check_prerequisites(eval_param, max_deep) { - Ok(is_match) if !is_match => { - return Ok(self.default_variation(eval_param, None)); - } - Ok(_is_match) => {} - Err(e) => return Err(e), + if !self.meet_prerequisite(eval_param, max_depth)? { + return Ok(self.disabled_variation(eval_param, Some( + "Prerequisite not match".to_owned()))); } for (i, rule) in self.rules.iter().enumerate() { @@ -237,13 +228,13 @@ impl Toggle { Ok(self.default_variation(eval_param, None)) } - fn check_prerequisites( + fn meet_prerequisite( &self, eval_param: &EvalParams, deep: u8, ) -> Result { if deep == 0 { - return Err(PrerequisiteError::DeepOverflow); + return Err(PrerequisiteError::DepthOverflow); } if let Some(ref prerequisites) = self.prerequisites { @@ -300,10 +291,38 @@ impl Toggle { eval_param: &EvalParams, reason: Option, ) -> EvalDetail { - match self.default_serve.select_variation(eval_param) { + return self.fixed_variation( + &self.default_serve, + eval_param, + "default.".to_owned(), + reason, + ); + } + + fn disabled_variation( + &self, + eval_param: &EvalParams, + reason: Option, + ) -> EvalDetail { + return self.fixed_variation( + &self.disabled_serve, + eval_param, + "disabled.".to_owned(), + reason, + ); + } + + fn fixed_variation( + &self, + serve: &Serve, + eval_param: &EvalParams, + default_reason: String, + reason: Option, + ) -> EvalDetail { + match serve.select_variation(eval_param) { Ok(v) => self.serve_variation( Some(v), - concat_reason("default".to_owned(), reason), + concat_reason(default_reason, reason), None, eval_param.debug_until_time, ), @@ -776,7 +795,7 @@ mod tests { } #[test] - fn test_prerequisite_not_exist() { + fn test_prerequisite_not_exist_should_return_disabled_variation() { let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("resources/fixtures/repo.json"); let json_str = fs::read_to_string(path).unwrap(); @@ -789,12 +808,12 @@ mod tests { let toggle = repo.toggles.get("prerequisite_toggle_not_exist").unwrap(); let r = toggle.eval(&user, &repo.segments, &repo.toggles, false, MAX_DEEP, None); - assert!(r.value.unwrap().as_object().unwrap().get("1").is_some()); + assert!(r.value.unwrap().as_object().unwrap().get("0").is_some()); assert!(r.reason.contains("not exist")); } #[test] - fn test_prerequisite_not_match() { + fn test_prerequisite_not_match_should_return_disabled_variation() { let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("resources/fixtures/repo.json"); let json_str = fs::read_to_string(path).unwrap(); @@ -807,12 +826,12 @@ mod tests { let toggle = repo.toggles.get("prerequisite_toggle_not_match").unwrap(); let r = toggle.eval(&user, &repo.segments, &repo.toggles, false, MAX_DEEP, None); - assert!(r.value.unwrap().as_object().unwrap().get("1").is_some()); - assert!(r.reason.contains("default.")); + assert!(r.value.unwrap().as_object().unwrap().get("0").is_some()); + assert!(r.reason.contains("disabled.")); } #[test] - fn test_prerequisite_max_deep() { + fn test_prerequisite_depth_overflow_should_return_disabled_variation() { let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("resources/fixtures/repo.json"); let json_str = fs::read_to_string(path).unwrap(); @@ -825,8 +844,8 @@ mod tests { let toggle = repo.toggles.get("prerequisite_toggle").unwrap(); let r = toggle.eval(&user, &repo.segments, &repo.toggles, false, 1, None); - assert!(r.value.unwrap().as_object().unwrap().get("1").is_some()); - assert!(r.reason.contains("deep overflow")); + assert!(r.value.unwrap().as_object().unwrap().get("0").is_some()); + assert!(r.reason.contains("depth overflow")); } fn gen_users(num: usize, random: bool) -> Vec { diff --git a/src/lib.rs b/src/lib.rs index 67c6e4f..a2f234e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,8 +52,8 @@ pub enum FPError { #[derive(Debug, Error)] enum PrerequisiteError { - #[error("prerequisite deep overflow")] - DeepOverflow, + #[error("prerequisite depth overflow")] + DepthOverflow, #[error("prerequisite not exist: {0}")] NotExist(String), }