Skip to content

Commit fc06596

Browse files
committed
chore: reduce visibility of fields + renaming
1 parent 0718b6f commit fc06596

File tree

8 files changed

+190
-67
lines changed

8 files changed

+190
-67
lines changed

libdd-http-client/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
//! let client = HttpClient::new("http://localhost:8080".to_string(), Duration::from_secs(5))?;
3838
//! let request = HttpRequest::new(HttpMethod::Get, "http://localhost:8080/ping".to_string());
3939
//! let response = client.send(request).await?;
40-
//! println!("Status: {}", response.status_code);
40+
//! println!("Status: {}", response.status_code());
4141
//! # Ok(())
4242
//! # }
4343
//! ```

libdd-http-client/src/request.rs

Lines changed: 130 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ pub enum HttpMethod {
2828
#[derive(Debug, Clone)]
2929
pub struct MultipartPart {
3030
/// The field name for this part.
31-
pub name: String,
31+
pub(crate) name: String,
3232
/// The part's data.
33-
pub data: bytes::Bytes,
33+
pub(crate) data: bytes::Bytes,
3434
/// Optional filename for this part.
35-
pub filename: Option<String>,
35+
pub(crate) filename: Option<String>,
3636
/// Optional MIME content type (e.g. `"application/json"`).
37-
pub content_type: Option<String>,
37+
pub(crate) content_type: Option<String>,
3838
}
3939

4040
impl MultipartPart {
@@ -49,42 +49,68 @@ impl MultipartPart {
4949
}
5050

5151
/// Set the filename for this part.
52-
pub fn filename(mut self, filename: impl Into<String>) -> Self {
52+
#[inline]
53+
pub fn with_filename(mut self, filename: impl Into<String>) -> Self {
5354
self.filename = Some(filename.into());
5455
self
5556
}
5657

5758
/// Set the MIME content type for this part.
58-
pub fn content_type(mut self, content_type: impl Into<String>) -> Self {
59+
#[inline]
60+
pub fn with_content_type(mut self, content_type: impl Into<String>) -> Self {
5961
self.content_type = Some(content_type.into());
6062
self
6163
}
64+
65+
/// Returns the field name for this part.
66+
#[inline]
67+
pub fn name(&self) -> &str {
68+
&self.name
69+
}
70+
71+
/// Returns the raw bytes of this part.
72+
#[inline]
73+
pub fn data(&self) -> &bytes::Bytes {
74+
&self.data
75+
}
76+
77+
/// Returns the filename, if any.
78+
#[inline]
79+
pub fn filename(&self) -> Option<&str> {
80+
self.filename.as_deref()
81+
}
82+
83+
/// Returns the MIME content type, if any.
84+
#[inline]
85+
pub fn content_type(&self) -> Option<&str> {
86+
self.content_type.as_deref()
87+
}
6288
}
6389

6490
/// An outgoing HTTP request.
6591
#[derive(Debug, Clone)]
6692
pub struct HttpRequest {
6793
/// HTTP method.
68-
pub method: HttpMethod,
94+
pub(crate) method: HttpMethod,
6995

7096
/// Absolute URL string (e.g. `"http://localhost:8080/v0.4/traces"`).
71-
pub url: String,
97+
pub(crate) url: String,
7298

7399
/// Request headers as a list of (name, value) pairs.
74100
///
75101
/// Vec preserves insertion order and allows duplicate header names,
76102
/// both of which are valid in HTTP.
77-
pub headers: Vec<(String, String)>,
103+
pub(crate) headers: Vec<(String, String)>,
78104

79105
/// Request body bytes. Empty for requests with no body.
80-
pub body: bytes::Bytes,
106+
pub(crate) body: bytes::Bytes,
81107

82108
/// Per-request timeout. Overrides the client-level timeout if set.
83-
pub timeout: Option<Duration>,
109+
pub(crate) timeout: Option<Duration>,
84110

85111
/// Multipart form-data parts. When non-empty, the request is sent as
86112
/// multipart/form-data and `body` is ignored.
87-
pub multipart_parts: Vec<MultipartPart>,
113+
pub(crate) multipart_parts: Vec<MultipartPart>,
88114
}
89115

90116
impl HttpRequest {
@@ -101,10 +127,86 @@ impl HttpRequest {
101127
}
102128
}
103129

104-
/// Add a multipart part to this request. When any parts are present, the
105-
/// request is sent as multipart/form-data and `body` is ignored.
106-
pub fn add_multipart_part(&mut self, part: MultipartPart) {
130+
/// Append a header to this request.
131+
#[inline]
132+
pub fn with_header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
133+
self.headers.push((name.into(), value.into()));
134+
self
135+
}
136+
137+
/// Set the request body.
138+
#[inline]
139+
pub fn with_body(mut self, body: impl Into<bytes::Bytes>) -> Self {
140+
self.body = body.into();
141+
self
142+
}
143+
144+
/// Set the per-request timeout, overriding the client-level timeout.
145+
#[inline]
146+
pub fn with_timeout(mut self, timeout: Duration) -> Self {
147+
self.timeout = Some(timeout);
148+
self
149+
}
150+
151+
/// Append a multipart part to this request.
152+
#[inline]
153+
pub fn with_multipart_part(mut self, part: MultipartPart) -> Self {
107154
self.multipart_parts.push(part);
155+
self
156+
}
157+
158+
/// Returns the HTTP method.
159+
#[inline]
160+
pub fn method(&self) -> HttpMethod {
161+
self.method
162+
}
163+
164+
/// Returns the request URL.
165+
#[inline]
166+
pub fn url(&self) -> &str {
167+
&self.url
168+
}
169+
170+
/// Returns the request headers.
171+
#[inline]
172+
pub fn headers(&self) -> &[(String, String)] {
173+
&self.headers
174+
}
175+
176+
/// Returns the request body.
177+
#[inline]
178+
pub fn body(&self) -> &bytes::Bytes {
179+
&self.body
180+
}
181+
182+
/// Returns the per-request timeout override, if set.
183+
#[inline]
184+
pub fn timeout(&self) -> Option<Duration> {
185+
self.timeout
186+
}
187+
188+
/// Returns the multipart parts.
189+
#[inline]
190+
pub fn multipart_parts(&self) -> &[MultipartPart] {
191+
&self.multipart_parts
192+
}
193+
194+
/// Returns a mutable reference to the headers list.
195+
#[inline]
196+
pub fn headers_mut(&mut self) -> &mut Vec<(String, String)> {
197+
&mut self.headers
198+
}
199+
200+
/// Returns a mutable reference to the request body.
201+
#[inline]
202+
pub fn body_mut(&mut self) -> &mut bytes::Bytes {
203+
&mut self.body
204+
}
205+
206+
/// Returns a mutable reference to the multipart parts list.
207+
#[inline]
208+
pub fn multipart_parts_mut(&mut self) -> &mut Vec<MultipartPart> {
209+
&mut self.multipart_parts
108210
}
109211
}
110212

@@ -126,7 +228,7 @@ mod tests {
126228
fn request_with_headers_and_body() {
127229
let mut req = HttpRequest::new(HttpMethod::Post, "http://localhost/data".to_owned());
128230
req.headers
129-
.push(("Content-Type".to_string(), "application/json".to_owned()));
231+
.push(("Content-Type".to_owned(), "application/json".to_owned()));
130232
req.body = bytes::Bytes::from_static(b"{\"key\":\"value\"}");
131233
req.timeout = Some(Duration::from_secs(10));
132234

@@ -140,4 +242,16 @@ mod tests {
140242
assert_eq!(HttpMethod::Get, HttpMethod::Get);
141243
assert_ne!(HttpMethod::Get, HttpMethod::Post);
142244
}
245+
246+
#[test]
247+
fn test_multipart_part_builder() {
248+
let part = MultipartPart::new("name", bytes::Bytes::from_static(b"data"))
249+
.with_filename("test.txt")
250+
.with_content_type("text/plain");
251+
252+
assert_eq!(part.name, "name");
253+
assert_eq!(part.data.as_ref(), b"data");
254+
assert_eq!(part.filename.as_deref(), Some("test.txt"));
255+
assert_eq!(part.content_type.as_deref(), Some("text/plain"));
256+
}
143257
}

libdd-http-client/src/response.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,31 @@
77
#[derive(Debug)]
88
pub struct HttpResponse {
99
/// HTTP status code (e.g. 200, 404, 503).
10-
pub status_code: u16,
11-
10+
pub(crate) status_code: u16,
1211
/// Response headers as a list of (name, value) pairs.
13-
pub headers: Vec<(String, String)>,
14-
12+
pub(crate) headers: Vec<(String, String)>,
1513
/// Response body bytes.
16-
pub body: bytes::Bytes,
14+
pub(crate) body: bytes::Bytes,
15+
}
16+
17+
impl HttpResponse {
18+
/// Returns the HTTP status code.
19+
#[inline]
20+
pub fn status_code(&self) -> u16 {
21+
self.status_code
22+
}
23+
24+
/// Returns the response headers as a slice of (name, value) pairs.
25+
#[inline]
26+
pub fn headers(&self) -> &[(String, String)] {
27+
&self.headers
28+
}
29+
30+
/// Returns the response body bytes.
31+
#[inline]
32+
pub fn body(&self) -> &bytes::Bytes {
33+
&self.body
34+
}
1735
}
1836

1937
#[cfg(test)]

libdd-http-client/tests/connection_pool.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ async fn test_multiple_requests_reuse_client() {
2323
let req = HttpRequest::new(HttpMethod::Get, server.url("/ping"));
2424
let response = client.send(req).await.unwrap();
2525
assert_eq!(
26-
response.status_code, 200,
26+
response.status_code(),
27+
200,
2728
"request {i} should have succeeded"
2829
);
2930
}
@@ -54,9 +55,9 @@ async fn test_concurrent_requests_succeed() {
5455

5556
let (r1, r2, r3) = tokio::join!(client.send(req1), client.send(req2), client.send(req3));
5657

57-
assert_eq!(r1.unwrap().status_code, 200);
58-
assert_eq!(r2.unwrap().status_code, 200);
59-
assert_eq!(r3.unwrap().status_code, 200);
58+
assert_eq!(r1.unwrap().status_code(), 200);
59+
assert_eq!(r2.unwrap().status_code(), 200);
60+
assert_eq!(r3.unwrap().status_code(), 200);
6061

6162
mock.assert_calls_async(3).await;
6263
}

libdd-http-client/tests/http_round_trip.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@ async fn test_post_round_trip() {
1919

2020
let client = HttpClient::new(server.url("/"), Duration::from_secs(5)).unwrap();
2121

22-
let mut req = HttpRequest::new(HttpMethod::Post, server.url("/v0.4/traces"));
23-
req.headers
24-
.push(("Content-Type".to_owned(), "application/msgpack".to_owned()));
25-
req.body = bytes::Bytes::from_static(b"test payload");
22+
let req = HttpRequest::new(HttpMethod::Post, server.url("/v0.4/traces"))
23+
.with_header("Content-Type", "application/msgpack")
24+
.with_body(bytes::Bytes::from_static(b"test payload"));
2625

2726
let response = client.send(req).await.unwrap();
2827

29-
assert_eq!(response.status_code, 200);
30-
assert_eq!(response.body.as_ref(), b"ok");
28+
assert_eq!(response.status_code(), 200);
29+
assert_eq!(response.body().as_ref(), b"ok");
3130

3231
mock.assert_async().await;
3332
}
@@ -51,8 +50,8 @@ async fn test_get_round_trip() {
5150
let req = HttpRequest::new(HttpMethod::Get, server.url("/info"));
5251
let response = client.send(req).await.unwrap();
5352

54-
assert_eq!(response.status_code, 200);
55-
assert_eq!(response.body.as_ref(), br#"{"version":"1.0"}"#);
53+
assert_eq!(response.status_code(), 200);
54+
assert_eq!(response.body().as_ref(), br#"{"version":"1.0"}"#);
5655

5756
mock.assert_async().await;
5857
}
@@ -74,7 +73,10 @@ async fn test_response_headers_returned() {
7473
let req = HttpRequest::new(HttpMethod::Get, server.url("/headers"));
7574
let response = client.send(req).await.unwrap();
7675

77-
let custom_header = response.headers.iter().find(|(name, _)| name == "x-custom");
76+
let custom_header = response
77+
.headers()
78+
.iter()
79+
.find(|(name, _)| name == "x-custom");
7880
assert!(
7981
custom_header.is_some(),
8082
"expected x-custom header in response"
@@ -132,8 +134,8 @@ async fn test_4xx_returns_ok_when_errors_disabled() {
132134
let req = HttpRequest::new(HttpMethod::Get, server.url("/not-found"));
133135
let response = client.send(req).await.unwrap();
134136

135-
assert_eq!(response.status_code, 404);
136-
assert_eq!(response.body.as_ref(), b"not found");
137+
assert_eq!(response.status_code(), 404);
138+
assert_eq!(response.body().as_ref(), b"not found");
137139
}
138140

139141
#[cfg_attr(miri, ignore)]

libdd-http-client/tests/multipart_test.rs

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ async fn test_multipart_upload() {
1919

2020
let client = HttpClient::new(server.url("/"), Duration::from_secs(5)).unwrap();
2121

22-
let mut req = HttpRequest::new(HttpMethod::Post, server.url("/upload"));
23-
req.add_multipart_part(
24-
MultipartPart::new("metadata", br#"{"case_id":"123"}"#.as_slice())
25-
.content_type("application/json"),
26-
);
27-
req.add_multipart_part(
28-
MultipartPart::new("file", b"binary data here".as_slice())
29-
.filename("data.bin")
30-
.content_type("application/octet-stream"),
31-
);
22+
let req = HttpRequest::new(HttpMethod::Post, server.url("/upload"))
23+
.with_multipart_part(
24+
MultipartPart::new("metadata", br#"{"case_id":"123"}"#.as_slice())
25+
.with_content_type("application/json"),
26+
)
27+
.with_multipart_part(
28+
MultipartPart::new("file", b"binary data here".as_slice())
29+
.with_filename("data.bin")
30+
.with_content_type("application/octet-stream"),
31+
);
3232

3333
let response = client.send(req).await.unwrap();
34-
assert_eq!(response.status_code, 200);
34+
assert_eq!(response.status_code(), 200);
3535

3636
mock.assert_async().await;
3737
}
@@ -52,23 +52,11 @@ async fn test_multipart_sets_content_type() {
5252

5353
let client = HttpClient::new(server.url("/"), Duration::from_secs(5)).unwrap();
5454

55-
let mut req = HttpRequest::new(HttpMethod::Post, server.url("/upload"));
56-
req.add_multipart_part(MultipartPart::new("field", b"value".as_slice()));
55+
let req = HttpRequest::new(HttpMethod::Post, server.url("/upload"))
56+
.with_multipart_part(MultipartPart::new("field", b"value".as_slice()));
5757

5858
let response = client.send(req).await.unwrap();
59-
assert_eq!(response.status_code, 200);
59+
assert_eq!(response.status_code(), 200);
6060

6161
mock.assert_async().await;
6262
}
63-
64-
#[test]
65-
fn test_multipart_part_builder() {
66-
let part = MultipartPart::new("name", bytes::Bytes::from_static(b"data"))
67-
.filename("test.txt")
68-
.content_type("text/plain");
69-
70-
assert_eq!(part.name, "name");
71-
assert_eq!(part.data.as_ref(), b"data");
72-
assert_eq!(part.filename.as_deref(), Some("test.txt"));
73-
assert_eq!(part.content_type.as_deref(), Some("text/plain"));
74-
}

0 commit comments

Comments
 (0)