segment/
http.rs

1//! Low-level HTTP bindings to the Segment tracking API.
2
3use crate::Client;
4use crate::Message;
5use crate::Result;
6use std::time::Duration;
7
8/// A client which synchronously sends single messages to the Segment tracking
9/// API.
10///
11/// `HttpClient` implements [`Client`](../client/trait.Client.html); see the
12/// documentation for `Client` for more on how to send events to Segment.
13#[derive(Clone, Debug)]
14pub struct HttpClient {
15    client: reqwest::Client,
16    host: String,
17}
18
19impl Default for HttpClient {
20    fn default() -> Self {
21        HttpClient {
22            client: reqwest::Client::builder()
23                .connect_timeout(Duration::new(10, 0))
24                .build()
25                .unwrap(),
26            host: "https://api.segment.io".to_owned(),
27        }
28    }
29}
30
31impl HttpClient {
32    /// Construct a new `HttpClient` from a `reqwest::Client` and a Segment API
33    /// scheme and host.
34    ///
35    /// If you don't care to re-use an existing `reqwest::Client`, you can use
36    /// the `Default::default` value, which will send events to
37    /// `https://api.segment.io`.
38    pub fn new(client: reqwest::Client, host: String) -> HttpClient {
39        HttpClient { client, host }
40    }
41}
42
43#[async_trait::async_trait]
44impl Client for HttpClient {
45    async fn send(&self, write_key: String, msg: Message) -> Result<()> {
46        let path = match msg {
47            Message::Identify(_) => "/v1/identify",
48            Message::Track(_) => "/v1/track",
49            Message::Page(_) => "/v1/page",
50            Message::Screen(_) => "/v1/screen",
51            Message::Group(_) => "/v1/group",
52            Message::Alias(_) => "/v1/alias",
53            Message::Batch(_) => "/v1/batch",
54        };
55
56        let _ = self
57            .client
58            .post(format!("{}{}", self.host, path))
59            .basic_auth(write_key, Some(""))
60            .json(&msg)
61            .send()
62            .await?
63            .error_for_status()?;
64
65        Ok(())
66    }
67}