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

Generate a Client method for Dropshot websocket channels #183

Merged
merged 1 commit into from Sep 28, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Expand Up @@ -24,6 +24,7 @@ https://github.com/oxidecomputer/progenitor/compare/v0.1.1\...v0.2.0[Full list o
* Derive `Debug` for `Client` and builders for the various operations (#145)
* Builders for `struct` types (#171)
* Add a prelude that include the `Client` and any extension traits (#176)
* Add support for upgrading connections, which requires a version bump to reqwest. (#183)

== 0.1.1 (released 2022-05-13)

Expand Down
46 changes: 43 additions & 3 deletions Cargo.lock

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

11 changes: 9 additions & 2 deletions README.md
Expand Up @@ -54,6 +54,13 @@ Similarly if there is a `format` field set to `uuid`:
+uuid = { version = "1.0.0", features = ["serde", "v4"] }
```

And if there are any websocket channel endpoints:
```diff
[dependencies]
+base64 = "0.13"
+rand = "0.8"
```

The macro has some additional fancy options to control the generated code:

```rust
Expand Down Expand Up @@ -116,7 +123,7 @@ You'll need to add add the following to `Cargo.toml`:
+serde_json = "1.0"
```

(`chrono` and `uuid` as above)
(`chrono`, `uuid`, `base64`, and `rand` as above)

Note that `progenitor` is used by `build.rs`, but the generated code required
`progenitor-client`.
Expand Down Expand Up @@ -290,4 +297,4 @@ let result = client
```

Consumers do not need to specify parameters and struct properties that are not
required or for which the API specifies defaults. Neat!
required or for which the API specifies defaults. Neat!
4 changes: 3 additions & 1 deletion example-build/Cargo.toml
Expand Up @@ -7,7 +7,9 @@ edition = "2021"
[dependencies]
chrono = { version = "0.4", features = ["serde"] }
progenitor-client = { path = "../progenitor-client" }
reqwest = { version = "0.11", features = ["json", "stream"] }
reqwest = { version = "0.11.12", features = ["json", "stream"] }
base64 = "0.13"
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
uuid = { version = "1.0", features = ["serde", "v4"] }

Expand Down
2 changes: 1 addition & 1 deletion example-macro/Cargo.toml
Expand Up @@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
chrono = { version = "0.4", features = ["serde"] }
progenitor = { path = "../progenitor" }
reqwest = { version = "0.11", features = ["json", "stream"] }
reqwest = { version = "0.11.12", features = ["json", "stream"] }
schemars = { version = "0.8.10", features = ["uuid1"] }
serde = { version = "1.0", features = ["derive"] }
uuid = { version = "1.0", features = ["serde", "v4"] }
2 changes: 1 addition & 1 deletion progenitor-client/Cargo.toml
Expand Up @@ -10,7 +10,7 @@ description = "An OpenAPI client generator - client support"
bytes = "1.2.1"
futures-core = "0.3.24"
percent-encoding = "2.2"
reqwest = { version = "0.11", default-features = false, features = ["json", "stream"] }
reqwest = { version = "0.11.12", default-features = false, features = ["json", "stream"] }
serde = "1.0"
serde_json = "1.0"
serde_urlencoded = "0.7.1"
24 changes: 24 additions & 0 deletions progenitor-client/src/progenitor_client.rs
Expand Up @@ -76,6 +76,30 @@ impl<T: DeserializeOwned> ResponseValue<T> {
}
}

impl ResponseValue<reqwest::Upgraded> {
#[doc(hidden)]
pub async fn upgrade<E: std::fmt::Debug>(
response: reqwest::Response,
) -> Result<Self, Error<E>> {
let status = response.status();
let headers = response.headers().clone();
if status == reqwest::StatusCode::SWITCHING_PROTOCOLS {
let inner = response
.upgrade()
.await
.map_err(Error::InvalidResponsePayload)?;

Ok(Self {
inner,
status,
headers,
})
} else {
Err(Error::UnexpectedResponse(response))
}
}
}

impl ResponseValue<ByteStream> {
#[doc(hidden)]
pub fn stream(response: reqwest::Response) -> Self {
Expand Down
11 changes: 10 additions & 1 deletion progenitor-impl/src/lib.rs
Expand Up @@ -26,6 +26,8 @@ pub enum Error {
UnexpectedFormat(String),
#[error("invalid operation path {0}")]
InvalidPath(String),
#[error("invalid dropshot extension use: {0}")]
InvalidExtension(String),
#[error("internal error {0}")]
InternalError(String),
}
Expand All @@ -36,6 +38,7 @@ pub struct Generator {
type_space: TypeSpace,
settings: GenerationSettings,
uses_futures: bool,
uses_websockets: bool,
}

#[derive(Default, Clone)]
Expand Down Expand Up @@ -116,6 +119,7 @@ impl Default for Generator {
),
settings: Default::default(),
uses_futures: Default::default(),
uses_websockets: Default::default(),
}
}
}
Expand All @@ -133,6 +137,7 @@ impl Generator {
type_space: TypeSpace::new(&type_settings),
settings: settings.clone(),
uses_futures: false,
uses_websockets: false,
}
}

Expand Down Expand Up @@ -426,7 +431,7 @@ impl Generator {
"bytes = \"1.1\"",
"futures-core = \"0.3\"",
"percent-encoding = \"2.1\"",
"reqwest = { version = \"0.11\", features = [\"json\", \"stream\"] }",
"reqwest = { version = \"0.11.12\", features = [\"json\", \"stream\"] }",
"serde = { version = \"1.0\", features = [\"derive\"] }",
"serde_urlencoded = \"0.7\"",
];
Expand All @@ -444,6 +449,10 @@ impl Generator {
if self.uses_futures {
deps.push("futures = \"0.3\"")
}
if self.uses_websockets {
deps.push("base64 = \"0.13\"");
deps.push("rand = \"0.8\"");
}
if self.type_space.uses_serde_json() {
deps.push("serde_json = \"1.0\"")
}
Expand Down