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

Schema for BigDecimal is not correct #123

Closed
Flowneee opened this issue Dec 8, 2021 · 3 comments · Fixed by #248
Closed

Schema for BigDecimal is not correct #123

Flowneee opened this issue Dec 8, 2021 · 3 comments · Fixed by #248

Comments

@Flowneee
Copy link

Flowneee commented Dec 8, 2021

Problem

0.8.8 version added schema for BigDecimal, but it is incorrect, because BigDecimal serialized as string, and can be deserialized from string, number or integer.

Details

Current schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Number",
  "type": "number"
}

For example:

use bigdecimal::BigDecimal;
use schemars::schema_for;

fn main() {
    let schema = schema_for!(BigDecimal);
    println!("{}", serde_json::to_string_pretty(&schema).unwrap());
    println!(
        "{:?}",
        serde_json::to_value(&BigDecimal::default()).unwrap()
    )
}

gives

Schema: {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Number",
  "type": "number"
}
Serialized: String("0")

see https://www.jsonschemavalidator.net/s/s2ULf39e as well.

And about deserialization:

use bigdecimal::BigDecimal;

fn main() {
    assert!(serde_json::from_str::<BigDecimal>("123").is_ok());
    assert!(serde_json::from_str::<BigDecimal>("123.123").is_ok());
    assert!(serde_json::from_str::<BigDecimal>("\"123\"").is_ok());
}

Solution

I don't have any good solutions. The problem is: this type have different schemas for deserialization and serialization. One possible solution: use most common type here - string and then add description and pattern to it.

I recently faced same problem in my work project, and we came up with 2 wrapper types, which have different JsonSchema implementations, but this is quite ugly and would not be suitable for this lib I think.

@aldofunes
Copy link

aldofunes commented Jun 14, 2023

I was able to make it work by mapping a BigDecimal to an anyOf config, where one is a number and the other a string with a regex that validates it's actually a number.

I ran some tests and it worked great for my use case, and thought that it was best to share it, and thus I made PR #224 . Hope it helps

@GREsau
Copy link
Owner

GREsau commented Sep 17, 2023

This is mostly fixed in v0.8.14, in that the schema will now match how BigDecimal is serialised (i.e. as a numeric string). There's not yet a good way to specify different schemas for serialization vs deserialization (#48) though, so the schema doesn't accept a plain number even though it would be valid for deserialization

@SohumB
Copy link

SohumB commented Oct 17, 2023

Just as a note — we use rust_decimal schemas in our input jsonschemas, and we currently expect schemars min and max annotations to work on them. with this change, they no longer work, so we're currently pinning to v0.8.13 pending further investigation. I'm not intending this as a bug report exactly, just more of a usage note.

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 a pull request may close this issue.

4 participants