Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ https://github.com/oxidecomputer/dropshot/compare/v0.5.1\...HEAD[Full list of co
* https://github.com/oxidecomputer/dropshot/pull/100[#100] The type used for the "limit" argument for paginated resources has changed. This limit refers to the number of items that an HTTP client can ask for in a single request to a paginated endpoint. The limit is now 4294967295, where it may have previously been larger. This is not expected to affect consumers because this limit is far larger than practical. For details, see #100.
* https://github.com/oxidecomputer/dropshot/pull/116[#116] Unused, non-`pub` endpoints from the `#[endpoint { ... }]` macro now produce a lint warning. This is *technically* a breaking change for those who may have had unused endpoints and compiled with `#[deny(warning)]` or `#[deny(dead_code)]` thus implicitly relying on the *absence* of a warning about the endpoint being unused.
* https://github.com/oxidecomputer/dropshot/pull/118[#118] Path handling has changed. Escape sequences are decoded so that path parameters will no longer include those escape sequences. In addition, paths for endpoints added via `ApiDescription::register()` may not contain consecutive "/" characters.
* https://github.com/oxidecomputer/dropshot/pull/161[#161] The `ApiDescription::print_openapi()` interface (previously deprecated) has been removed. Now use `ApiDescription::openapi()` followed by a call to `OpenApiDefinition::write()` for equivalent functionality.

== 0.5.1 (released 2021-03-18)

Expand Down
38 changes: 2 additions & 36 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dropshot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ futures = "0.3.1"
hostname = "0.3.0"
http = "0.2.5"
indexmap = "1.7.0"
openapiv3 = "0.5.0"
openapiv3 = "1.0.0-beta.3"
paste = "1.0.6"
percent-encoding = "2.1.0"
proc-macro2 = "1.0.32"
Expand Down
76 changes: 17 additions & 59 deletions dropshot/src/api_description.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,52 +428,6 @@ impl<Context: ServerContext> ApiDescription<Context> {
OpenApiDefinition::new(self, title.as_ref(), version.as_ref())
}

/**
* Emit the OpenAPI Spec document describing this API in its JSON form.
*
* This routine is deprecated in favour of the new openapi() builder
* routine.
*/
#[allow(clippy::too_many_arguments)]
#[deprecated(note = "switch to openapi()")]
pub fn print_openapi(
&self,
out: &mut dyn std::io::Write,
title: &dyn ToString,
description: Option<&dyn ToString>,
terms_of_service: Option<&dyn ToString>,
contact_name: Option<&dyn ToString>,
contact_url: Option<&dyn ToString>,
contact_email: Option<&dyn ToString>,
license_name: Option<&dyn ToString>,
license_url: Option<&dyn ToString>,
version: &dyn ToString,
) -> serde_json::Result<()> {
let mut oapi = self.openapi(title.to_string(), version.to_string());
if let Some(s) = description {
oapi.description(s.to_string());
}
if let Some(s) = terms_of_service {
oapi.terms_of_service(s.to_string());
}
if let Some(s) = contact_name {
oapi.contact_name(s.to_string());
}
if let Some(s) = contact_url {
oapi.contact_url(s.to_string());
}
if let Some(s) = contact_email {
oapi.contact_email(s.to_string());
}
if let (Some(name), Some(url)) = (license_name, license_url) {
oapi.license(name.to_string(), url.to_string());
} else if let Some(name) = license_name {
oapi.license_name(name.to_string());
}

oapi.write(out)
}

/**
* Internal routine for constructing the OpenAPI definition describing this
* API in its JSON form.
Expand All @@ -493,7 +447,7 @@ impl<Context: ServerContext> ApiDescription<Context> {
if !endpoint.visible {
continue;
}
let path = openapi.paths.entry(path).or_insert(
let path = openapi.paths.paths.entry(path).or_insert(
openapiv3::ReferenceOr::Item(openapiv3::PathItem::default()),
);

Expand Down Expand Up @@ -612,9 +566,7 @@ impl<Context: ServerContext> ApiDescription<Context> {
mime_type.to_string(),
openapiv3::MediaType {
schema: Some(schema),
example: None,
examples: indexmap::IndexMap::new(),
encoding: indexmap::IndexMap::new(),
..Default::default()
},
);

Expand Down Expand Up @@ -653,9 +605,7 @@ impl<Context: ServerContext> ApiDescription<Context> {
CONTENT_TYPE_JSON.to_string(),
openapiv3::MediaType {
schema: Some(j2oas_schema(name.as_ref(), &js)),
example: None,
examples: indexmap::IndexMap::new(),
encoding: indexmap::IndexMap::new(),
..Default::default()
},
);
}
Expand Down Expand Up @@ -788,7 +738,7 @@ fn j2oas_schema_object(
let ty = match &obj.instance_type {
Some(schemars::schema::SingleOrVec::Single(ty)) => Some(ty.as_ref()),
Some(schemars::schema::SingleOrVec::Vec(_)) => {
unimplemented!("unsupported by openapiv3")
panic!("unsupported by openapiv3")
}
None => None,
};
Expand Down Expand Up @@ -870,8 +820,7 @@ fn j2oas_subschemas(
.map(|schema| j2oas_schema(None, schema))
.collect::<Vec<_>>(),
},
(None, None, None) => todo!("missed a valid case"),
_ => panic!("invalid"),
_ => panic!("invalid subschema {:#?}", subschemas),
}
}

Expand Down Expand Up @@ -1045,7 +994,13 @@ fn j2oas_string(

let enumeration = enum_values
.iter()
.flat_map(|v| v.iter().map(|vv| vv.as_str().unwrap().to_string()))
.flat_map(|v| {
v.iter().map(|vv| match vv {
serde_json::Value::Null => None,
serde_json::Value::String(s) => Some(s.clone()),
_ => panic!("unexpected enumeration value {:?}", vv),
})
})
.collect::<Vec<_>>();

openapiv3::SchemaKind::Type(openapiv3::Type::String(
Expand All @@ -1067,9 +1022,12 @@ fn j2oas_array(
openapiv3::SchemaKind::Type(openapiv3::Type::Array(openapiv3::ArrayType {
items: match &arr.items {
Some(schemars::schema::SingleOrVec::Single(schema)) => {
box_reference_or(j2oas_schema(None, &schema))
Some(box_reference_or(j2oas_schema(None, &schema)))
}
Some(schemars::schema::SingleOrVec::Vec(_)) => {
panic!("OpenAPI v3.0.x cannot support tuple-like arrays")
}
_ => unimplemented!("don't think this is valid"),
None => None,
},
min_items: arr.min_items.map(|n| n as usize),
max_items: arr.max_items.map(|n| n as usize),
Expand Down
28 changes: 2 additions & 26 deletions dropshot/tests/test_openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,37 +285,13 @@ fn make_api() -> Result<ApiDescription<()>, String> {
Ok(api)
}

#[test]
fn test_openapi_old() -> Result<(), String> {
let api = make_api()?;
let mut output = Cursor::new(Vec::new());

#[allow(deprecated)]
let _ = api.print_openapi(
&mut output,
&"test",
None,
None,
None,
None,
None,
None,
None,
&"threeve",
);
let actual = from_utf8(&output.get_ref()).unwrap();

expectorate::assert_contents("tests/test_openapi_old.json", actual);
Ok(())
}

#[test]
fn test_openapi() -> Result<(), String> {
let api = make_api()?;
let mut output = Cursor::new(Vec::new());

let _ = api.openapi("test", "threeve").write(&mut output);
let actual = from_utf8(&output.get_ref()).unwrap();
let actual = from_utf8(output.get_ref()).unwrap();

expectorate::assert_contents("tests/test_openapi.json", actual);
Ok(())
Expand All @@ -333,7 +309,7 @@ fn test_openapi_fuller() -> Result<(), String> {
.license_name("CDDL")
.terms_of_service("no hat, no cane? no service!")
.write(&mut output);
let actual = from_utf8(&output.get_ref()).unwrap();
let actual = from_utf8(output.get_ref()).unwrap();

expectorate::assert_contents("tests/test_openapi_fuller.json", actual);
Ok(())
Expand Down
Loading