Skip to content

Commit 96f8e92

Browse files
feat: add serde and utoipa support
1 parent 6b71fec commit 96f8e92

28 files changed

Lines changed: 891 additions & 9 deletions

File tree

Cargo.lock

Lines changed: 636 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = ["example", "packages/*"]
2+
members = ["examples/*", "packages/*"]
33
resolver = "2"
44

55
[workspace.package]
@@ -16,6 +16,7 @@ regex = "1.12.2"
1616
serde = "1.0.228"
1717
serde_json = "1.0.145"
1818
tokio = "1.48.0"
19+
utoipa = "5.4.0"
1920

2021
[workspace.lints.rust]
2122
unsafe_code = "deny"

deny.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
all-features = true
33

44
[advisories]
5-
ignore = []
5+
ignore = [
6+
{ id = "RUSTSEC-2024-0436", reason = "No maintained version available for `paste`." },
7+
]
68

79
[bans]
810
allow-wildcard-paths = true
911
multiple-versions = "allow"
1012
wildcards = "deny"
1113

1214
[licenses]
13-
allow = ["MIT", "Unicode-3.0"]
15+
allow = ["Apache-2.0", "BSD-3-Clause", "MIT", "Unicode-3.0"]
1416
confidence-threshold = 1.0
1517

1618
[sources]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
2-
name = "fortifier-example"
3-
description = "Fortifier example."
2+
name = "fortifier-example-basic"
3+
description = "Fortifier basic example."
44

55
authors.workspace = true
66
edition.workspace = true

examples/server/Cargo.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[package]
2+
name = "fortifier-example-server"
3+
description = "Fortifier server example."
4+
5+
authors.workspace = true
6+
edition.workspace = true
7+
license.workspace = true
8+
repository.workspace = true
9+
version.workspace = true
10+
11+
[dependencies]
12+
axum = "0.8.7"
13+
fortifier = { workspace = true, features = [
14+
"email",
15+
"regex",
16+
"serde",
17+
"url",
18+
"utoipa",
19+
] }
20+
serde = { workspace = true, features = ["derive"] }
21+
thiserror = "2.0.17"
22+
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
23+
utoipa = { workspace = true, features = ["axum_extras", "uuid"] }
24+
utoipa-axum = "0.2.0"
25+
utoipa-scalar = { version = "0.3.0", features = ["axum"] }
26+
uuid = { version = "1.19.0", features = ["serde", "v7"] }
27+
28+
[lints]
29+
workspace = true

examples/server/src/main.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
mod routes;
2+
mod user;
3+
4+
use std::{
5+
error::Error,
6+
net::{IpAddr, Ipv4Addr, SocketAddr},
7+
};
8+
9+
use tokio::net::TcpListener;
10+
11+
use crate::routes::Routes;
12+
13+
#[tokio::main]
14+
async fn main() -> Result<(), Box<dyn Error>> {
15+
let router = Routes::router();
16+
17+
let address = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
18+
let listener = TcpListener::bind(&address).await?;
19+
20+
println!("listening on http://{}", &address);
21+
axum::serve(listener, router).await?;
22+
23+
Ok(())
24+
}

examples/server/src/routes.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use axum::{Json, Router, routing::get};
2+
use utoipa::OpenApi;
3+
use utoipa_axum::router::OpenApiRouter;
4+
use utoipa_scalar::{Scalar, Servable};
5+
6+
use crate::user::routes::UserRoutes;
7+
8+
#[derive(OpenApi)]
9+
#[openapi(info(
10+
title = "Fortifier Example API",
11+
description = "Example to showcase Fortifier validation.",
12+
))]
13+
pub struct Routes;
14+
15+
impl Routes {
16+
pub fn router<S>() -> Router<S>
17+
where
18+
S: Clone + Send + Sync + 'static,
19+
{
20+
let router = OpenApiRouter::new().merge(UserRoutes::router());
21+
22+
let (router, openapi) = OpenApiRouter::with_openapi(Routes::openapi())
23+
.nest("/api/v1", router)
24+
.split_for_parts();
25+
26+
router
27+
.merge(Scalar::with_url("/api/reference", openapi.clone()))
28+
.route("/api/v1/openapi.json", get(|| async { Json(openapi) }))
29+
}
30+
}

0 commit comments

Comments
 (0)