notra 0.1.1

Unofficial Rust SDK for the Notra API
Documentation
use serde::{Deserialize, Serialize};

use crate::client::Notra;
use crate::error::Result;
use crate::models::{GithubIntegration, LinearIntegration, Organization};

use super::brand_identities::DisabledItem;

// ── List Integrations ───────────────────────────────────────────────────

#[derive(Debug, Deserialize)]
pub struct ListIntegrationsResponse {
    pub organization: Organization,
    #[serde(default)]
    pub github: Vec<GithubIntegration>,
    #[serde(default)]
    pub slack: Vec<serde_json::Value>,
    #[serde(default)]
    pub linear: Vec<LinearIntegration>,
}

pub struct ListIntegrationsBuilder<'a> {
    client: &'a Notra,
}

impl<'a> ListIntegrationsBuilder<'a> {
    pub(crate) fn new(client: &'a Notra) -> Self {
        Self { client }
    }

    pub async fn send(self) -> Result<ListIntegrationsResponse> {
        self.client.get("/v1/integrations", &[]).await
    }
}

// ── Create GitHub Integration ───────────────────────────────────────────

#[derive(Debug, Deserialize)]
pub struct CreateGithubIntegrationResponse {
    pub organization: Organization,
    pub github: GithubIntegration,
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct CreateGithubIntegrationBody {
    owner: String,
    repo: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    branch: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    auth_token: Option<String>,
}

pub struct CreateGithubIntegrationBuilder<'a> {
    client: &'a Notra,
    owner: String,
    repo: String,
    branch: Option<String>,
    auth_token: Option<String>,
}

impl<'a> CreateGithubIntegrationBuilder<'a> {
    pub(crate) fn new(
        client: &'a Notra,
        owner: impl Into<String>,
        repo: impl Into<String>,
    ) -> Self {
        Self {
            client,
            owner: owner.into(),
            repo: repo.into(),
            branch: None,
            auth_token: None,
        }
    }

    pub fn branch(mut self, branch: impl Into<String>) -> Self {
        self.branch = Some(branch.into());
        self
    }

    pub fn auth_token(mut self, token: impl Into<String>) -> Self {
        self.auth_token = Some(token.into());
        self
    }

    pub async fn send(self) -> Result<CreateGithubIntegrationResponse> {
        let body = CreateGithubIntegrationBody {
            owner: self.owner,
            repo: self.repo,
            branch: self.branch,
            auth_token: self.auth_token,
        };
        self.client.post("/v1/integrations/github", &body).await
    }
}

// ── Delete Integration ──────────────────────────────────────────────────

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DeleteIntegrationResponse {
    pub id: String,
    pub organization: Organization,
    #[serde(default)]
    pub disabled_schedules: Vec<DisabledItem>,
    #[serde(default)]
    pub disabled_events: Vec<DisabledItem>,
}

pub struct DeleteIntegrationBuilder<'a> {
    client: &'a Notra,
    integration_id: String,
}

impl<'a> DeleteIntegrationBuilder<'a> {
    pub(crate) fn new(client: &'a Notra, integration_id: impl Into<String>) -> Self {
        Self {
            client,
            integration_id: integration_id.into(),
        }
    }

    pub async fn send(self) -> Result<DeleteIntegrationResponse> {
        let path = format!("/v1/integrations/{}", self.integration_id);
        self.client.delete(&path).await
    }
}