Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use serde_with::serde_as in conjunction with schemars(schema_with) #712

Closed
indietyp opened this issue Mar 6, 2024 · 3 comments · Fixed by #715
Closed

Unable to use serde_with::serde_as in conjunction with schemars(schema_with) #712

indietyp opened this issue Mar 6, 2024 · 3 comments · Fixed by #715
Labels
bug Something isn't working

Comments

@indietyp
Copy link

indietyp commented Mar 6, 2024

I am trying to properly encode Base64 encoded data using schemars, but I am failing while the schemars_0_8 feature is enabled. Base64 does not implement JsonSchemaAs, so I went ahead and tried to implement it myself using the schema_with annotation.

#[serde_with::serde_as]
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase")]
pub struct Image {
    #[serde_as(as = "serde_with::base64::Base64")]
    #[cfg_attr(feature = "schemars", schemars(schema_with = "base_64_schema"))]
    pub buffer: Vec<u8>,
}

#[cfg(feature = "schemars")]
fn base_64_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
    // These properties are valid JSON-schema properties, but they are not supported by schemars
    let mut extensions = std::collections::BTreeMap::new();
    extensions.insert(
        "contentEncoding".to_owned(),
        serde_json::Value::from("base64"),
    );
    extensions.insert(
        "contentMediaType".to_owned(),
        serde_json::Value::from("image/*"),
    );

    schemars::schema::SchemaObject {
        instance_type: Some(schemars::schema::InstanceType::String.into()),
        extensions,
        ..schemars::schema::SchemaObject::default()
    }
    .into()
}

This fails with the error: schemars attribute cannot contain both with and schema_with

any help would be immensely appreciated. Thank you so much for the great library and overall integration of schemars into it!

@indietyp
Copy link
Author

indietyp commented Mar 6, 2024

I just found out that schemars = false works on a container level, but something similar would be great on a per field level.

@jonasbb
Copy link
Owner

jonasbb commented Mar 6, 2024

The macro should handle such conflicts. There is a test, but it might only work for schemars(with = ...) and not schemars(schema_with = ...).

fn schemars_custom_with() {
#[serde_as]
#[derive(JsonSchema, Serialize)]
struct Test {
#[serde_as(as = "DisplayFromStr")]
#[schemars(with = "i32")]
custom: i32,
#[serde_as(as = "DisplayFromStr")]
#[cfg_attr(any(), schemars(with = "i32"))]
with_disabled: i32,
#[serde_as(as = "DisplayFromStr")]
#[cfg_attr(all(), schemars(with = "i32"))]
always_enabled: i32,
}
check_matches_schema::<Test>(&json!({
"custom": 3,
"with_disabled": "5",
"always_enabled": 7,
}));
}

You should be able to work around this for now, by using a type and with instead of schema_with.

The schema_with seems to have an identical functionality to with, but with different syntax. That in that case, the macro should detect both. I will check how to update the serde_as macro here.

@jonasbb jonasbb added the bug Something isn't working label Mar 6, 2024
swlynch99 added a commit to swlynch99/serde_with that referenced this issue Mar 7, 2024
This treats a `#[schemars(schema_with = "...")]` attribute the same as a
`#[schemars(with = "...")]` attribute when deciding whether to emit our
own.

There is also a new test case that validates that everything works as
expected.

Fixes jonasbb#712
jonasbb pushed a commit to swlynch99/serde_with that referenced this issue Mar 8, 2024
This treats a `#[schemars(schema_with = "...")]` attribute the same as a
`#[schemars(with = "...")]` attribute when deciding whether to emit our
own.

There is also a new test case that validates that everything works as
expected.

Fixes jonasbb#712
@jonasbb
Copy link
Owner

jonasbb commented Mar 11, 2024

A fix for this is released in v3.7.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants