eyes-subscriber 0.6.0

Tracing subscriber for sending traces to Eyes (eyes.coreyja.com)
Documentation
use async_trait::async_trait;
use reqwest::Client;
use url::Url;
use uuid::Uuid;

use crate::{
    transport::{Transport, TransportError},
    EventData,
};

pub struct HttpTransport {
    client: Client,
    url: Url,
    auth_token: Option<String>,
}

impl HttpTransport {
    pub fn new(
        base_url: Url,
        org_id: Uuid,
        app_id: Uuid,
        auth_token: Option<String>,
    ) -> Result<Self, TransportError> {
        let url = base_url
            .join(&format!("/api/orgs/{}/apps/{}/events", org_id, app_id))
            .map_err(|e| TransportError::Configuration(format!("Invalid URL: {}", e)))?;

        Ok(Self {
            client: Client::new(),
            url,
            auth_token,
        })
    }
}

#[async_trait]
impl Transport for HttpTransport {
    async fn connect(&mut self) -> Result<(), TransportError> {
        Ok(())
    }

    async fn send(&mut self, event: EventData) -> Result<(), TransportError> {
        let mut request = self.client.post(self.url.clone()).json(&event);
        if let Some(token) = &self.auth_token {
            request = request.bearer_auth(token);
        }
        let response = request
            .send()
            .await
            .map_err(|e| TransportError::Send(format!("HTTP request failed: {}", e)))?;

        if !response.status().is_success() {
            return Err(TransportError::Send(format!(
                "Server returned error status: {}",
                response.status()
            )));
        }

        Ok(())
    }

    async fn close(&mut self) -> Result<(), TransportError> {
        Ok(())
    }
}