//! Run with //! //! ```not_rust //! cargo run --example axum --features="full" //! //! curl '127.0.0.1:3000?title=' //! -> Input validation error: [[title], msg:[title is required,title should be starts with `hi`,]] //! //! curl '127.0.0.1:3000?title=hihihi' //! ->

Hello, hihihi!

//! ``` use std::net::SocketAddr; use axum::{ extract::{rejection::FormRejection, Form}, http::StatusCode, response::{Html, IntoResponse, Response}, routing::get, Router, }; use serde::{Deserialize, Serialize}; use thiserror::Error; use valitron::{ available::{Required, StartWith}, register::ValidatorError, RuleExt, Validatable, Validator, }; #[tokio::main] async fn main() { let app = Router::new().route("/", get(handler)); // run it let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); println!("listening on {}", addr); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } #[derive(Debug, Serialize, Deserialize)] pub struct BlogInput { pub title: String, } async fn handler(Form(input): Form) -> Result, ServerError> { input.validate( Validator::new() .rule("title", Required.and(StartWith("hi"))) .map(String::from) .message([ ("title.required", "title is required"), ("title.start_with", "title should be starts with `hi`"), ]), )?; Ok(Html(format!("

Hello, {}!

", input.title))) } #[derive(Debug, Error)] pub enum ServerError { #[error(transparent)] ValidationError(#[from] ValidatorError), #[error(transparent)] AxumFormRejection(#[from] FormRejection), } impl IntoResponse for ServerError { fn into_response(self) -> Response { match self { ServerError::ValidationError(msg) => { let mut result = String::new(); for (name, msg_vec) in msg.iter() { result.push_str(&format!("[{}]", name.as_str())); result.push_str(", msg:["); for msg in msg_vec.iter() { result.push_str(msg.as_str()); result.push(','); } result.push(']'); } let message = format!("Input validation error: [{}]", result); (StatusCode::BAD_REQUEST, message) } ServerError::AxumFormRejection(_) => (StatusCode::BAD_REQUEST, self.to_string()), } .into_response() } }