-
Notifications
You must be signed in to change notification settings - Fork 248
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
add Method
& StatusCode
to azure_core
#849
Conversation
@@ -1,4 +1,5 @@ | |||
use std::ops::Deref; | |||
use crate::error::{Error, ErrorKind}; | |||
use std::{ops::Deref, str::FromStr}; | |||
|
|||
#[derive(PartialEq, Eq, Clone, Debug)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not Copy
?
|
||
/// Construct a new `HttpClient` with the `reqwest` backend. | ||
pub fn new_http_client() -> std::sync::Arc<dyn HttpClient> { | ||
std::sync::Arc::new(::reqwest::Client::new()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::sync::Arc::new(::reqwest::Client::new()) | |
std::sync::Arc::new(reqwest::Client::new()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put these in a module named reqwest, so needed that prefix. Could rename the module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... or you could rename the 3rd party crate. use ::request as hyperium_request
.
} | ||
|
||
#[async_trait] | ||
impl HttpClient for ::reqwest::Client { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
impl HttpClient for ::reqwest::Client { | |
impl HttpClient for reqwest::Client { |
} | ||
|
||
fn try_from_method(method: &crate::Method) -> crate::Result<::reqwest::Method> { | ||
::reqwest::Method::from_str(method.as_ref()).map_kind(ErrorKind::DataConversion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
::reqwest::Method::from_str(method.as_ref()).map_kind(ErrorKind::DataConversion) | |
reqwest::Method::from_str(method.as_ref()).map_kind(ErrorKind::DataConversion) |
This should never happen. I wonder if we should have a wrapper error that says something like: if you ever see this, please report a bug.
http_types::StatusCode::try_from(status) | ||
.map_err(|_| { | ||
Error::with_message(ErrorKind::DataConversion, || { | ||
format!("invalid status code {status}") | ||
}) | ||
}) | ||
.map(crate::StatusCode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use crate::StatusCode
's TryFrom<u16>
impl
} | ||
pub fn from_u16(value: u16) -> crate::Result<Self> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | |
pub fn from_u16(value: u16) -> crate::Result<Self> { | |
} | |
pub fn from_u16(value: u16) -> crate::Result<Self> { |
pub const TOO_MANY_REQUESTS: StatusCode = StatusCode(http_types::StatusCode::TooManyRequests); | ||
} | ||
|
||
impl Default for StatusCode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I like this impl. OK
does not logically feel like the "default" status code to me.
log = "0.4" | ||
once_cell = "1.0" | ||
# once_cell = "1.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can remove. http crate doesn’t have Mehod::MERGE.
.parse::<u16>() | ||
.map_err(|_| { | ||
Error::message(ErrorKind::DataConversion, "invalid HTTP status code") | ||
})?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think StatusCode
has a TryFrom<&str>
impl no?
@@ -40,7 +40,7 @@ impl Transaction { | |||
for transaction_operation in self.transaction_operations.iter() { | |||
s.push_str(&format!("--changeset_{}\nContent-Type: application/http\nContent-Transfer-Encoding: binary\n\n", self.change_set_uuid.hyphenated())); | |||
s.push_str(&format!( | |||
"{} {} HTTP/1.1\n", | |||
"{:?} {} HTTP/1.1\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I like that method
doesn't have a display. The string representations of the HTTP methods are cononical no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string representations of the HTTP methods are cononical no?
Correct. As per RFC 9110, 9: Methods:
The method token is case-sensitive because it might be used as a gateway to object-based systems with case-sensitive method names. By convention, standardized methods are defined in all-uppercase US-ASCII letters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bigger question is do we want to use the http-types StatusCode directly. This wrapper shows what the differences are, where the gaps are.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like I'm missing some context about direction. Obviously as the lead author of http-types
I'm thrilled by the prospect that we may want to use it for the azure SDK. But I want to make sure that we properly understand and discuss the tradeoffs of doing so. Because if we're going to adopt it, I want to make sure we're doing so for the right reasons.
For example: should we expose http-types
types from the Rust Azure SDK's public API? If we do that, how do we feel about the governance? Are there any reasons beyond the code changes in this API why we may want to adopt this?
I think it would be worth laying out a vision of how you see the integration working out in the longer term. And then maybe we can discuss it offline here / perhaps bring it to a meeting to discuss further?
pub const BAD_GATEWAY: StatusCode = StatusCode(http_types::StatusCode::BadGateway); | ||
pub const GATEWAY_TIMEOUT: StatusCode = StatusCode(http_types::StatusCode::GatewayTimeout); | ||
pub const INTERNAL_SERVER_ERROR: StatusCode = | ||
StatusCode(http_types::StatusCode::InternalServerError); | ||
pub const NOT_MODIFIED: StatusCode = StatusCode(http_types::StatusCode::NotModified); | ||
pub const OK: StatusCode = StatusCode(http_types::StatusCode::Ok); | ||
pub const REQUEST_TIMEOUT: StatusCode = StatusCode(http_types::StatusCode::RequestTimeout); | ||
pub const SERVICE_UNAVAILABLE: StatusCode = | ||
StatusCode(http_types::StatusCode::ServiceUnavailable); | ||
pub const TOO_MANY_REQUESTS: StatusCode = StatusCode(http_types::StatusCode::TooManyRequests); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm so-so about this construct. In my opinion status codes are best represented in Rust as non-exhaustive enums; providing a balance between extensibility and enumerability.
I feel like we'd be better off either re-exporting http_types::StatusCode
as-is, or if we don't want to rely on using http-types
in our public API, either copying over the implementation - or creating a wrapper/type-alias to it.
We'll discuss this in our next meeting. A purpose of this PR was to show the differences between https://docs.rs/http-types/latest/src/http_types/method.rs.html #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Method { https://docs.rs/http-types/latest/src/http_types/status_code.rs.html #[repr(u16)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum StatusCode {
https://docs.rs/http/latest/src/http/status.rs.html
Differences
I created #852 with a subset of changes that leave |
This removes the last dependency on the
http
crate by adding aMethod
andStatusCode
types. I'm interested in having compatibility with http-types and supporting surf in addition toreqwest
. This draft wrapshttp-types
implementations ofMethod
andStatusCode
, but exposes the API fromhttp
crate that we are using. There are a few different ways we could go here. Looking for feedback.