Skip to content
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

feat: add support with rocket_okapi and update crate dependencies #43

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e2cc555
chore(deps): update codecov/codecov-action action to v4.6.0
renovate[bot] Oct 1, 2024
23b85ac
chore(deps): update swatinem/rust-cache action to v2.7.5
renovate[bot] Oct 12, 2024
7f70a6a
chore(deps): update actions/checkout action to v4.2.2
renovate[bot] Oct 23, 2024
a1a8491
fix(deps): update rust crate validator to 0.19.0
renovate[bot] Nov 3, 2024
4513afe
chore(deps): update codecov/codecov-action action to v5
renovate[bot] Dec 5, 2024
637a99b
Merge remote-tracking branch 'origin/renovate/actions-checkout-4.x'
sawa-ko Dec 16, 2024
31e0092
Merge remote-tracking branch 'origin/renovate/codecov-codecov-action-…
sawa-ko Dec 16, 2024
faaa793
Merge remote-tracking branch 'origin/renovate/codecov-codecov-action-…
sawa-ko Dec 16, 2024
451594c
Merge remote-tracking branch 'origin/renovate/swatinem-rust-cache-2.x'
sawa-ko Dec 16, 2024
7145b6c
feat: init compatibility with rocket_okapi
sawa-ko Dec 16, 2024
39cee28
feat: redundante lifetime
sawa-ko Dec 16, 2024
fe01c97
fix: conflicting FromData Validated<Json<_>>
sawa-ko Dec 16, 2024
0335a8d
chore: rework openapi implementation
sawa-ko Dec 17, 2024
14edcd3
feat: init compatibility with rocket_okapi
sawa-ko Dec 17, 2024
7f5fe45
feat: add compatibility with rocket_okapi and FromForm
sawa-ko Dec 17, 2024
d7a949a
fix: validation errors in fromform trait implement
sawa-ko Dec 17, 2024
9923b94
feat: update examples
sawa-ko Dec 17, 2024
891b12f
feat: setup compatibility with rocket_okapi with a crate flag
sawa-ko Dec 17, 2024
d1da022
chore: enable serde_json feature to rocket dep
sawa-ko Dec 17, 2024
266d387
feat: add parse errors too in message validation errors
sawa-ko Dec 17, 2024
1629cdc
feat: add flag to show parser errors in error response
sawa-ko Dec 17, 2024
630fa3c
fix: missing impl for FromFrom of OpenApi for Validated<T>
sawa-ko Dec 23, 2024
054f14f
chore: some code clean up
sawa-ko Dec 23, 2024
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
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ jobs:
runs-on: ${{ matrix.config.node }}
steps:
- name: Checkout repository
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4.2.2

- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.toolchain }}
override: true

- uses: Swatinem/rust-cache@v2.7.3
- uses: Swatinem/rust-cache@v2.7.5

- name: Test Dev
run: cargo test --all-features --workspace
Expand Down Expand Up @@ -89,7 +89,7 @@ jobs:
runs-on: ${{ matrix.config.node }}
steps:
- name: Checkout repository
uses: actions/checkout@v4.1.1
uses: actions/checkout@v4.2.2

- uses: docker-practice/actions-setup-docker@master

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
with:
toolchain: stable

- uses: Swatinem/rust-cache@v2.7.3
- uses: Swatinem/rust-cache@v2.7.5

- name: Run fmt
run: cargo fmt -- --check
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
args: '-- --test-threads 1'

- name: Upload to codecov.io
uses: codecov/codecov-action@v4.0.1
uses: codecov/codecov-action@v5.1.1
with:
token: ${{secrets.CODECOV_TOKEN}}

Expand Down
11 changes: 9 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,23 @@ categories = ["web-programming"]
rust-version = "1.59.0"
description = "Rocket Guards to support validation using validator"

[features]
rocket_okapi = []
parser_errors = []

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
path = "src/lib.rs"

[dependencies]
rocket = { version = "0.5.0", default-features = false, features = [
rocket = { version = "0.5.1", default-features = false, features = [
"json",
"serde_json"
] }
validator = { version = "0.18.0", features = ["derive"] }
validator = { version = "0.19.0", features = ["derive"] }
schemars = "0.8.21"
rocket_okapi = "0.9.0"

[[example]]
name = "json-validation"
Expand Down
9 changes: 3 additions & 6 deletions examples/form-validation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ name = "form-validation"
version = "0.1.0"
edition = "2021"
repository = "https://github.com/somehowchris/rocket-validation"
keywords = ["me"]
categories = ["me"]
rust-version = "1.59.0"
readme = "../.."
license = "MIT"
description = "me"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rocket = { version = "0.5.0-rc.1", features=["json"] }
rocket-validation = { path = "../../" }
validator = "0.16.0"
rocket = { version = "0.5.1", features=["json"] }
rocket-validation = { path = "../.." }
validator = "0.19.0"
10 changes: 4 additions & 6 deletions examples/json-validation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ name = "json-validation"
version = "0.1.0"
edition = "2021"
repository = "https://github.com/somehowchris/rocket-validation"
keywords = ["me"]
categories = ["me"]
rust-version = "1.59.0"
readme = "../.."
license = "MIT"
description = "me"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rocket = { version = "0.5.0-rc.1", features=["json"] }
rocket-validation = { path = "../../" }
validator = "0.16.0"
rocket = { version = "0.5.1", features=["json"] }
rocket-validation = { path = "../.." }
validator = "0.19.0"

9 changes: 3 additions & 6 deletions examples/query-validation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ name = "query-validation"
version = "0.1.0"
edition = "2021"
repository = "https://github.com/somehowchris/rocket-validation"
keywords = ["me"]
categories = ["me"]
rust-version = "1.59.0"
readme = "../.."
license = "MIT"
description = "me"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rocket = { version = "0.5.0-rc.1", features=["json"] }
rocket-validation = { path = "../../" }
validator = "0.16.0"
rocket = { version = "0.5.1", features=["json"] }
rocket-validation = { path = "../.." }
validator = "0.19.0"
75 changes: 74 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub extern crate validator;
#[macro_use]
extern crate rocket;

use std::borrow::Cow;
use rocket::{
data::{Data, FromData, Outcome as DataOutcome},
form,
Expand All @@ -92,7 +93,11 @@ use rocket::{
serde::{json::Json, Serialize},
};
use std::fmt::Debug;
use rocket::form::{Form, Options};
use rocket_okapi::gen::OpenApiGenerator;
use rocket_okapi::okapi::openapi3::Parameter;
pub use validator::{Validate, ValidationErrors};
use validator::ValidationError;

/// Struct used for Request Guards
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -184,7 +189,15 @@ impl<'r, D: Validate + rocket::serde::Deserialize<'r>> FromData<'r> for Validate
let data_outcome = <Json<D> as FromData<'r>>::from_data(req, data).await;

match data_outcome {
Outcome::Error((status, err)) => Outcome::Error((status, Err(err))),
Outcome::Error((status, err)) => {
let mut errors = ValidationErrors::new();

#[cfg(feature = "parser_errors")]
errors.add("Parser", ValidationError::new("Error").with_message(Cow::from(err.to_string())));

req.local_cache(|| CachedValidationErrors(Some(errors)));
Outcome::Error((status, Err(err)))
},
Outcome::Forward(err) => Outcome::Forward(err),
Outcome::Success(data) => match data.validate() {
Ok(_) => Outcome::Success(Validated(data)),
Expand Down Expand Up @@ -288,3 +301,63 @@ impl<'r, T: Validate + FromForm<'r>> FromForm<'r> for Validated<T> {
}
}
}

#[cfg(feature = "rocket_okapi")]
#[rocket::async_trait]
impl<T> rocket_okapi::request::OpenApiFromData<'_> for Validated<Json<T>>
where
T: schemars::JsonSchema + for<'de> rocket::serde::Deserialize<'de> + validator::Validate,
{
fn request_body(gen: &mut OpenApiGenerator) -> rocket_okapi::Result<rocket_okapi::okapi::openapi3::RequestBody> {
Json::<T>::request_body(gen)
}
}

#[cfg(feature = "rocket_okapi")]
#[rocket::async_trait]
impl<'r, T> FromData<'r> for Validated<Form<T>>
where
T: FromForm<'r> + Validate,
{
type Error = Result<ValidationErrors, form::Errors<'r>>;

async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> DataOutcome<'r, Self> {
let data_outcome = <Form<T> as FromData<'r>>::from_data(req, data).await;

match data_outcome {
DataOutcome::Error((status, err)) => DataOutcome::Error((status, Err(err))),
DataOutcome::Forward(f) => DataOutcome::Forward(f),
DataOutcome::Success(form) => {
let inner = form.into_inner();
match inner.validate() {
Ok(_) => DataOutcome::Success(Validated(rocket::form::Form::from(inner))),
Err(err) => {
req.local_cache(|| CachedValidationErrors(Some(err.to_owned())));
DataOutcome::Error((Status::UnprocessableEntity, Ok(err)))
}
}
}
}
}
}

#[cfg(feature = "rocket_okapi")]
#[rocket::async_trait]
impl<'r, T> rocket_okapi::request::OpenApiFromData<'r> for Validated<Form<T>>
where
T: schemars::JsonSchema + FromForm<'r> + 'static + validator::Validate,
{
fn request_body(gen: &mut OpenApiGenerator) -> rocket_okapi::Result<rocket_okapi::okapi::openapi3::RequestBody> {
Form::<T>::request_body(gen)
}
}

#[cfg(feature = "rocket_okapi")]
impl<'r, T> rocket_okapi::request::OpenApiFromForm<'r> for Validated<T>
where
T: schemars::JsonSchema + FromForm<'r> + 'static + validator::Validate,
{
fn form_multi_parameter(gen: &mut OpenApiGenerator, name: String, required: bool) -> rocket_okapi::Result<Vec<Parameter>> {
T::form_multi_parameter(gen, name, required)
}
}