Skip to content

Commit df53044

Browse files
authored
Minimize exposed API (#29)
closes #7 Minimizes the exposed public API (removes some methods in the `Feature` and `Property` trait that were exposing _private_ `models`): ![image](https://github.com/user-attachments/assets/d07a8adf-6034-408c-8b7b-9ec001055b84) In another PR, we could merge `Value` and `entity::AttrValue`, they offer basically the same functionality, wdyt?
2 parents 25ed7ff + 9714156 commit df53044

File tree

16 files changed

+88
-147
lines changed

16 files changed

+88
-147
lines changed

examples/demo.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414

1515
use std::{collections::HashMap, env, thread, time::Duration};
1616

17-
use appconfiguration_rust_sdk::{client::AppConfigurationClient, AttrValue, Entity, Feature, Property};
17+
use appconfiguration_rust_sdk::{
18+
AppConfigurationClient, AttrValue, Entity, Feature, Property, Value,
19+
};
1820
use dotenvy::dotenv;
1921
use std::error::Error;
2022

21-
type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
22-
2323
#[derive(Debug)]
2424
struct CustomerEntity {
2525
id: String,
@@ -33,16 +33,14 @@ impl Entity for CustomerEntity {
3333
}
3434

3535
fn get_attributes(&self) -> HashMap<String, AttrValue> {
36-
use AttrValue;
37-
3836
HashMap::from_iter(vec![
3937
("city".to_string(), AttrValue::String(self.city.clone())),
4038
("radius".to_string(), AttrValue::Numeric(self.radius as f64)),
4139
])
4240
}
4341
}
4442

45-
fn main() -> Result<()> {
43+
fn main() -> std::result::Result<(), Box<dyn Error>> {
4644
dotenv().ok();
4745
let region = env::var("REGION").expect("REGION should be set.");
4846
let guid = env::var("GUID").expect("GUID should be set.");
@@ -70,13 +68,15 @@ fn main() -> Result<()> {
7068
match client.get_feature_proxy(&feature_id) {
7169
Ok(feature) => {
7270
println!("Feature name: {}", feature.get_name()?);
73-
println!("Feature id: {}", feature.get_id());
74-
println!("Feature data type: {}", feature.get_data_type()?);
71+
let value = feature.get_value(&entity)?;
72+
let data_type = match &value {
73+
Value::Numeric(_) => "Numeric",
74+
Value::String(_) => "String",
75+
Value::Boolean(_) => "Boolean",
76+
};
77+
println!("Feature data type: {}", data_type);
7578
println!("Is feature enabled: {}", feature.is_enabled()?);
76-
println!(
77-
"Feature evaluated value is: {:?}",
78-
feature.get_value(&entity)?
79-
);
79+
println!("Feature evaluated value is: {value:?}");
8080
}
8181
Err(error) => {
8282
println!("There was an error getting the Feature Flag. Error {error}",);
@@ -87,12 +87,14 @@ fn main() -> Result<()> {
8787
match client.get_property_proxy(&property_id) {
8888
Ok(property) => {
8989
println!("Property name: {}", property.get_name()?);
90-
println!("Property id: {}", property.get_id());
91-
println!("Property data type: {}", property.get_data_type()?);
92-
println!(
93-
"Property evaluated value is: {:?}",
94-
property.get_value(&entity)?
95-
);
90+
let value = property.get_value(&entity)?;
91+
let data_type = match &value {
92+
Value::Numeric(_) => "Numeric",
93+
Value::String(_) => "String",
94+
Value::Boolean(_) => "Boolean",
95+
};
96+
println!("Property data type: {data_type}");
97+
println!("Property evaluated value is: {value:?}");
9698
}
9799
Err(error) => {
98100
println!("There was an error getting the Property. Error {error}",);

src/client/feature_proxy.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::io::Cursor;
1717
use murmur3::murmur3_32;
1818

1919
use crate::entity::Entity;
20-
use crate::Feature;
20+
use crate::{Feature, Value};
2121

2222
use super::feature_snapshot::FeatureSnapshot;
2323
use super::AppConfigurationClient;
@@ -38,29 +38,15 @@ impl<'a> FeatureProxy<'a> {
3838
}
3939

4040
impl<'a> Feature for FeatureProxy<'a> {
41-
fn get_id(&self) -> &str {
42-
&self.feature_id
43-
}
44-
4541
fn get_name(&self) -> crate::errors::Result<String> {
4642
self.client.get_feature(&self.feature_id)?.get_name()
4743
}
4844

49-
fn get_data_type(&self) -> crate::errors::Result<crate::models::ValueKind> {
50-
self.client.get_feature(&self.feature_id)?.get_data_type()
51-
}
52-
5345
fn is_enabled(&self) -> crate::errors::Result<bool> {
5446
self.client.get_feature(&self.feature_id)?.is_enabled()
5547
}
5648

57-
fn get_enabled_value(&self) -> crate::errors::Result<crate::models::ConfigValue> {
58-
self.client
59-
.get_feature(&self.feature_id)?
60-
.get_enabled_value()
61-
}
62-
63-
fn get_value(&self, entity: &impl Entity) -> crate::errors::Result<super::value::Value> {
49+
fn get_value(&self, entity: &impl Entity) -> crate::errors::Result<Value> {
6450
self.client.get_feature(&self.feature_id)?.get_value(entity)
6551
}
6652
}

src/client/feature_snapshot.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use crate::client::value::{NumericValue, Value};
15+
use crate::value::{NumericValue, Value};
1616
use crate::entity::Entity;
1717
use crate::Feature;
1818
use std::collections::HashMap;
@@ -102,26 +102,14 @@ impl FeatureSnapshot {
102102
}
103103

104104
impl Feature for FeatureSnapshot {
105-
fn get_id(&self) -> &str {
106-
&self.feature.feature_id
107-
}
108-
109105
fn get_name(&self) -> Result<String> {
110106
Ok(self.feature.name.clone())
111107
}
112108

113-
fn get_data_type(&self) -> Result<crate::models::ValueKind> {
114-
Ok(self.feature.kind)
115-
}
116-
117109
fn is_enabled(&self) -> Result<bool> {
118110
Ok(self.feature.enabled)
119111
}
120112

121-
fn get_enabled_value(&self) -> Result<crate::models::ConfigValue> {
122-
Ok(self.feature.enabled_value.clone())
123-
}
124-
125113
fn get_value(&self, entity: &impl Entity) -> Result<Value> {
126114
let model_value = self.evaluate_feature_for_entity(entity)?;
127115

@@ -151,11 +139,8 @@ impl Feature for FeatureSnapshot {
151139
pub mod tests {
152140

153141
use super::*;
154-
use crate::{
155-
entity,
156-
models::{ConfigValue, Segment, SegmentRule, Segments, TargetingRule, ValueKind},
157-
AttrValue,
158-
};
142+
use crate::entity::AttrValue;
143+
use crate::models::{ConfigValue, Segment, SegmentRule, Segments, TargetingRule, ValueKind};
159144
use rstest::rstest;
160145

161146
#[rstest]

src/client/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
mod app_configuration_client;
1616

1717
pub(crate) mod cache;
18-
pub mod feature_snapshot;
18+
pub(crate) mod feature_snapshot;
1919
pub(crate) mod feature_proxy;
2020
pub(crate) mod http;
21-
pub mod property_snapshot;
21+
pub(crate) mod property_snapshot;
2222
pub(crate) mod property_proxy;
23-
pub mod value;
23+
2424

2525
pub use app_configuration_client::AppConfigurationClient;
2626

src/client/property_proxy.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414

1515
use crate::Property;
1616

17-
use crate::entity::Entity;
18-
1917
use super::property_snapshot::PropertySnapshot;
2018
use super::AppConfigurationClient;
19+
use crate::value::Value;
20+
use crate::Entity;
2121

2222
pub struct PropertyProxy<'a> {
2323
client: &'a AppConfigurationClient,
@@ -38,25 +38,11 @@ impl<'a> PropertyProxy<'a> {
3838
}
3939

4040
impl<'a> Property for PropertyProxy<'a> {
41-
fn get_id(&self) -> &str {
42-
&self.property_id
43-
}
44-
4541
fn get_name(&self) -> crate::errors::Result<String> {
4642
self.client.get_property(&self.property_id)?.get_name()
4743
}
4844

49-
fn get_data_type(&self) -> crate::errors::Result<crate::models::ValueKind> {
50-
self.client.get_property(&self.property_id)?.get_data_type()
51-
}
52-
53-
fn get_value_default(&self) -> crate::errors::Result<crate::models::ConfigValue> {
54-
self.client
55-
.get_property(&self.property_id)?
56-
.get_value_default()
57-
}
58-
59-
fn get_value(&self, entity: &impl Entity) -> crate::errors::Result<super::value::Value> {
45+
fn get_value(&self, entity: &impl Entity) -> crate::errors::Result<Value> {
6046
self.client
6147
.get_property(&self.property_id)?
6248
.get_value(entity)

src/client/property_snapshot.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use crate::client::value::{NumericValue, Value};
15+
use crate::value::{NumericValue, Value};
1616
use crate::entity::Entity;
1717
use crate::Property;
1818
use std::collections::HashMap;
@@ -63,22 +63,10 @@ impl PropertySnapshot {
6363
}
6464

6565
impl Property for PropertySnapshot {
66-
fn get_id(&self) -> &str {
67-
&self.property.property_id
68-
}
69-
7066
fn get_name(&self) -> Result<String> {
7167
Ok(self.property.name.clone())
7268
}
7369

74-
fn get_data_type(&self) -> Result<crate::models::ValueKind> {
75-
Ok(self.property.kind)
76-
}
77-
78-
fn get_value_default(&self) -> Result<crate::models::ConfigValue> {
79-
Ok(self.property.value.clone())
80-
}
81-
8270
fn get_value(&self, entity: &impl Entity) -> Result<Value> {
8371
let model_value = self.evaluate_feature_for_entity(entity)?;
8472

@@ -104,14 +92,11 @@ impl Property for PropertySnapshot {
10492
}
10593
}
10694

107-
10895
#[cfg(test)]
10996
pub mod tests {
11097
use super::*;
111-
use crate::{
112-
models::{ConfigValue, Segment, SegmentRule, Segments, TargetingRule, ValueKind},
113-
AttrValue,
114-
};
98+
use crate::entity::AttrValue;
99+
use crate::models::{ConfigValue, Segment, SegmentRule, Segments, TargetingRule, ValueKind};
115100

116101
#[test]
117102
fn test_get_value_segment_with_default_value() {

src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::sync::PoisonError;
22

33
use thiserror::Error;
44

5-
use crate::segment_evaluation::SegmentEvaluationError;
5+
use crate::segment_evaluation::errors::SegmentEvaluationError;
66

77
pub type Result<T> = std::result::Result<T, Error>;
88

src/feature.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,13 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use crate::client::value::Value;
1615
use crate::errors::Result;
17-
use crate::Entity;
16+
use crate::{Entity, Value};
1817

1918
pub trait Feature {
20-
fn get_id(&self) -> &str;
21-
2219
fn get_name(&self) -> Result<String>;
2320

24-
fn get_data_type(&self) -> Result<crate::models::ValueKind>;
25-
2621
fn is_enabled(&self) -> Result<bool>;
2722

28-
fn get_enabled_value(&self) -> Result<crate::models::ConfigValue>;
29-
3023
fn get_value(&self, entity: &impl Entity) -> Result<Value>;
3124
}

src/lib.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,21 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
pub mod client;
16-
pub mod entity;
17-
pub mod errors;
18-
pub mod models;
19-
mod segment_evaluation;
15+
mod client;
16+
mod entity;
17+
mod errors;
2018
mod feature;
19+
mod models;
2120
mod property;
21+
mod segment_evaluation;
22+
mod value;
2223

24+
pub use client::AppConfigurationClient;
25+
pub use entity::{Entity, AttrValue};
2326
pub use feature::Feature;
2427
pub use property::Property;
25-
pub use entity::{AttrValue, Entity};
28+
pub use value::Value;
29+
pub use errors::{Result, Error};
2630

2731
#[cfg(test)]
2832
mod tests;

src/models.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub(crate) struct Property {
6666
}
6767

6868
#[derive(Copy, Clone, Debug, Deserialize, PartialEq)]
69-
pub enum ValueKind {
69+
pub(crate) enum ValueKind {
7070
#[serde(rename(deserialize = "NUMERIC"))]
7171
Numeric,
7272
#[serde(rename(deserialize = "BOOLEAN"))]
@@ -87,7 +87,7 @@ impl Display for ValueKind {
8787
}
8888

8989
#[derive(Debug, Clone, Deserialize)]
90-
pub struct ConfigValue(pub(crate) serde_json::Value);
90+
pub(crate) struct ConfigValue(pub(crate) serde_json::Value);
9191

9292
impl ConfigValue {
9393
pub fn as_i64(&self) -> Option<i64> {
@@ -133,27 +133,27 @@ pub(crate) struct SegmentRule {
133133
}
134134

135135
#[derive(Debug, Deserialize, Clone)]
136-
pub struct TargetingRule {
136+
pub(crate) struct TargetingRule {
137137
pub rules: Vec<Segments>,
138138
pub value: ConfigValue,
139139
pub order: u32,
140140
pub rollout_percentage: Option<ConfigValue>,
141141
}
142142

143143
#[derive(Debug, Deserialize, Clone)]
144-
pub struct Segments {
144+
pub(crate) struct Segments {
145145
pub segments: Vec<String>,
146146
}
147147

148148
#[cfg(test)]
149-
pub mod tests {
149+
pub(crate) mod tests {
150150

151151
use super::*;
152152
use rstest::*;
153153
use std::{fs, path::PathBuf};
154154

155155
#[fixture]
156-
pub fn example_configuration_enterprise() -> Configuration {
156+
pub(crate) fn example_configuration_enterprise() -> Configuration {
157157
// Create a configuration object from the data files
158158

159159
let mut mocked_data = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
@@ -166,7 +166,7 @@ pub mod tests {
166166
}
167167

168168
#[fixture]
169-
pub fn configuration_feature1_enabled() -> Configuration {
169+
pub(crate) fn configuration_feature1_enabled() -> Configuration {
170170
Configuration {
171171
environments: vec![Environment {
172172
name: "name".to_string(),
@@ -189,7 +189,7 @@ pub mod tests {
189189
}
190190

191191
#[fixture]
192-
pub fn configuration_property1_enabled() -> Configuration {
192+
pub(crate) fn configuration_property1_enabled() -> Configuration {
193193
Configuration {
194194
environments: vec![Environment {
195195
name: "name".to_string(),

0 commit comments

Comments
 (0)