Skip to content

Support $ref generation#2

Merged
s00d merged 1 commit into
s00d:mainfrom
eholman:feature/support-ref-generation
Mar 19, 2026
Merged

Support $ref generation#2
s00d merged 1 commit into
s00d:mainfrom
eholman:feature/support-ref-generation

Conversation

@eholman
Copy link
Copy Markdown
Contributor

@eholman eholman commented Mar 19, 2026

I'm having nested structs and I was missing the nested struct properties + validation rules. Instead I only saw object.

This PR brings in some functionality to get nested structs validated. The only puzzle piece I couldn't figure out was adding the nested struct to the components part of utoipa. Therefore this is necessary with my PR:

#[derive(utoipa::OpenApi)]
#[openapi(
    components(
        schemas(
            EmployeeAddress,
        )))]
pub(super) struct Api;

My struct:

schema! {
    struct EmployeeAddress {
        pub street_address: String as "streetAddress" => vld::string().max(255),
        pub street_number: i16 as "streetNumber" => vld::number().transform(|n| n as i16),
        pub street_number_addition: Option<String> as "streetNumberAddition" => vld::string().max(20).optional(),
        pub postal_code: Option<String> as "postalCode" => vld::string().max(20).optional(),
        pub city: Option<String> => vld::string().max(100).optional(),
        pub state_province: Option<String> as "stateProvince" => vld::string().max(100).optional(),
        pub country: Option<String> => vld::string().max(2).optional(),
    }
}
impl_to_schema!(EmployeeAddress);

schema! {
    struct PostEmployeeRequest {
        pub first_name: String as "firstName" => vld::string().min(1).max(100),
        pub last_name: String as "lastName" => vld::string().min(1).max(100),
        pub role_id: Option<Uuid> as "roleId" => vld::string().uuid().transform(|x| x.parse::<Uuid>().unwrap()).optional(),
        pub user_id: Option<Uuid> as "userId" => vld::string().uuid().transform(|x| x.parse::<Uuid>().unwrap()).optional(),
        pub display_name: String as "displayName" => vld::string().max(150),
        pub initials: String => vld::string().max(10),
        pub email: String => vld::string().email(),
        pub phone_number: String as "phoneNumber" => vld::string().max(50),
        pub address: Option<EmployeeAddress> => vld::nested!(EmployeeAddress).optional(),
    }
}
 impl_to_schema!(PostEmployeeRequest);

@s00d s00d merged commit dc7990e into s00d:main Mar 19, 2026
1 check failed
@eholman eholman deleted the feature/support-ref-generation branch March 19, 2026 15:51
s00d added a commit that referenced this pull request Mar 19, 2026
Add CollectNestedSchemas trait and json_schema_fn to NestedSchema,
enabling automatic discovery of nested types for OpenAPI component
registration. The nested! macro now passes json_schema_fn when the
openapi feature is on, and schema! generates __vld_nested_schemas()
to collect all nested type references.

Resolves the problem from PR #2 where nested structs had to be
manually listed in utoipa's components(schemas(...)).

Made-with: Cursor
@s00d
Copy link
Copy Markdown
Owner

s00d commented Mar 19, 2026

Hi, thanks - I merged and released version 0.2.0. I also fixed your code and the issues you had. You can check the docs and examples here: vld-utoipa

@eholman
Copy link
Copy Markdown
Contributor Author

eholman commented Mar 19, 2026

Holy moly - You're the KING! Thanks for picking it up so fast!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants