Skip to content

Commit 48fa5dc

Browse files
authored
Move more towards header methods (#857)
1 parent 546a17f commit 48fa5dc

File tree

23 files changed

+193
-415
lines changed

23 files changed

+193
-415
lines changed

sdk/core/src/headers/mod.rs

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@ impl Headers {
6666

6767
/// Get a header value or error if it is not found
6868
pub fn get_or_err(&self, key: &HeaderName) -> crate::Result<&HeaderValue> {
69-
let value = self.0.get(key);
70-
value.ok_or_else(|| {
71-
Error::with_message(ErrorKind::Other, || {
69+
self.get(key).ok_or_else(|| {
70+
Error::with_message(ErrorKind::DataConversion, || {
7271
format!("header not found {}", key.as_str())
7372
})
7473
})
@@ -94,41 +93,32 @@ impl Headers {
9493
self.get_or_err(key).map(|v| v.as_str().to_string())
9594
}
9695

97-
/// Get a header value as a u64
98-
pub fn get_as_u64(&self, key: &HeaderName) -> crate::Result<Option<u64>> {
96+
pub fn get_optional_as<V, E>(&self, key: &HeaderName) -> crate::Result<Option<V>>
97+
where
98+
V: FromStr<Err = E>,
99+
E: std::error::Error + Send + Sync + 'static,
100+
{
99101
self.get(key)
100102
.map(|v: &HeaderValue| {
101103
let v = v.as_str();
102-
v.parse::<u64>()
103-
.with_context(ErrorKind::DataConversion, || {
104-
format!("unable to parse header into u64 {key:?}: {v}")
105-
})
104+
v.parse::<V>().with_context(ErrorKind::DataConversion, || {
105+
let ty = std::any::type_name::<V>();
106+
format!("unable to parse header '{key:?}: {v}' into {ty}",)
107+
})
106108
})
107109
.transpose()
108110
}
109111

110-
/// Get a header value as a u64 or error if it is not found
111-
pub fn get_as_u64_or_err(&self, key: &HeaderName) -> crate::Result<u64> {
112-
let v = self.get_or_err(key)?;
113-
let v = v.as_str();
114-
v.parse::<u64>()
115-
.with_context(ErrorKind::DataConversion, || {
116-
format!("unable to parse header into u64 {key:?}: {v}")
117-
})
118-
}
119-
120-
pub fn get_as_enum<V: FromStr<Err = E>, E>(&self, key: &HeaderName) -> crate::Result<Option<V>>
112+
pub fn get_as<V, E>(&self, key: &HeaderName) -> crate::Result<V>
121113
where
114+
V: FromStr<Err = E>,
122115
E: std::error::Error + Send + Sync + 'static,
123116
{
124-
self.get(key)
125-
.map(|v: &HeaderValue| {
126-
let v = v.as_str();
127-
v.parse::<V>().with_context(ErrorKind::DataConversion, || {
128-
format!("unable to parse header into enum {key:?}: {v}")
129-
})
117+
self.get_optional_as(key)?.ok_or_else(|| {
118+
Error::with_message(ErrorKind::Other, || {
119+
format!("header not found {}", key.as_str())
130120
})
131-
.transpose()
121+
})
132122
}
133123

134124
/// Insert a header name/value pair

sdk/core/src/headers/utilities.rs

Lines changed: 20 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -3,67 +3,6 @@ use crate::error::{Error, ErrorKind};
33
use crate::request_options::LeaseId;
44
use crate::{RequestId, SessionToken};
55
use chrono::{DateTime, FixedOffset, Utc};
6-
use std::str::FromStr;
7-
8-
pub fn get_option_str_from_headers<'a>(
9-
headers: &'a Headers,
10-
key: &HeaderName,
11-
) -> crate::Result<Option<&'a str>> {
12-
let h = match headers.get(key) {
13-
Some(h) => h,
14-
None => return Ok(None),
15-
};
16-
Ok(Some(h.as_str()))
17-
}
18-
19-
pub fn get_str_from_headers<'a>(headers: &'a Headers, key: &HeaderName) -> crate::Result<&'a str> {
20-
get_option_str_from_headers(headers, key)?.ok_or_else(|| {
21-
Error::with_message(ErrorKind::DataConversion, || {
22-
format!("could not find '{key:?}' in headers")
23-
})
24-
})
25-
}
26-
27-
pub fn get_option_from_headers<T>(headers: &Headers, key: &HeaderName) -> crate::Result<Option<T>>
28-
where
29-
T: std::str::FromStr + 'static,
30-
T::Err: std::error::Error + Send + Sync,
31-
{
32-
let h = match get_option_str_from_headers(headers, key)? {
33-
Some(h) => h,
34-
None => return Ok(None),
35-
};
36-
37-
Ok(Some(h.parse().map_err(|e| {
38-
Error::full(
39-
ErrorKind::DataConversion,
40-
e,
41-
format!(
42-
"failed to parse header '{:?}' as {:?}",
43-
key,
44-
std::any::TypeId::of::<T>()
45-
),
46-
)
47-
})?))
48-
}
49-
50-
pub fn get_from_headers<T>(headers: &Headers, key: &HeaderName) -> crate::Result<T>
51-
where
52-
T: std::str::FromStr + 'static,
53-
T::Err: std::error::Error + Send + Sync,
54-
{
55-
get_str_from_headers(headers, key)?.parse().map_err(|e| {
56-
Error::full(
57-
ErrorKind::DataConversion,
58-
e,
59-
format!(
60-
"failed to parse header '{:?}' as {:?}",
61-
key,
62-
std::any::TypeId::of::<T>()
63-
),
64-
)
65-
})
66-
}
676

687
pub fn parse_date_from_str(date: &str, fmt: &str) -> crate::Result<DateTime<FixedOffset>> {
698
DateTime::parse_from_str(date, fmt).map_err(|e| {
@@ -88,37 +27,22 @@ pub fn parse_date_from_rfc2822(date: &str) -> crate::Result<DateTime<FixedOffset
8827
})
8928
}
9029

91-
pub fn parse_int<F>(s: &str) -> crate::Result<F>
92-
where
93-
F: FromStr<Err = std::num::ParseIntError>,
94-
{
95-
FromStr::from_str(s).map_err(|e| {
96-
Error::full(
97-
ErrorKind::DataConversion,
98-
e,
99-
format!("failed to parse string '{}' as int", s),
100-
)
101-
})
102-
}
103-
10430
pub fn lease_id_from_headers(headers: &Headers) -> crate::Result<LeaseId> {
105-
get_from_headers(headers, &LEASE_ID)
31+
headers.get_as(&LEASE_ID)
10632
}
10733

10834
pub fn request_id_from_headers(headers: &Headers) -> crate::Result<RequestId> {
109-
get_from_headers(headers, &REQUEST_ID)
35+
headers.get_as(&REQUEST_ID)
11036
}
11137

11238
pub fn client_request_id_from_headers_optional(headers: &Headers) -> Option<String> {
113-
get_option_from_headers(headers, &CLIENT_REQUEST_ID)
114-
.ok()
115-
.flatten()
39+
headers.get_as_string(&CLIENT_REQUEST_ID)
11640
}
11741

11842
pub fn last_modified_from_headers_optional(
11943
headers: &Headers,
12044
) -> crate::Result<Option<DateTime<Utc>>> {
121-
get_option_from_headers(headers, &LAST_MODIFIED)
45+
headers.get_optional_as(&LAST_MODIFIED)
12246
}
12347

12448
pub fn date_from_headers(headers: &Headers) -> crate::Result<DateTime<Utc>> {
@@ -133,7 +57,7 @@ pub fn rfc2822_from_headers_mandatory(
13357
headers: &Headers,
13458
header_name: &HeaderName,
13559
) -> crate::Result<DateTime<Utc>> {
136-
let date = get_str_from_headers(headers, header_name)?;
60+
let date = headers.get_as_str_or_err(header_name)?;
13761
utc_date_from_rfc2822(date)
13862
}
13963

@@ -145,63 +69,63 @@ pub fn utc_date_from_rfc2822(date: &str) -> crate::Result<DateTime<Utc>> {
14569
pub fn continuation_token_from_headers_optional(
14670
headers: &Headers,
14771
) -> crate::Result<Option<String>> {
148-
Ok(get_option_str_from_headers(headers, &CONTINUATION)?.map(String::from))
72+
Ok(headers.get_as_string(&CONTINUATION))
14973
}
15074

15175
pub fn sku_name_from_headers(headers: &Headers) -> crate::Result<String> {
152-
Ok(get_str_from_headers(headers, &SKU_NAME)?.to_owned())
76+
headers.get_as_string_or_err(&SKU_NAME)
15377
}
15478

15579
pub fn account_kind_from_headers(headers: &Headers) -> crate::Result<String> {
156-
Ok(get_str_from_headers(headers, &ACCOUNT_KIND)?.to_owned())
80+
headers.get_as_string_or_err(&ACCOUNT_KIND)
15781
}
15882

15983
pub fn etag_from_headers_optional(headers: &Headers) -> crate::Result<Option<String>> {
160-
Ok(get_option_str_from_headers(headers, &ETAG)?.map(String::from))
84+
Ok(headers.get_as_string(&ETAG))
16185
}
16286

16387
pub fn etag_from_headers(headers: &Headers) -> crate::Result<String> {
164-
Ok(get_str_from_headers(headers, &ETAG)?.to_owned())
88+
headers.get_as_string_or_err(&ETAG)
16589
}
16690

16791
pub fn lease_time_from_headers(headers: &Headers) -> crate::Result<u8> {
168-
get_from_headers(headers, &LEASE_TIME)
92+
headers.get_as(&LEASE_TIME)
16993
}
17094

17195
#[cfg(not(feature = "azurite_workaround"))]
17296
pub fn delete_type_permanent_from_headers(headers: &Headers) -> crate::Result<bool> {
173-
get_from_headers(headers, &DELETE_TYPE_PERMANENT)
97+
headers.get_as(&DELETE_TYPE_PERMANENT)
17498
}
17599

176100
#[cfg(feature = "azurite_workaround")]
177101
pub fn delete_type_permanent_from_headers(headers: &Headers) -> crate::Result<Option<bool>> {
178-
get_option_from_headers(headers, &DELETE_TYPE_PERMANENT)
102+
headers.get_optional_as(&DELETE_TYPE_PERMANENT)
179103
}
180104

181105
pub fn sequence_number_from_headers(headers: &Headers) -> crate::Result<u64> {
182-
get_from_headers(headers, &BLOB_SEQUENCE_NUMBER)
106+
headers.get_as(&BLOB_SEQUENCE_NUMBER)
183107
}
184108

185109
pub fn session_token_from_headers(headers: &Headers) -> crate::Result<SessionToken> {
186-
get_str_from_headers(headers, &SESSION_TOKEN).map(ToOwned::to_owned)
110+
headers.get_as_string_or_err(&SESSION_TOKEN)
187111
}
188112

189113
pub fn server_from_headers(headers: &Headers) -> crate::Result<&str> {
190-
get_str_from_headers(headers, &SERVER)
114+
headers.get_as_str_or_err(&SERVER)
191115
}
192116

193117
pub fn version_from_headers(headers: &Headers) -> crate::Result<&str> {
194-
get_str_from_headers(headers, &VERSION)
118+
headers.get_as_str_or_err(&VERSION)
195119
}
196120

197121
pub fn request_server_encrypted_from_headers(headers: &Headers) -> crate::Result<bool> {
198-
get_from_headers(headers, &REQUEST_SERVER_ENCRYPTED)
122+
headers.get_as(&REQUEST_SERVER_ENCRYPTED)
199123
}
200124

201125
pub fn content_type_from_headers(headers: &Headers) -> crate::Result<&str> {
202-
get_str_from_headers(headers, &CONTENT_TYPE)
126+
headers.get_as_str_or_err(&CONTENT_TYPE)
203127
}
204128

205129
pub fn item_count_from_headers(headers: &Headers) -> crate::Result<u32> {
206-
get_from_headers(headers, &ITEM_COUNT)
130+
headers.get_as(&ITEM_COUNT)
207131
}

0 commit comments

Comments
 (0)