• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polyphony-chat / polyproto-rs / #8

23 Feb 2025 10:48AM UTC coverage: 68.198% (-8.2%) from 76.367%
#8

push

bitfl0wer
Use LLVM and no-dead-code as recommended by tarpaulin for linux

980 of 1437 relevant lines covered (68.2%)

30.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

38.1
/src/api/mod.rs
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4

5
use serde::Deserialize;
6
use serde_json::from_str;
7
use url::Url;
8

9
use crate::errors::RequestError;
10

11
/// The `core` module contains all API routes for implementing the core polyproto protocol in a client or server.
12
pub mod core;
13

14
#[derive(Debug, Clone)]
15
/// A client for making HTTP requests to a polyproto home server. Stores headers such as the
16
/// authentication token, and the base URL of the server. Both the headers and the URL can be
17
/// modified after the client is created. However, the intended use case is to create one client
18
/// per actor, and use it for all requests made by that actor.
19
///
20
/// # Example
21
///
22
/// ```rs
23
/// let mut header_map = reqwest::header::HeaderMap::new();
24
/// header_map.insert("Authorization", "nx8r902hjkxlo2n8n72x0");
25
/// let client = HttpClient::new("https://example.com").unwrap();
26
/// client.headers(header_map);
27
///
28
/// let challenge: ChallengeString = client.get_challenge_string().await.unwrap();
29
/// ```
30
pub struct HttpClient {
31
    /// The reqwest client used to make requests.
32
    pub client: reqwest::Client,
33
    headers: reqwest::header::HeaderMap,
34
    version: http::Version, //TODO: Allow setting HTTP version?
35
    pub(crate) url: Url,
36
    zstd_compression: bool,
37
}
38

39
/// A type alias for the result of an HTTP request.
40
pub type HttpResult<T> = Result<T, RequestError>;
41

42
impl HttpClient {
43
    /// Creates a new instance of the client with no further configuration. To access routes which
44
    /// require authentication, you must set the authentication header using the `headers` method.
45
    ///
46
    /// # Arguments
47
    ///
48
    /// * `url` - The base URL of a polyproto home server.
49
    ///
50
    /// # Errors
51
    ///
52
    /// Will fail if the URL is invalid or if there are issues creating the reqwest client.
53
    pub fn new(url: &str) -> HttpResult<Self> {
17✔
54
        let client = reqwest::ClientBuilder::new()
34✔
55
            .zstd(true)
56
            .user_agent(format!("polyproto-rs/{}", env!("CARGO_PKG_VERSION")))
17✔
57
            .build()?;
58
        let headers = reqwest::header::HeaderMap::new();
×
59
        let url = Url::parse(url)?;
17✔
60
        let version = http::Version::HTTP_11;
17✔
61

62
        Ok(Self {
17✔
63
            client,
17✔
64
            headers,
17✔
65
            url,
17✔
66
            version,
17✔
67
            zstd_compression: true,
17✔
68
        })
69
    }
70

71
    /// Creates a new instance of the client with the specified arguments. To access routes which
72
    /// require authentication, you must set an authentication header.
73
    ///
74
    /// # Arguments
75
    ///
76
    /// * `url` - The base URL of a polyproto home server.
77
    /// * `headers`: [reqwest::header::HeaderMap]
78
    /// * `version`: Version of the HTTP spec
79
    /// * `zstd_compression`: Whether to use zstd compression for responses.
80
    ///
81
    /// # Errors
82
    ///
83
    /// Will fail if the URL is invalid or if there are issues creating the reqwest client.
84
    pub fn new_with_args(
×
85
        url: &str,
86
        headers: reqwest::header::HeaderMap,
87
        version: http::Version,
88
        zstd_compression: bool,
89
    ) -> HttpResult<Self> {
90
        let client = reqwest::ClientBuilder::new()
×
91
            .zstd(zstd_compression)
×
92
            .user_agent(format!("polyproto-rs/{}", env!("CARGO_PKG_VERSION")))
×
93
            .build()?;
94
        let url = Url::parse(url)?;
×
95
        Ok(Self {
×
96
            client,
×
97
            headers,
×
98
            version,
×
99
            url,
×
100
            zstd_compression,
×
101
        })
102
    }
103

104
    /// Sets the headers for the client.
105
    pub fn headers(&mut self, headers: reqwest::header::HeaderMap) {
×
106
        self.headers = headers;
×
107
    }
108

109
    /// Returns the URL
110
    pub fn url(&self) -> String {
×
111
        self.url.to_string()
×
112
    }
113

114
    /// Sets the base URL of the client.
115
    pub fn set_url(&mut self, url: &str) -> HttpResult<()> {
×
116
        self.url = Url::parse(url)?;
×
117
        Ok(())
×
118
    }
119

120
    /// Sends a request and returns the response.
121
    pub async fn request<T: Into<reqwest::Body>>(
×
122
        &self,
123
        method: reqwest::Method,
124
        url: &str,
125
        body: Option<T>,
126
    ) -> HttpResult<reqwest::Response> {
127
        Url::parse(url)?;
×
128
        let mut request = self.client.request(method, url);
×
129
        request = request.headers(self.headers.clone());
×
130
        if let Some(body) = body {
×
131
            request = request.body(body);
×
132
        }
133
        Ok(request.send().await?)
×
134
    }
135

136
    /// Sends a request, handles the response, and returns the deserialized object.
137
    pub(crate) async fn handle_response<T: for<'a> Deserialize<'a>>(
17✔
138
        response: Result<reqwest::Response, reqwest::Error>,
139
    ) -> Result<T, RequestError> {
140
        let response = response?;
34✔
141
        let response_text = response.text().await?;
17✔
142
        let object = from_str::<T>(&response_text)?;
34✔
143
        Ok(object)
17✔
144
    }
145
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc