Skip to main content

fandwill_vo/
lib.rs

1//! Shared value objects for the [Fandwill](https://github.com/furlink/fandwill-rust-sdk) HTTP API.
2//!
3//! Use the same crate version in the Fandwill backend, future Rust SDK, and any generated
4//! client bindings so JSON payloads stay aligned.
5//!
6//! ## Features
7//!
8//! - **`garde`** (default) — `garde::Validate` on request types.
9//! - **`utoipa`** (default) — `utoipa::ToSchema` for OpenAPI.
10//!
11//! Serde-only build: `default-features = false`.
12
13pub mod auth;
14pub mod collections;
15pub mod listings;
16pub mod meta;
17pub mod notifications;
18pub mod pagination;
19pub mod resources;
20pub mod reviews;
21pub mod users;
22pub mod validation;
23
24#[cfg(all(test, feature = "garde"))]
25mod tests {
26    use crate::auth::SignUpVO;
27    use garde::Validate;
28
29    #[test]
30    fn sign_up_vo_roundtrip_json() {
31        let vo = SignUpVO {
32            email: "user@example.com".into(),
33            password: "password123".into(),
34            nickname: Some("TestUser".into()),
35        };
36        vo.validate().expect("valid fixture");
37        let json = serde_json::to_string(&vo).unwrap();
38        let back: SignUpVO = serde_json::from_str(&json).unwrap();
39        assert_eq!(back.email, vo.email);
40        assert_eq!(back.password, vo.password);
41        assert_eq!(back.nickname, vo.nickname);
42    }
43}
44
45#[cfg(all(test, feature = "utoipa"))]
46mod openapi_tests {
47    use crate::{
48        listings::ListingsQuery, notifications::NotificationsQuery, pagination::PaginationParams,
49        reviews::ReviewFilter,
50    };
51    use utoipa::{IntoParams, openapi::path::ParameterIn};
52
53    fn parameter_names<T: IntoParams>() -> Vec<String> {
54        T::into_params(|| Some(ParameterIn::Query))
55            .into_iter()
56            .map(|parameter| parameter.name)
57            .collect()
58    }
59
60    #[test]
61    fn shared_query_types_expose_every_openapi_parameter() {
62        assert_eq!(parameter_names::<PaginationParams>(), ["page", "page_size"]);
63        assert_eq!(
64            parameter_names::<ListingsQuery>(),
65            [
66                "page",
67                "page_size",
68                "mode",
69                "q",
70                "min_relevance",
71                "max_distance",
72            ]
73        );
74        assert_eq!(
75            parameter_names::<ReviewFilter>(),
76            ["listing_id", "page", "page_size"]
77        );
78        assert_eq!(
79            parameter_names::<NotificationsQuery>(),
80            ["page", "page_size", "unread_only", "after_id"]
81        );
82    }
83}