honor default values for struct properties (#50)

This commit is contained in:
Adam Leventhal 2022-05-12 15:07:48 -07:00 committed by GitHub
parent 5dba719455
commit 1af79ebec7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 178 additions and 41 deletions

86
Cargo.lock generated
View File

@ -19,9 +19,9 @@ checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
[[package]]
name = "async-stream"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625"
checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
dependencies = [
"async-stream-impl",
"futures-core",
@ -29,9 +29,9 @@ dependencies = [
[[package]]
name = "async-stream-impl"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308"
checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
dependencies = [
"proc-macro2",
"quote",
@ -40,9 +40,9 @@ dependencies = [
[[package]]
name = "async-trait"
version = "0.1.52"
version = "0.1.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3"
checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
dependencies = [
"proc-macro2",
"quote",
@ -243,7 +243,7 @@ dependencies = [
[[package]]
name = "dropshot"
version = "0.6.1-dev"
source = "git+https://github.com/oxidecomputer/dropshot#18078c4909d6260dddb924915f830de12840871d"
source = "git+https://github.com/oxidecomputer/dropshot#0b259fb094361e0a626e0f4d16d8a7c715554f97"
dependencies = [
"async-stream",
"async-trait",
@ -276,12 +276,13 @@ dependencies = [
"toml",
"usdt",
"uuid 0.8.2",
"version_check",
]
[[package]]
name = "dropshot_endpoint"
version = "0.6.1-dev"
source = "git+https://github.com/oxidecomputer/dropshot#18078c4909d6260dddb924915f830de12840871d"
source = "git+https://github.com/oxidecomputer/dropshot#0b259fb094361e0a626e0f4d16d8a7c715554f97"
dependencies = [
"proc-macro2",
"quote",
@ -584,9 +585,9 @@ dependencies = [
[[package]]
name = "http"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03"
checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb"
dependencies = [
"bytes",
"fnv",
@ -666,9 +667,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
@ -939,9 +940,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
[[package]]
name = "percent-encoding"
@ -1012,9 +1013,9 @@ checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
[[package]]
name = "proc-macro2"
version = "1.0.36"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
dependencies = [
"unicode-xid",
]
@ -1221,9 +1222,9 @@ dependencies = [
[[package]]
name = "rustls-pemfile"
version = "0.3.0"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360"
checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9"
dependencies = [
"base64",
]
@ -1344,18 +1345,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.136"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.136"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
dependencies = [
"proc-macro2",
"quote",
@ -1472,9 +1473,9 @@ dependencies = [
[[package]]
name = "slog-json"
version = "2.6.0"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70f825ce7346f40aa318111df5d3a94945a7fdca9081584cb9b05692fb3dfcb4"
checksum = "3e1e53f61af1e3c8b852eef0a9dee29008f55d6dd63794f3f12cef786cf0f219"
dependencies = [
"serde",
"serde_json",
@ -1707,9 +1708,9 @@ dependencies = [
[[package]]
name = "tokio-rustls"
version = "0.23.2"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls",
"tokio",
@ -1732,9 +1733,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.5.8"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
dependencies = [
"serde",
]
@ -1793,7 +1794,7 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "typify"
version = "0.0.6-dev"
source = "git+https://github.com/oxidecomputer/typify#4494446aac57ad0841f0d91ba0a9c1acca5de228"
source = "git+https://github.com/oxidecomputer/typify#90894d81e303cd56056b179f31b60401efa3462d"
dependencies = [
"typify-impl",
"typify-macro",
@ -1802,7 +1803,7 @@ dependencies = [
[[package]]
name = "typify-impl"
version = "0.0.6-dev"
source = "git+https://github.com/oxidecomputer/typify#4494446aac57ad0841f0d91ba0a9c1acca5de228"
source = "git+https://github.com/oxidecomputer/typify#90894d81e303cd56056b179f31b60401efa3462d"
dependencies = [
"heck",
"log",
@ -1819,7 +1820,7 @@ dependencies = [
[[package]]
name = "typify-macro"
version = "0.0.6-dev"
source = "git+https://github.com/oxidecomputer/typify#4494446aac57ad0841f0d91ba0a9c1acca5de228"
source = "git+https://github.com/oxidecomputer/typify#90894d81e303cd56056b179f31b60401efa3462d"
dependencies = [
"proc-macro2",
"quote",
@ -1884,9 +1885,9 @@ dependencies = [
[[package]]
name = "usdt"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3877c300bc107d8d05455e8e2bec271ca9e1d24fbc17e3ef27d18b9b53c684e2"
checksum = "5409e16f35fdba646ff4290e6f96f0bb958b43e0bd09d790c3714456a76c11ac"
dependencies = [
"dof",
"serde",
@ -1897,9 +1898,9 @@ dependencies = [
[[package]]
name = "usdt-attr-macro"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dedf62a6eab9c6da23fa64353382ef2b73dce8891eadda8755bfed179cb2103d"
checksum = "d203cad87b8424e1fbd0fef29b6df2113e68be5dd75f4043427eb0ce6601041f"
dependencies = [
"dtrace-parser",
"proc-macro2",
@ -1911,9 +1912,9 @@ dependencies = [
[[package]]
name = "usdt-impl"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dda9311a9f1452ebc752d264e9d1e3c2dac9807219e19471bcef3bd1b7f90cb"
checksum = "3c146394183fcea90d93e2d4602e1a7eb6cab8e807b58f99d4f343720d4e9d69"
dependencies = [
"byteorder",
"dof",
@ -1926,13 +1927,14 @@ dependencies = [
"syn",
"thiserror",
"thread-id",
"version_check",
]
[[package]]
name = "usdt-macro"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64160eb8f7ee61fcaef542b2f75fa807e8c3ed4b4f075e6ca0b17ea6fcea6f8"
checksum = "8dddab3586eaf539e2daddc425261daef6a6d2f85131bac7345caa8e6a423b27"
dependencies = [
"dtrace-parser",
"proc-macro2",
@ -1968,6 +1970,12 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
version = "2.3.2"

View File

@ -9,7 +9,7 @@ description = "An OpenAPI client generator - core implementation"
[dependencies]
heck = "0.4.0"
getopts = "0.2"
indexmap = "1.7"
indexmap = "1.8"
openapiv3 = "1.0.0"
proc-macro2 = "1.0"
quote = "1.0"

View File

@ -112,6 +112,7 @@ impl Generator {
.collect::<Vec<_>>();
types.sort_by(|(a_name, _), (b_name, _)| a_name.cmp(b_name));
let types = types.into_iter().map(|(_, def)| def);
let shared = self.type_space.common_code();
let inner_property = self.inner_type.as_ref().map(|inner| {
quote! {
@ -131,6 +132,7 @@ impl Generator {
pub mod types {
use serde::{Deserialize, Serialize};
#shared
#(#types)*
}

View File

@ -0,0 +1,79 @@
pub use progenitor_client::{ByteStream, Error, ResponseValue};
pub mod types {
use serde::{Deserialize, Serialize};
mod defaults {
pub(super) fn default_u64<T, const V: u64>() -> T
where
T: std::convert::TryFrom<u64>,
<T as std::convert::TryFrom<u64>>::Error: std::fmt::Debug,
{
T::try_from(V).unwrap()
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BodyWithDefaults {
#[serde(rename = "forty-two", default = "defaults::default_u64::<u32, 42>")]
pub forty_two: u32,
pub s: String,
#[serde(default)]
pub yes: bool,
}
#[doc = "Error information from a response."]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Error {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error_code: Option<String>,
pub message: String,
pub request_id: String,
}
}
#[derive(Clone)]
pub struct Client {
baseurl: String,
client: reqwest::Client,
}
impl Client {
pub fn new(baseurl: &str) -> Self {
let dur = std::time::Duration::from_secs(15);
let client = reqwest::ClientBuilder::new()
.connect_timeout(dur)
.timeout(dur)
.build()
.unwrap();
Self::new_with_client(baseurl, client)
}
pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self {
Self {
baseurl: baseurl.to_string(),
client,
}
}
pub fn baseurl(&self) -> &String {
&self.baseurl
}
pub fn client(&self) -> &reqwest::Client {
&self.client
}
#[doc = "Sends a `POST` request to ``"]
pub async fn default_params<'a>(
&'a self,
body: &'a types::BodyWithDefaults,
) -> Result<ResponseValue<ByteStream>, Error<ByteStream>> {
let url = format!("{}", self.baseurl,);
let request = self.client.post(url).json(body).build()?;
let result = self.client.execute(request).await;
let response = result?;
match response.status().as_u16() {
200..=299 => Ok(ResponseValue::stream(response)),
_ => Err(Error::ErrorResponse(ResponseValue::stream(response))),
}
}
}

View File

@ -4,7 +4,7 @@ use std::{str::from_utf8, sync::Arc};
use dropshot::{
endpoint, ApiDescription, HttpError, HttpResponseUpdatedNoContent, Path,
Query, RequestContext,
Query, RequestContext, TypedBody,
};
use http::Response;
use hyper::Body;
@ -104,3 +104,51 @@ fn test_freeform_response() {
&output,
)
}
#[derive(Deserialize, JsonSchema)]
#[allow(dead_code)]
struct BodyWithDefaults {
s: String,
#[serde(default)]
yes: bool,
#[serde(default = "forty_two", rename = "forty-two")]
forty_two: u32,
}
fn forty_two() -> u32 {
42
}
#[endpoint {
method = POST,
path = "/",
}]
async fn default_params(
_rqctx: Arc<RequestContext<()>>,
_body: TypedBody<BodyWithDefaults>,
) -> Result<Response<Body>, HttpError> {
unreachable!();
}
/// Test default type values.
#[test]
fn test_default_params() {
let mut api = ApiDescription::new();
api.register(default_params).unwrap();
let mut out = Vec::new();
api.openapi("pagination-demo", "9000")
.write(&mut out)
.unwrap();
let out = from_utf8(&out).unwrap();
let spec = serde_json::from_str::<OpenAPI>(out).unwrap();
let mut generator = Generator::new();
let output = generator.generate_text(&spec).unwrap();
expectorate::assert_contents(
format!("tests/output/{}.out", "test_default_params"),
&output,
)
}