Skip to content

Spec-update-1 #42

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/ci-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --features ${{ matrix.features }}
args: --no-default-features --features strict,${{ matrix.features }}

- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features --features ${{ matrix.features }}
args: --no-default-features --features strict,${{ matrix.features }}

clippy:
runs-on: ubuntu-latest
Expand All @@ -59,13 +59,13 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: build
args: --features surf-client,reqwest-client,reqwest-client-rustls --all-targets
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls --all-targets

- uses: actions-rs/cargo@v1
# We test with all-features to ensure that that does build
# We test with approximately all-features to ensure that that does build (excludes nightly only backtrace)
with:
command: test
args: --features surf-client,reqwest-client,reqwest-client-rustls --all-targets
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls --all-targets

- uses: actions-rs/cargo@v1
with:
Expand All @@ -75,4 +75,4 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: clippy
args: --features surf-client,reqwest-client,reqwest-client-rustls --all-targets -- -D warnings
args: --features strict,surf-client,reqwest-client,reqwest-client-rustls --all-targets -- -D warnings
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ functional = []
reqwest-client = ["reqwest", "reqwest/default-tls"]
# For users that don't want to depend on OpenSSL.
reqwest-client-rustls = ["reqwest", "reqwest/rustls-tls"]
# To error if an unsupported API feature is present
strict = []
# For use with --no-default-features
surf-client = ["surf", "async-std"]

Expand Down
15 changes: 8 additions & 7 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use chrono::Utc;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
// #[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct Features {
pub version: u8,
pub features: Vec<Feature>,
Expand All @@ -20,7 +20,7 @@ impl Features {
}

#[derive(Clone, Serialize, Deserialize, Debug)]
// #[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct Feature {
pub name: String,
#[serde(default)]
Expand All @@ -33,15 +33,15 @@ pub struct Feature {
}

#[derive(Clone, Default, Serialize, Deserialize, Debug)]
// #[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct Strategy {
pub constraints: Option<Vec<Constraint>>,
pub name: String,
pub parameters: Option<HashMap<String, String>>,
}

#[derive(Clone, Serialize, Deserialize, Debug)]
// #[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct Constraint {
#[serde(rename = "contextName")]
pub context_name: String,
Expand All @@ -51,7 +51,7 @@ pub struct Constraint {

#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(tag = "operator", content = "values")]
// #[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub enum ConstraintExpression {
#[serde(rename = "IN")]
In(Vec<String>),
Expand All @@ -60,16 +60,17 @@ pub enum ConstraintExpression {
}

#[derive(Clone, Serialize, Deserialize, Debug)]
// #[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct Variant {
pub name: String,
pub weight: u8,
pub payload: Option<HashMap<String, String>>,
pub overrides: Option<Vec<VariantOverride>>,
pub stickiness: Option<String>,
}

#[derive(Clone, Serialize, Deserialize, Debug)]
// #[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct VariantOverride {
#[serde(rename = "contextName")]
pub context_name: String,
Expand Down
3 changes: 3 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,7 @@ mod tests {
"type".into() => "string".into(),
"value".into() => "val1".into()]),
overrides: None,
stickiness: None,
}]),
name: "one".into(),
strategies: vec![],
Expand All @@ -1132,6 +1133,7 @@ mod tests {
"type".into() => "string".into(),
"value".into() => "val1".into()]),
overrides: None,
stickiness: None,
},
api::Variant {
name: "varianttwo".into(),
Expand All @@ -1140,6 +1142,7 @@ mod tests {
"type".into() => "string".into(),
"value".into() => "val2".into()]),
overrides: None,
stickiness: None,
},
]),
name: "two".into(),
Expand Down
2 changes: 1 addition & 1 deletion src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<'de> de::Deserialize<'de> for IPAddress {
}

#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
#[cfg_attr(feature = "strict", serde(deny_unknown_fields))]
pub struct Context {
#[serde(rename = "userId")]
pub user_id: Option<String>,
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
Enables reqwest with OpenSSL TLS support
* **reqwest-client-rustls** -
Enables reqwest with RusTLS support
* **strict** -
Turn unexpected fields in API responses into errors
* **surf-client** -
Enables Surf as the HTTP client to retrieve flags
*/
Expand Down
16 changes: 15 additions & 1 deletion src/strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,21 @@ fn _user_id<S: BuildHasher>(
})
}

// Build a closure to handle customField rollouts, parameterised by groupId and
// a metaparameter of the percentage taken from rollout_key.
fn _custom_field<S: BuildHasher>(
parameters: Option<HashMap<String, String, S>>,
rollout_key: &str,
) -> Evaluate {
let (group, rollout) = group_and_rollout(&parameters, rollout_key);
Box::new(move |context: &Context| -> bool {
let variable = context.properties.get("customField");
partial_rollout(&group, variable, rollout)
})
}

/// <https://docs.getunleash.io/user_guide/activation_strategy#gradual-rollout>
/// stickiness: [default|userId|sessionId|random]
/// stickiness: [default|userId|sessionId|random|customField]
/// groupId: hash key
/// rollout: percentage
pub fn flexible_rollout<S: BuildHasher>(
Expand All @@ -162,6 +175,7 @@ pub fn flexible_rollout<S: BuildHasher>(
} else {
return Box::new(|_| false);
} {
"customField" => _custom_field(parameters, "rollout"),
"default" => {
// user, session, random in that order.
let (group, rollout) = group_and_rollout(&parameters, "rollout");
Expand Down