Skip to content

Commit

Permalink
Add async functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
umgefahren committed Jan 11, 2025
1 parent 962d1f1 commit 617b9a5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "posthog-rs"
license = "MIT"
version = "0.2.6"
version = "0.3.0"
authors = ["christos <christos@openquery.io>"]
description = "An unofficial Rust client for Posthog (https://posthog.com/)."
repository = "https://github.com/openquery-io/posthog-rs"
Expand All @@ -10,7 +10,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
reqwest = { version = "0.11.3", default-features = false, features = ["blocking", "rustls-tls"] }
reqwest = { version = "0.11.3", default-features = false, features = ["rustls-tls"] }
serde = { version = "1.0.125", features = ["derive"] }
chrono = {version = "0.4.19", features = ["serde"] }
serde_json = "1.0.64"
Expand All @@ -21,4 +21,5 @@ dotenv = "0.15.0"
ctor = "0.1.26"

[features]
blocking = ["reqwest/blocking"]
e2e-test = []
50 changes: 44 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

use chrono::NaiveDateTime;
use reqwest::blocking::Client as HttpClient;
#[cfg(feature = "blocking")]
use reqwest::blocking::Client as BlockingHttpClient;
use reqwest::header::CONTENT_TYPE;
use reqwest::Client as AsyncHttpClient;
use semver::Version;
use serde::Serialize;
use std::collections::HashMap;
Expand All @@ -13,13 +17,20 @@ const API_ENDPOINT: &str = "https://us.i.posthog.com/capture/";
const TIMEOUT: &Duration = &Duration::from_millis(800); // This should be specified by the user

pub fn client<C: Into<ClientOptions>>(options: C) -> Client {
let client = HttpClient::builder()
#[cfg(feature = "blocking")]
let blocking_client = BlockingHttpClient::builder()
.timeout(Some(*TIMEOUT))
.build()
.unwrap(); // Unwrap here is as safe as `HttpClient::new`
let async_client = AsyncHttpClient::builder()
.timeout(*TIMEOUT)
.build()
.unwrap(); // Unwrap here is as safe as `HttpClient::new`
Client {
options: options.into(),
client,
#[cfg(feature = "blocking")]
blocking_client,
async_client,
}
}

Expand Down Expand Up @@ -56,14 +67,17 @@ impl From<&str> for ClientOptions {

pub struct Client {
options: ClientOptions,
client: HttpClient,
#[cfg(feature = "blocking")]
blocking_client: BlockingHttpClient,
async_client: AsyncHttpClient,
}

impl Client {
#[cfg(feature = "blocking")]
pub fn capture(&self, event: Event) -> Result<(), Error> {
let inner_event = InnerEvent::new(event, self.options.api_key.clone());
let _res = self
.client
.blocking_client
.post(self.options.api_endpoint.clone())
.header(CONTENT_TYPE, "application/json")
.body(serde_json::to_string(&inner_event).expect("unwrap here is safe"))
Expand All @@ -72,12 +86,36 @@ impl Client {
Ok(())
}

pub fn capture_batch(&self, events: Vec<Event>) -> Result<(), Error> {
pub async fn async_capture(&self, event: Event) -> Result<(), Error> {
let inner_event = InnerEvent::new(event, self.options.api_key.clone());
let _res = self
.async_client
.post(self.options.api_endpoint.clone())
.header(CONTENT_TYPE, "application/json")
.body(serde_json::to_string(&inner_event).expect("unwrap here is safe"))
.send()
.await
.map_err(|e| Error::Connection(e.to_string()))?;
Ok(())
}

#[cfg(feature = "blocking")]
pub fn capture_batch(&self, events: impl Iterator<Item = Event>) -> Result<(), Error> {
for event in events {
self.capture(event)?;
}
Ok(())
}

pub async fn async_capture_batch(
&self,
events: impl Iterator<Item = Event>,
) -> Result<(), Error> {
for event in events {
self.async_capture(event).await?;
}
Ok(())
}
}

// This exists so that the client doesn't have to specify the API key over and over
Expand Down

0 comments on commit 617b9a5

Please sign in to comment.