paperclip
paperclip copied to clipboard
Fails to deserialize sample YAML v2 document
The sample YAML document on this page: https://swagger.io/docs/specification/2-0/basic-structure/ cannot be deserialized by paperclip, it errors out here:
---- test_basic_structure stdout ----
thread 'test_basic_structure' panicked at 'Couldn't deser doc: Yaml(Message("invalid type: integer `200`, expected a string", Some(Pos { marker: Marker { index: 183, line: 14, col: 7 }, path: "paths./users" })))', src/lib.rs:41:45
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Here is the code I used to generate this error:
use paperclip::v2::{self, ResolvableApi, DefaultSchema, models::Version};
#[test]
fn test_basic_structure() {
use std::io::{self, Cursor};
let doc = r#"swagger: "2.0"
info:
title: Sample API
description: API description in Markdown.
version: 1.0.0
host: api.example.com
basePath: /v1
schemes:
- https
paths:
/users:
get:
summary: Some text
description: Some more text
produces:
- application/json
responses:
200:
description: OK"#.to_string();
let bytes = doc.as_bytes().to_vec();
let mut bytes = Cursor::new(bytes);
let api: ResolvableApi<DefaultSchema> = v2::from_reader(&mut bytes).expect("Couldn't deser doc");
assert_eq!(api.swagger, Version::V2);
}
As the error says, you should have "200"
(string) instead of 200
(integer) in responses schema.
ok, but this sample is not from me, but from the official OpenAPIv2 spec...not accepting 200
means paperclip is not spec-compliant.
The official spec seems to describe the status code as a string (example here). The JSON schema for v2 spec also says that the responses schema is an object, which only have string keys.
exactly, so the 200
should be parsed as a string instead of integer, but it's not, that's where the issue is.
Um, no. The 200
should be written as a string in the spec (it will be parsed as an integer, but it should still be "200"
in the spec).
At the end of the day, the document above is a spec-compliant document, as it was taken directly from the spec. All other OpenAPI validators I've run it through have successfully validated it. Only the 2 rust crates I have tried, yours and the openapi
crate, have failed to parse it. My use case involves accepting arbitrary OpenAPI documents from my users, so I need to be able to accept any valid OpenAPI spec, and therefore paperclip
isn't an option as long as it won't accept all valid OpenAPI specs.
Okay, I guess it doesn't hurt to deviate a little from the spec and relax the check with an enum of integer/string.
This is now open for anyone to work on!
So I've looked into this, and there seems to be an issue with serde
. Specifically, a struct
that has a #[serde(flatten)]
property of BTreeMap<_, BTreeMap<String, _>>
doesn't automatically cast numbers to String
s, while a struct
with the same property without a #[serde(flatten)]
attribute does.
Example: https://gist.github.com/mxndtaylor/488db8ca053d8d69e72fa0fc4f5d0a23