Skip to content

Commit

Permalink
Upgrade http/hyper 1.0 (#564)
Browse files Browse the repository at this point in the history
Hakuyume authored Feb 7, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 59be97c commit f350014
Showing 14 changed files with 122 additions and 148 deletions.
18 changes: 10 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -31,12 +31,14 @@ futures = { version = "0.3.15" }
futures-core = { version = "0.3.15", optional = true }
futures-util = { version = "0.3.15", optional = true }
jsonwebtoken = "9"
http = "0.2.5"
http-body = "0.4.5"
hyper = { version = "0.14.13", features = ["client", "http1", "stream", "tcp"] }
hyper-rustls = { version = "0.24.0", optional = true }
hyper-timeout = { version = "0.4.1", optional = true }
hyper-tls = { version = "0.5.0", optional = true }
http = "1.0.0"
http-body = "1.0.0"
http-body-util = "0.1.0"
hyper = "1.1.0"
hyper-rustls = { version = "0.26.0", optional = true }
hyper-timeout = { version = "0.5.1", optional = true }
hyper-tls = { version = "0.6.0", optional = true }
hyper-util = { version = "0.1.3", features = ["client-legacy", "http1"] }
once_cell = "1.7.2"
percent-encoding = "2.2.0"
pin-project = "1.0.12"
@@ -48,7 +50,7 @@ serde_urlencoded = "0.7.1"
snafu = { version = "0.7", features = ["backtraces"] }
tokio = { version = "1.17.0", default-features = false, optional = true }
tower = { version = "0.4.13", default-features = false, features = ["util", "buffer"] }
tower-http = { version = "0.4.0", features = ["map-response-body", "trace"] }
tower-http = { version = "0.5.1", features = ["map-response-body", "trace"] }
tracing = { version = "0.1.37", features = ["log"], optional = true }
url = { version = "2.2.2", features = ["serde"] }

@@ -73,5 +75,5 @@ retry = ["tower/retry", "futures-util"]
rustls = ["hyper-rustls"]
rustls-webpki-tokio = ["hyper-rustls/webpki-tokio"]
opentls = ["hyper-tls"]
stream = ["futures-core", "futures-util", "hyper/stream"]
stream = ["futures-core", "futures-util"]
timeout = ["hyper-timeout", "tokio", "tower/timeout"]
4 changes: 3 additions & 1 deletion examples/custom_client.rs
Original file line number Diff line number Diff line change
@@ -11,11 +11,13 @@ use std::sync::Arc;
async fn main() -> octocrab::Result<()> {
let connector = HttpsConnectorBuilder::new()
.with_native_roots() // enabled the `rustls-native-certs` feature in hyper-rustls
.unwrap()
.https_only()
.enable_http1()
.build();

let client = hyper::Client::builder().build(connector);
let client = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new())
.build(connector);
let octocrab = OctocrabBuilder::new_empty()
.with_service(client)
.with_layer(&BaseUriLayer::new(Uri::from_static(
10 changes: 6 additions & 4 deletions src/api/actions.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//! GitHub Actions
use bytes::Bytes;
use http_body_util::combinators::BoxBody;
use http_body_util::{BodyExt, Collected};
use snafu::ResultExt;

pub mod self_hosted_runners;

use self::self_hosted_runners::{CreateJitRunnerConfigBuilder, ListSelfHostedRunnersBuilder};
use crate::error::{HttpSnafu, HyperSnafu};
use crate::error::HttpSnafu;
use crate::etag::{EntityTag, Etagged};
use crate::models::{
workflows::WorkflowDispatch, workflows::WorkflowListArtifact, ArtifactId, RepositoryId, RunId,
@@ -13,7 +16,6 @@ use crate::models::{RunnerGroupId, RunnerId};
use crate::{params, FromResponse, Octocrab, Page};
use http::request::Builder;
use http::{header::HeaderMap, Method, StatusCode, Uri};
use hyper::body;

pub struct ListWorkflowRunArtifacts<'octo> {
crab: &'octo Octocrab,
@@ -268,13 +270,13 @@ impl<'octo> ActionsHandler<'octo> {

async fn follow_location_to_data(
&self,
response: http::Response<hyper::Body>,
response: http::Response<BoxBody<Bytes, crate::Error>>,
) -> crate::Result<bytes::Bytes> {
let data_response = self.crab.follow_location_to_data(response).await?;

let body = data_response.into_body();

body::to_bytes(body).await.context(HyperSnafu)
body.collect().await.map(Collected::to_bytes)
}

/// Downloads and returns the raw data representing a zip of the logs from
6 changes: 4 additions & 2 deletions src/api/repos.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! The repositories API.
use bytes::Bytes;
use http::header::ACCEPT;
use http::request::Builder;
use http::Uri;
use http_body_util::combinators::BoxBody;
use snafu::ResultExt;

mod branches;
@@ -561,7 +563,7 @@ impl<'octo> RepoHandler<'octo> {
self,
reference: impl Into<params::repos::Commitish>,
path: impl AsRef<str>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let route = format!(
"/repos/{owner}/{repo}/contents/{path}",
owner = self.owner,
@@ -606,7 +608,7 @@ impl<'octo> RepoHandler<'octo> {
pub async fn download_tarball(
&self,
reference: impl Into<params::repos::Commitish>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let route = format!(
"/repos/{owner}/{repo}/tarball/{reference}",
owner = self.owner,
8 changes: 2 additions & 6 deletions src/api/repos/releases.rs
Original file line number Diff line number Diff line change
@@ -194,12 +194,8 @@ impl<'octo, 'r> ReleasesHandler<'octo, 'r> {
let request = self.parent.crab.build_request(builder, None::<&()>)?;
let response = self.parent.crab.execute(request).await?;
let response = self.parent.crab.follow_location_to_data(response).await?;
Ok(response
.into_body()
.map_err(|source| crate::error::Error::Hyper {
source,
backtrace: snafu::Backtrace::generate(),
}))
Ok(http_body_util::BodyStream::new(response.into_body())
.try_filter_map(|frame| futures_util::future::ok(frame.into_data().ok())))
}
}

2 changes: 1 addition & 1 deletion src/etag.rs
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ pub struct EntityTag {
}

impl EntityTag {
pub fn extract_from_response(response: &http::Response<hyper::Body>) -> Option<EntityTag> {
pub fn extract_from_response<B>(response: &http::Response<B>) -> Option<EntityTag> {
response
.headers()
.get("ETag")
16 changes: 11 additions & 5 deletions src/from_response.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
use bytes::Bytes;
use http_body::Body;
use http_body_util::BodyExt;
use snafu::ResultExt;

/// A trait for mapping from a `http::Response` to an another type.
#[async_trait::async_trait]
pub trait FromResponse: Sized {
async fn from_response(response: http::Response<hyper::Body>) -> crate::Result<Self>;
async fn from_response<B>(response: http::Response<B>) -> crate::Result<Self>
where
B: Body<Data = Bytes, Error = crate::Error> + Send;
}

#[async_trait::async_trait]
impl<T: serde::de::DeserializeOwned> FromResponse for T {
async fn from_response(response: http::Response<hyper::Body>) -> crate::Result<Self> {
async fn from_response<B>(response: http::Response<B>) -> crate::Result<Self>
where
B: Body<Data = Bytes, Error = crate::Error> + Send,
{
let (_, body) = response.into_parts();
let body = hyper::body::to_bytes(body)
.await
.context(crate::error::HyperSnafu)?;
let body = body.collect().await?.to_bytes();
let de = &mut serde_json::Deserializer::from_slice(&body);
return serde_path_to_error::deserialize(de).context(crate::error::JsonSnafu);
}
109 changes: 58 additions & 51 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -190,10 +190,11 @@ pub mod etag;
pub mod models;
pub mod params;
pub mod service;
use crate::service::body::BodyStreamExt;

use chrono::{DateTime, Utc};
use http::{HeaderMap, HeaderValue, Method, Uri};
use http_body_util::combinators::BoxBody;
use http_body_util::BodyExt;
use service::middleware::auth_header::AuthHeaderLayer;
use std::convert::{Infallible, TryInto};
use std::fmt;
@@ -206,7 +207,7 @@ use std::time::Duration;
use http::{header::HeaderName, StatusCode};
#[cfg(all(not(feature = "opentls"), not(feature = "rustls")))]
use hyper::client::HttpConnector;
use hyper::{body, Body, Request, Response};
use hyper::{Request, Response};

use once_cell::sync::Lazy;
use secrecy::{ExposeSecret, SecretString};
@@ -227,10 +228,7 @@ use hyper_rustls::HttpsConnectorBuilder;
use tower::retry::{Retry, RetryLayer};

#[cfg(feature = "timeout")]
use {
hyper_timeout::TimeoutConnector,
tokio::io::{AsyncRead, AsyncWrite},
};
use hyper_timeout::TimeoutConnector;

use tower_http::{classify::ServerErrorsFailureClass, map_response_body::MapResponseBodyLayer};

@@ -299,18 +297,14 @@ pub fn format_media_type(media_type: impl AsRef<str>) -> String {
/// Maps a GitHub error response into and `Err()` variant if the status is
/// not a success.
pub async fn map_github_error(
response: http::Response<hyper::Body>,
) -> Result<http::Response<hyper::Body>> {
response: http::Response<BoxBody<Bytes, crate::Error>>,
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
if response.status().is_success() {
Ok(response)
} else {
let b: error::GitHubError = serde_json::from_slice(
body::to_bytes(response.into_body())
.await
.context(error::HyperSnafu)?
.as_ref(),
)
.context(error::SerdeSnafu)?;
let b: error::GitHubError =
serde_json::from_slice(response.into_body().collect().await?.to_bytes().as_ref())
.context(error::SerdeSnafu)?;

Err(error::Error::GitHub {
source: b,
@@ -459,12 +453,19 @@ where
Svc: Service<Request<String>, Response = Response<B>> + Send + 'static,
Svc::Future: Send + 'static,
Svc::Error: Into<BoxError>,
B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
B: http_body::Body<Data = bytes::Bytes> + Send + Sync + 'static,
B::Error: Into<BoxError>,
{
/// Build a [`Client`] instance with the current [`Service`] stack.
pub fn build(self) -> Result<Octocrab, Infallible> {
Ok(Octocrab::new(self.service, self.auth))
// Transform response body to `BoxBody<Bytes, crate::Error>` and use type erased error to avoid type parameters.
let service = MapResponseBodyLayer::new(|b: B| {
b.map_err(|e| ServiceSnafu.into_error(e.into())).boxed()
})
.layer(self.service)
.map_err(|e| e.into());

Ok(Octocrab::new(service, self.auth))
}
}

@@ -565,8 +566,8 @@ impl OctocrabBuilder<NoSvc, DefaultOctocrabBuilderConfig, NoAuth, NotLayerReady>
#[cfg(feature = "retry")]
pub fn set_connector_retry_service<S>(
&self,
connector: hyper::Client<S, String>,
) -> Retry<RetryConfig, hyper::Client<S, String>> {
connector: hyper_util::client::legacy::Client<S, String>,
) -> Retry<RetryConfig, hyper_util::client::legacy::Client<S, String>> {
let retry_layer = RetryLayer::new(self.config.retry_config.clone());

retry_layer.layer(connector)
@@ -576,7 +577,7 @@ impl OctocrabBuilder<NoSvc, DefaultOctocrabBuilderConfig, NoAuth, NotLayerReady>
pub fn set_connect_timeout_service<T>(&self, connector: T) -> TimeoutConnector<T>
where
T: Service<Uri> + Send,
T::Response: AsyncRead + AsyncWrite + Send + Unpin,
T::Response: hyper::rt::Read + hyper::rt::Write + Send + Unpin,
T::Future: Send + 'static,
T::Error: Into<BoxError>,
{
@@ -590,7 +591,7 @@ impl OctocrabBuilder<NoSvc, DefaultOctocrabBuilderConfig, NoAuth, NotLayerReady>

/// Build a [`Client`] instance with the current [`Service`] stack.
pub fn build(self) -> Result<Octocrab> {
let client: hyper::Client<_, String> = {
let client: hyper_util::client::legacy::Client<_, String> = {
#[cfg(all(not(feature = "opentls"), not(feature = "rustls")))]
let mut connector = HttpConnector::new();

@@ -600,7 +601,10 @@ impl OctocrabBuilder<NoSvc, DefaultOctocrabBuilderConfig, NoAuth, NotLayerReady>
#[cfg(feature = "rustls-webpki-tokio")]
let builder = builder.with_webpki_roots();
#[cfg(not(feature = "rustls-webpki-tokio"))]
let builder = builder.with_native_roots(); // enabled the `rustls-native-certs` feature in hyper-rustls
let builder = builder
.with_native_roots()
.map_err(Into::into)
.context(error::OtherSnafu)?; // enabled the `rustls-native-certs` feature in hyper-rustls

builder
.https_or_http() // Disable .https_only() during tests until: https://github.com/LukeMathWalker/wiremock-rs/issues/58 is resolved. Alternatively we can use conditional compilation to only enable this feature in tests, but it becomes rather ugly with integration tests.
@@ -614,7 +618,8 @@ impl OctocrabBuilder<NoSvc, DefaultOctocrabBuilderConfig, NoAuth, NotLayerReady>
#[cfg(feature = "timeout")]
let connector = self.set_connect_timeout_service(connector);

hyper::Client::builder().build(connector)
hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new())
.build(connector)
};

#[cfg(feature = "retry")]
@@ -637,7 +642,7 @@ impl OctocrabBuilder<NoSvc, DefaultOctocrabBuilderConfig, NoAuth, NotLayerReady>
tracing::debug!("requesting");
})
.on_response(
|res: &Response<hyper::Body>, _latency: Duration, span: &Span| {
|res: &Response<hyper::body::Incoming>, _latency: Duration, span: &Span| {
let status = res.status();
span.record("http.status_code", status.as_u16());
if status.is_client_error() || status.is_server_error() {
@@ -726,7 +731,7 @@ impl OctocrabBuilder<NoSvc, DefaultOctocrabBuilderConfig, NoAuth, NotLayerReady>
let client = ExtraHeadersLayer::new(Arc::new(hmap)).layer(client);

let client = MapResponseBodyLayer::new(|body| {
Box::new(http_body::Body::map_err(body, BoxError::from)) as Box<DynBody>
BodyExt::map_err(body, |e| HyperSnafu.into_error(e)).boxed()
})
.layer(client);

@@ -784,8 +789,6 @@ impl DefaultOctocrabBuilderConfig {
}
}

pub type DynBody = dyn http_body::Body<Data = Bytes, Error = BoxError> + Send + Unpin;

#[derive(Debug, Clone)]
struct CachedTokenInner {
expiration: Option<DateTime<Utc>>,
@@ -892,7 +895,7 @@ pub enum AuthState {
}

pub type OctocrabService = Buffer<
BoxService<http::Request<String>, http::Response<hyper::Body>, BoxError>,
BoxService<http::Request<String>, http::Response<BoxBody<Bytes, Error>>, BoxError>,
http::Request<String>,
>;

@@ -930,20 +933,15 @@ impl Octocrab {
}

/// Creates a new `Octocrab`.
fn new<S, B>(service: S, auth_state: AuthState) -> Self
fn new<S>(service: S, auth_state: AuthState) -> Self
where
S: Service<Request<String>, Response = Response<B>> + Send + 'static,
S: Service<Request<String>, Response = Response<BoxBody<Bytes, crate::Error>>>
+ Send
+ 'static,
S::Future: Send + 'static,
S::Error: Into<BoxError>,
B: http_body::Body<Data = bytes::Bytes> + Send + 'static,
B::Error: Into<BoxError>,
{
// Transform response body to `hyper::Body` and use type erased error to avoid type parameters.
let service = MapResponseBodyLayer::new(|b: B| Body::wrap_stream(b.into_stream()))
.layer(service)
.map_err(|e| e.into());

let service = Buffer::new(BoxService::new(service), 1024);
let service = Buffer::new(BoxService::new(service.map_err(Into::into)), 1024);

Self {
client: service,
@@ -1182,7 +1180,7 @@ impl Octocrab {
&self,
uri: impl TryInto<http::Uri>,
body: Option<&P>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let uri = uri
.try_into()
.map_err(|_| UriParseError {})
@@ -1204,7 +1202,10 @@ impl Octocrab {
}

/// Send a `GET` request with no additional post-processing.
pub async fn _get(&self, uri: impl TryInto<Uri>) -> Result<http::Response<hyper::Body>> {
pub async fn _get(
&self,
uri: impl TryInto<Uri>,
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
self._get_with_headers(uri, None).await
}

@@ -1234,8 +1235,11 @@ impl Octocrab {
uri
}

pub async fn body_to_string(&self, res: http::Response<Body>) -> Result<String> {
let body_bytes = body::to_bytes(res.into_body()).await.context(HyperSnafu)?;
pub async fn body_to_string(
&self,
res: http::Response<BoxBody<Bytes, crate::Error>>,
) -> Result<String> {
let body_bytes = res.into_body().collect().await?.to_bytes();
String::from_utf8(body_bytes.to_vec()).context(InvalidUtf8Snafu)
}

@@ -1263,7 +1267,7 @@ impl Octocrab {
&self,
uri: impl TryInto<Uri>,
headers: Option<http::header::HeaderMap>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let uri = uri
.try_into()
.map_err(|_| UriParseError {})
@@ -1297,7 +1301,7 @@ impl Octocrab {
&self,
uri: impl TryInto<Uri>,
body: Option<&B>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let uri = uri
.try_into()
.map_err(|_| UriParseError {})
@@ -1326,7 +1330,7 @@ impl Octocrab {
&self,
uri: impl TryInto<Uri>,
body: Option<&B>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let uri = uri
.try_into()
.map_err(|_| UriParseError {})
@@ -1380,7 +1384,7 @@ impl Octocrab {
&self,
uri: impl TryInto<Uri>,
body: Option<&B>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let uri = uri
.try_into()
.map_err(|_| UriParseError {})
@@ -1445,9 +1449,12 @@ impl Octocrab {
}

/// Send the given request to the underlying service
pub async fn send(&self, request: Request<String>) -> Result<http::Response<hyper::Body>> {
pub async fn send(
&self,
request: Request<String>,
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let mut svc = self.client.clone();
let response: Response<Body> = svc
let response: Response<BoxBody<Bytes, crate::Error>> = svc
.ready()
.await
.context(ServiceSnafu)?
@@ -1471,7 +1478,7 @@ impl Octocrab {
pub async fn execute(
&self,
request: http::Request<String>,
) -> Result<http::Response<hyper::Body>> {
) -> Result<http::Response<BoxBody<Bytes, crate::Error>>> {
let (mut parts, body) = request.into_parts();
// Saved request that we can retry later if necessary
let auth_header: Option<HeaderValue> = match self.auth_state {
@@ -1540,8 +1547,8 @@ impl Octocrab {

pub async fn follow_location_to_data(
&self,
response: http::Response<hyper::Body>,
) -> crate::Result<http::Response<hyper::Body>> {
response: http::Response<BoxBody<Bytes, Error>>,
) -> crate::Result<http::Response<BoxBody<Bytes, crate::Error>>> {
if let Some(redirect) = response.headers().get(http::header::LOCATION) {
let location = redirect.to_str().expect("Location URL not valid str");

21 changes: 11 additions & 10 deletions src/models/repos.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::*;
use crate::error;
use crate::error::SerdeSnafu;
use hyper::{body, Response};
use bytes::Bytes;
use http_body::Body;
use http_body_util::BodyExt;
use hyper::Response;
use snafu::ResultExt;
use url::Url;

@@ -229,14 +231,13 @@ impl Content {

#[async_trait::async_trait]
impl crate::FromResponse for ContentItems {
async fn from_response(response: Response<hyper::Body>) -> crate::Result<Self> {
let json: serde_json::Value = serde_json::from_slice(
body::to_bytes(response.into_body())
.await
.context(error::HyperSnafu)?
.as_ref(),
)
.context(SerdeSnafu)?;
async fn from_response<B>(response: Response<B>) -> crate::Result<Self>
where
B: Body<Data = Bytes, Error = crate::Error> + Send,
{
let json: serde_json::Value =
serde_json::from_slice(response.into_body().collect().await?.to_bytes().as_ref())
.context(SerdeSnafu)?;

if json.is_array() {
Ok(ContentItems {
20 changes: 10 additions & 10 deletions src/page.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use bytes::Bytes;
use http::Uri;
use hyper::body;
use http_body::Body;
use http_body_util::BodyExt;
use std::slice::Iter;
use std::str::FromStr;

use crate::error;
use crate::error::{SerdeSnafu, UriSnafu};
use snafu::{GenerateImplicitData, ResultExt};
use url::form_urlencoded;
@@ -166,21 +167,20 @@ impl<'iter, T> IntoIterator for &'iter Page<T> {

#[async_trait::async_trait]
impl<T: serde::de::DeserializeOwned> crate::FromResponse for Page<T> {
async fn from_response(response: http::Response<hyper::Body>) -> crate::Result<Self> {
async fn from_response<B>(response: http::Response<B>) -> crate::Result<Self>
where
B: Body<Data = Bytes, Error = crate::Error> + Send,
{
let HeaderLinks {
first,
prev,
next,
last,
} = get_links(response.headers())?;

let json: serde_json::Value = serde_json::from_slice(
body::to_bytes(response.into_body())
.await
.context(error::HyperSnafu)?
.as_ref(),
)
.context(SerdeSnafu)?;
let json: serde_json::Value =
serde_json::from_slice(response.into_body().collect().await?.to_bytes().as_ref())
.context(SerdeSnafu)?;

if json.is_array() {
Ok(Self {
43 changes: 0 additions & 43 deletions src/service/body.rs

This file was deleted.

6 changes: 3 additions & 3 deletions src/service/middleware/retry.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use futures_util::future;
use http::{Request, Response};
use hyper::{Body, Error};
use hyper_util::client::legacy::Error;
use tower::retry::Policy;

#[derive(Clone)]
@@ -9,13 +9,13 @@ pub enum RetryConfig {
Simple(usize),
}

impl Policy<Request<String>, Response<hyper::Body>, hyper::Error> for RetryConfig {
impl<B> Policy<Request<String>, Response<B>, Error> for RetryConfig {
type Future = futures_util::future::Ready<Self>;

fn retry(
&self,
_req: &Request<String>,
result: Result<&Response<Body>, &Error>,
result: Result<&Response<B>, &Error>,
) -> Option<Self::Future> {
match self {
RetryConfig::None => None,
1 change: 0 additions & 1 deletion src/service/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub mod body;
pub mod middleware;
6 changes: 3 additions & 3 deletions tests/actions_self_hosted_runners.rs
Original file line number Diff line number Diff line change
@@ -103,8 +103,8 @@ async fn test_context(
resp_body: Option<impl Serialize>,
) -> TestContext {
let template = match resp_body {
Some(resp_body) => ResponseTemplate::new(response_code).set_body_json(resp_body),
None => ResponseTemplate::new(response_code),
Some(resp_body) => ResponseTemplate::new(response_code.as_u16()).set_body_json(resp_body),
None => ResponseTemplate::new(response_code.as_u16()),
};
let server = setup_api(scope, method_name, actions_uri, None::<()>, template).await;
let client = Octocrab::builder()
@@ -127,7 +127,7 @@ async fn test_context_with_request_body(
request_body: impl Serialize,
resp_body: Option<impl Serialize>,
) -> TestContext {
let template = ResponseTemplate::new(response_code).set_body_json(resp_body);
let template = ResponseTemplate::new(response_code.as_u16()).set_body_json(resp_body);
let server = setup_api(
scope,
method_name,

0 comments on commit f350014

Please sign in to comment.