diff --git a/.github/workflows/ci-matrix.yml b/.github/workflows/ci-matrix.yml index 8516d99..8de7d9f 100644 --- a/.github/workflows/ci-matrix.yml +++ b/.github/workflows/ci-matrix.yml @@ -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 @@ -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: @@ -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 diff --git a/Cargo.toml b/Cargo.toml index 605cf90..853b22a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] diff --git a/client-specification b/client-specification index 3d91a8f..d069632 160000 --- a/client-specification +++ b/client-specification @@ -1 +1 @@ -Subproject commit 3d91a8f18e1679994d308e5dde47954ae2def56d +Subproject commit d0696320bb8999acaaaa4b29291ee85e6172d736 diff --git a/src/api.rs b/src/api.rs index 79fbc0c..261a4fa 100644 --- a/src/api.rs +++ b/src/api.rs @@ -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, @@ -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)] @@ -33,7 +33,7 @@ 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>, pub name: String, @@ -41,7 +41,7 @@ pub struct Strategy { } #[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, @@ -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), @@ -60,7 +60,7 @@ 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, @@ -69,7 +69,7 @@ pub struct Variant { } #[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, diff --git a/src/context.rs b/src/context.rs index eb8ff54..89ad438 100644 --- a/src/context.rs +++ b/src/context.rs @@ -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, diff --git a/src/lib.rs b/src/lib.rs index 6335911..cf99657 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,6 +106,8 @@ fn main() -> Result<(), Box> { 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 */