Coverage Report

Created: 2026-04-29 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ureq-3.3.0/src/body/build.rs
Line
Count
Source
1
use std::io::{self, Cursor};
2
use std::sync::Arc;
3
4
use ureq_proto::BodyMode;
5
6
use 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
/// ```
36
pub struct BodyBuilder {
37
    info: ResponseInfo,
38
    limit: Option<u64>,
39
}
40
41
impl BodyBuilder {
42
0
    pub(crate) fn new() -> Self {
43
0
        BodyBuilder {
44
0
            info: ResponseInfo {
45
0
                content_encoding: ContentEncoding::None,
46
0
                mime_type: None,
47
0
                charset: None,
48
0
                body_mode: BodyMode::NoBody,
49
0
            },
50
0
            limit: None,
51
0
        }
52
0
    }
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
0
    pub fn mime_type(mut self, mime_type: impl Into<String>) -> Self {
66
0
        self.info.mime_type = Some(mime_type.into());
67
0
        self
68
0
    }
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
0
    pub fn charset(mut self, charset: impl Into<String>) -> Self {
83
0
        self.info.charset = Some(charset.into());
84
0
        self
85
0
    }
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
0
    pub fn limit(mut self, l: u64) -> Self {
102
0
        self.limit = Some(l);
103
0
        self
104
0
    }
105
106
    /// Creates the body data turned into bytes.
107
    ///
108
    /// Will automatically limit the body reader to the lenth of the data.
109
0
    pub fn data(mut self, data: impl Into<Vec<u8>>) -> Body {
110
0
        let data: Vec<u8> = data.into();
111
112
0
        let len = self.limit.unwrap_or(data.len() as u64);
113
0
        self.info.body_mode = BodyMode::LengthDelimited(len);
114
115
0
        self.reader(Cursor::new(data))
116
0
    }
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
0
    pub fn reader(self, data: impl io::Read + Send + Sync + 'static) -> Body {
123
0
        Body {
124
0
            source: BodyDataSource::Reader(Box::new(data)),
125
0
            info: Arc::new(self.info),
126
0
        }
127
0
    }
128
}