update docs
This commit is contained in:
13
CHANGELOG.md
13
CHANGELOG.md
@@ -8,6 +8,19 @@
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
## axum-valid 0.9.0 (2023-09-29)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Introduced the `ValidEx` type to enhance data validation capabilities.
|
||||||
|
* Added the `Arguments` and `HasValidateArgs` traits to support the use of `ValidEx`.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Upgraded `axum_typed_multipart` to version 0.10.0.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
## axum-valid 0.8.0 (2023-09-19)
|
## axum-valid 0.8.0 (2023-09-19)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
83
README.md
83
README.md
@@ -65,6 +65,86 @@ When validation errors occur, the extractor will automatically return 400 with v
|
|||||||
|
|
||||||
To see how each extractor can be used with `Valid`, please refer to the example in the [documentation](https://docs.rs/axum-valid) of the corresponding module.
|
To see how each extractor can be used with `Valid`, please refer to the example in the [documentation](https://docs.rs/axum-valid) of the corresponding module.
|
||||||
|
|
||||||
|
## Argument-Based Validation
|
||||||
|
|
||||||
|
Here's a basic example of using the `ValidEx` extractor to validate data in a `Form` using arguments:
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
use axum::routing::post;
|
||||||
|
use axum::{Form, Router};
|
||||||
|
use axum_valid::{Arguments, ValidEx};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::ops::{RangeFrom, RangeInclusive};
|
||||||
|
use validator::{Validate, ValidateArgs, ValidationError};
|
||||||
|
|
||||||
|
// NOTE: When some fields use custom validation functions with arguments,
|
||||||
|
// `#[derive(Validate)]` will implement `ValidateArgs` instead of `Validate` for the type.
|
||||||
|
// The validation arguments will be a tuple of all the field validation args.
|
||||||
|
// In this example it is (&RangeInclusive<usize>, &RangeFrom<usize>).
|
||||||
|
// For more detailed information and understanding of `ValidateArgs` and their argument types,
|
||||||
|
// please refer to the `validator` crate documentation.
|
||||||
|
#[derive(Debug, Validate, Deserialize)]
|
||||||
|
pub struct Pager {
|
||||||
|
#[validate(custom(function = "validate_page_size", arg = "&'v_a RangeInclusive<usize>"))]
|
||||||
|
pub page_size: usize,
|
||||||
|
#[validate(custom(function = "validate_page_no", arg = "&'v_a RangeFrom<usize>"))]
|
||||||
|
pub page_no: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_page_size(v: usize, args: &RangeInclusive<usize>) -> Result<(), ValidationError> {
|
||||||
|
args.contains(&v)
|
||||||
|
.then_some(())
|
||||||
|
.ok_or_else(|| ValidationError::new("page_size is out of range"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_page_no(v: usize, args: &RangeFrom<usize>) -> Result<(), ValidationError> {
|
||||||
|
args.contains(&v)
|
||||||
|
.then_some(())
|
||||||
|
.ok_or_else(|| ValidationError::new("page_no is out of range"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Clone is required
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct PagerValidArgs {
|
||||||
|
page_size_range: RangeInclusive<usize>,
|
||||||
|
page_no_range: RangeFrom<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This implementation allows PagerValidArgs to be the second member of ValidEx, and provides arguments for actual validation.
|
||||||
|
// The type mapping <Pager as ValidateArgs<'a>>::Args represents the combination of validators applied on each field of Pager.
|
||||||
|
// get() method returns the validating arguments to be used during validation.
|
||||||
|
impl<'a> Arguments<'a> for PagerValidArgs {
|
||||||
|
type T = Pager;
|
||||||
|
|
||||||
|
// NOTE: <Pager as ValidateArgs<'a>>::Args == (&RangeInclusive<usize>, &RangeFrom<usize>)
|
||||||
|
fn get(&'a self) -> <Pager as ValidateArgs<'a>>::Args {
|
||||||
|
(&self.page_size_range, &self.page_no_range)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn pager_from_form_ex(ValidEx(Form(pager), _): ValidEx<Form<Pager>, PagerValidArgs>) {
|
||||||
|
assert!((1..=50).contains(&pager.page_size));
|
||||||
|
assert!((1..).contains(&pager.page_no));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
let router = Router::new()
|
||||||
|
.route("/form", post(pager_from_form_ex))
|
||||||
|
.with_state(PagerValidArgs {
|
||||||
|
page_size_range: 1..=50,
|
||||||
|
page_no_range: 1..,
|
||||||
|
});
|
||||||
|
// NOTE: The PagerValidArgs can also be stored in a XxxState,
|
||||||
|
// make sure it implements FromRef<XxxState>.
|
||||||
|
|
||||||
|
axum::Server::bind(&([0u8, 0, 0, 0], 8080).into())
|
||||||
|
.serve(router.into_make_service())
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
| Feature | Description | Default | Example | Tests |
|
| Feature | Description | Default | Example | Tests |
|
||||||
@@ -90,8 +170,7 @@ To see how each extractor can be used with `Valid`, please refer to the example
|
|||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
* axum-valid 0.7.x works with axum-extra v0.7.x
|
To determine the compatible versions of `axum-valid`, `axum-extra`, `axum-yaml` and other dependencies that work together, please refer to the dependencies listed in the `Cargo.toml` file. The version numbers listed there will indicate the compatible versions.
|
||||||
* axum-valid 0.8.x works with axum-extra v0.8.x
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
30
src/lib.rs
30
src/lib.rs
@@ -81,17 +81,17 @@ impl<E> Valid<E> {
|
|||||||
|
|
||||||
/// # `ValidEx` data extractor
|
/// # `ValidEx` data extractor
|
||||||
///
|
///
|
||||||
/// `ValidEx` can be used with extractors from the various modules.
|
/// `ValidEx` can be incorporated with extractors from various modules, similar to `Valid`.
|
||||||
/// Refer to the examples for `Valid` in each module - the usage of
|
/// Two differences exist between `ValidEx` and `Valid`:
|
||||||
/// `ValidEx` is similar, except the inner data type implements
|
|
||||||
/// `ValidateArgs` instead of `Validate`.
|
|
||||||
///
|
///
|
||||||
/// `ValidateArgs` is usually automatically implemented by validator's
|
/// - The inner data type in `ValidEx` implements `ValidateArgs` instead of `Validate`.
|
||||||
/// derive macros. Refer to validator's documentation for details.
|
/// - `ValidEx` includes a second field that represents arguments used during validation of the first field.
|
||||||
|
///
|
||||||
|
/// The implementation of `ValidateArgs` is often automatically handled by validator's derive macros
|
||||||
|
/// (for more details, please refer to the validator's documentation).
|
||||||
|
///
|
||||||
|
/// Although current module documentation predominantly showcases `Valid` examples, the usage of `ValidEx` is analogous.
|
||||||
///
|
///
|
||||||
/// Note that the documentation for each module currently only shows
|
|
||||||
/// examples of `Valid`, and does not demonstrate concrete usage of
|
|
||||||
/// `ValidEx`, but the usage is analogous.
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct ValidEx<E, A>(pub E, pub A);
|
pub struct ValidEx<E, A>(pub E, pub A);
|
||||||
|
|
||||||
@@ -154,6 +154,10 @@ fn response_builder(ve: ValidationErrors) -> Response {
|
|||||||
/// validate. `T` must implement the `ValidateArgs` trait which defines the
|
/// validate. `T` must implement the `ValidateArgs` trait which defines the
|
||||||
/// validation logic.
|
/// validation logic.
|
||||||
///
|
///
|
||||||
|
/// It's important to mention that types implementing `Arguments` should be a part of the router's state
|
||||||
|
/// (either through implementing `FromRef<StateType>` or by directly becoming the state)
|
||||||
|
/// to enable automatic arguments retrieval during validation.
|
||||||
|
///
|
||||||
pub trait Arguments<'a> {
|
pub trait Arguments<'a> {
|
||||||
/// The data type to validate using this arguments
|
/// The data type to validate using this arguments
|
||||||
type T: ValidateArgs<'a>;
|
type T: ValidateArgs<'a>;
|
||||||
@@ -163,11 +167,15 @@ pub trait Arguments<'a> {
|
|||||||
|
|
||||||
/// `ValidRejection` is returned when the `Valid` extractor fails.
|
/// `ValidRejection` is returned when the `Valid` extractor fails.
|
||||||
///
|
///
|
||||||
|
/// This enumeration captures two types of errors that can occur when using `Valid`: errors related to the validation
|
||||||
|
/// logic itself (encapsulated in `Valid`), and errors that may arise within the inner extractor (represented by `Inner`).
|
||||||
|
///
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ValidRejection<E> {
|
pub enum ValidRejection<E> {
|
||||||
/// Validation errors
|
/// `Valid` variant captures errors related to the validation logic. It contains `ValidationErrors`
|
||||||
|
/// which is a collection of validation failures for each field.
|
||||||
Valid(ValidationErrors),
|
Valid(ValidationErrors),
|
||||||
/// Inner extractor error
|
/// `Inner` variant represents potential errors that might occur within the inner extractor.
|
||||||
Inner(E),
|
Inner(E),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user