qstash-rs 0.6.0

A Rust SDK for Upstash QStash
Documentation
use bytes::Bytes;
use reqwest::{header::CONTENT_TYPE, Method};
use serde::{Deserialize, Serialize};

use super::Client;
use crate::{error::Result, Error};

/// A URL Group endpoint.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Endpoint {
    /// Optional endpoint name.
    pub name: Option<String>,
    /// Endpoint URL.
    pub url: String,
}

/// A URL Group resource.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UrlGroup {
    /// Creation timestamp in milliseconds.
    pub created_at: u64,
    /// Last update timestamp in milliseconds.
    pub updated_at: u64,
    /// URL Group name.
    pub name: String,
    /// Attached endpoints.
    pub endpoints: Vec<Endpoint>,
}

#[derive(Debug, Serialize)]
struct EndpointsPayload<'a> {
    endpoints: &'a [Endpoint],
}

/// URL Group operations.
pub struct UrlGroupsApi<'a> {
    pub(crate) client: &'a Client,
}

impl UrlGroupsApi<'_> {
    /// Lists URL Groups.
    pub async fn list(&self) -> Result<Vec<UrlGroup>> {
        self.client
            .http
            .send_json(Method::GET, "v2/topics", &[], None, None)
            .await
    }

    /// Retrieves a URL Group by name.
    pub async fn get(&self, name: &str) -> Result<UrlGroup> {
        self.client
            .http
            .send_json(Method::GET, &format!("v2/topics/{name}"), &[], None, None)
            .await
    }

    /// Adds one or more endpoints to a URL Group, creating it when necessary.
    pub async fn upsert_endpoints(&self, name: &str, endpoints: &[Endpoint]) -> Result<()> {
        let body = Bytes::from(
            serde_json::to_vec(&EndpointsPayload { endpoints }).map_err(Error::Serialize)?,
        );
        let mut headers = reqwest::header::HeaderMap::new();
        headers.insert(
            CONTENT_TYPE,
            reqwest::header::HeaderValue::from_static("application/json"),
        );

        self.client
            .http
            .send_empty(
                Method::POST,
                &format!("v2/topics/{name}/endpoints"),
                &[],
                Some(headers),
                Some(body),
            )
            .await
    }

    /// Removes one or more endpoints from a URL Group.
    pub async fn remove_endpoints(&self, name: &str, endpoints: &[Endpoint]) -> Result<()> {
        let body = Bytes::from(
            serde_json::to_vec(&EndpointsPayload { endpoints }).map_err(Error::Serialize)?,
        );
        let mut headers = reqwest::header::HeaderMap::new();
        headers.insert(
            CONTENT_TYPE,
            reqwest::header::HeaderValue::from_static("application/json"),
        );

        self.client
            .http
            .send_empty(
                Method::DELETE,
                &format!("v2/topics/{name}/endpoints"),
                &[],
                Some(headers),
                Some(body),
            )
            .await
    }

    /// Deletes a URL Group.
    pub async fn delete(&self, name: &str) -> Result<()> {
        self.client
            .http
            .send_empty(
                Method::DELETE,
                &format!("v2/topics/{name}"),
                &[],
                None,
                None,
            )
            .await
    }
}