ureq/body/build.rs
1use std::io::{self, Cursor};
2use std::sync::Arc;
3
4use ureq_proto::BodyMode;
5
6use super::{Body, BodyDataSource, ContentEncoding, ResponseInfo};
7
8/// Builder for creating a response body.
9///
10/// This is useful for testing, or for [`Middleware`][crate::middleware::Middleware] that
11/// returns another body than the requested one.
12///
13/// # Example
14///
15/// ```
16/// use ureq::Body;
17/// use ureq::http::Response;
18///
19/// let body = Body::builder()
20/// .mime_type("text/plain")
21/// .charset("utf-8")
22/// .data("Hello world!");
23///
24/// let mut response = Response::builder()
25/// .status(200)
26/// .header("content-type", "text/plain; charset=utf-8")
27/// .body(body)?;
28///
29/// let text = response
30/// .body_mut()
31/// .read_to_string()?;
32///
33/// assert_eq!(text, "Hello world!");
34/// # Ok::<_, ureq::Error>(())
35/// ```
36pub struct BodyBuilder {
37 info: ResponseInfo,
38 limit: Option<u64>,
39}
40
41impl BodyBuilder {
42 pub(crate) fn new() -> Self {
43 BodyBuilder {
44 info: ResponseInfo {
45 content_encoding: ContentEncoding::None,
46 mime_type: None,
47 charset: None,
48 body_mode: BodyMode::NoBody,
49 },
50 limit: None,
51 }
52 }
53
54 /// Set the mime type of the body.
55 ///
56 /// **This does not set any HTTP headers. Affects Body decoding.**
57 ///
58 /// ```
59 /// use ureq::Body;
60 ///
61 /// let body = Body::builder()
62 /// .mime_type("text/plain")
63 /// .data("Hello world!");
64 /// ```
65 pub fn mime_type(mut self, mime_type: impl Into<String>) -> Self {
66 self.info.mime_type = Some(mime_type.into());
67 self
68 }
69
70 /// Set the mime type of the body
71 ///
72 /// **This does not set any HTTP headers. Affects Body decoding.**
73 ///
74 /// ```
75 /// use ureq::Body;
76 ///
77 /// let body = Body::builder()
78 /// .mime_type("text/plain")
79 /// .charset("utf-8")
80 /// .data("Hello world!");
81 /// ```
82 pub fn charset(mut self, charset: impl Into<String>) -> Self {
83 self.info.charset = Some(charset.into());
84 self
85 }
86
87 /// Limit how much data is to be released from the body.
88 ///
89 /// **This does not set any HTTP headers. Affects Body decoding.**
90 ///
91 /// ```
92 /// use ureq::Body;
93 ///
94 /// let body = Body::builder()
95 /// .mime_type("text/plain")
96 /// .charset("utf-8")
97 /// .limit(5)
98 /// // This will be limited to "Hello"
99 /// .data("Hello world!");
100 /// ```
101 pub fn limit(mut self, l: u64) -> Self {
102 self.limit = Some(l);
103 self
104 }
105
106 /// Creates the body data turned into bytes.
107 ///
108 /// Will automatically limit the body reader to the lenth of the data.
109 pub fn data(mut self, data: impl Into<Vec<u8>>) -> Body {
110 let data: Vec<u8> = data.into();
111
112 let len = self.limit.unwrap_or(data.len() as u64);
113 self.info.body_mode = BodyMode::LengthDelimited(len);
114
115 self.reader(Cursor::new(data))
116 }
117
118 /// Creates a body from a streaming reader.
119 ///
120 /// The reader can be limited by using `.limit()` or that the reader
121 /// reaches the end.
122 pub fn reader(self, data: impl io::Read + Send + Sync + 'static) -> Body {
123 Body {
124 source: BodyDataSource::Reader(Box::new(data)),
125 info: Arc::new(self.info),
126 }
127 }
128}