use crate::{anthropic_request_json, ApiResponseOrError, Credentials};
use derive_builder::Builder;
use reqwest::Method;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct Workspace {
pub id: String,
pub name: String,
pub created_at: String,
pub archived_at: Option<String>,
pub display_color: String,
#[serde(rename = "type")]
pub workspace_type: String,
}
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct WorkspaceList {
pub data: Vec<Workspace>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceListBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceListRequest {
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub include_archived: Option<bool>,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub before_id: Option<String>,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub after_id: Option<String>,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceRequest {
pub workspace_id: String,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceCreateBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceCreateRequest {
pub name: String,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceUpdateBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceUpdateRequest {
#[serde(skip_serializing)]
pub workspace_id: String,
pub name: String,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceArchiveBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceArchiveRequest {
pub workspace_id: String,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
impl WorkspaceList {
pub fn builder() -> WorkspaceListBuilder {
WorkspaceListBuilder::create_empty()
}
pub async fn create(request: WorkspaceListRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let mut query_params = Vec::new();
if let Some(include_archived) = request.include_archived {
query_params.push(("include_archived", include_archived.to_string()));
}
if let Some(before_id) = &request.before_id {
query_params.push(("before_id", before_id.clone()));
}
if let Some(after_id) = &request.after_id {
query_params.push(("after_id", after_id.clone()));
}
if let Some(limit) = request.limit {
query_params.push(("limit", limit.to_string()));
}
anthropic_request_json(
Method::GET,
"organizations/workspaces",
|r| r.query(&query_params),
credentials_opt,
)
.await
}
}
impl Workspace {
pub fn builder(workspace_id: impl Into<String>) -> WorkspaceBuilder {
WorkspaceBuilder::create_empty().workspace_id(workspace_id)
}
pub async fn create(request: WorkspaceRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!("organizations/workspaces/{}", request.workspace_id);
anthropic_request_json(Method::GET, &route, |r| r, credentials_opt).await
}
pub fn create_builder() -> WorkspaceCreateBuilder {
WorkspaceCreateBuilder::create_empty()
}
pub async fn create_new(request: WorkspaceCreateRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
anthropic_request_json(
Method::POST,
"organizations/workspaces",
|r| r.json(&request),
credentials_opt,
)
.await
}
pub fn update_builder(workspace_id: impl Into<String>) -> WorkspaceUpdateBuilder {
WorkspaceUpdateBuilder::create_empty().workspace_id(workspace_id)
}
pub async fn update(request: WorkspaceUpdateRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!("organizations/workspaces/{}", request.workspace_id);
anthropic_request_json(Method::POST, &route, |r| r.json(&request), credentials_opt).await
}
pub fn archive_builder(workspace_id: impl Into<String>) -> WorkspaceArchiveBuilder {
WorkspaceArchiveBuilder::create_empty().workspace_id(workspace_id)
}
pub async fn archive(request: WorkspaceArchiveRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!("organizations/workspaces/{}/archive", request.workspace_id);
anthropic_request_json(Method::POST, &route, |r| r, credentials_opt).await
}
}
impl WorkspaceListBuilder {
pub async fn create(self) -> ApiResponseOrError<WorkspaceList> {
let request = self.build().unwrap();
WorkspaceList::create(request).await
}
}
impl WorkspaceBuilder {
pub async fn create(self) -> ApiResponseOrError<Workspace> {
let request = self.build().unwrap();
Workspace::create(request).await
}
}
impl WorkspaceCreateBuilder {
pub async fn create(self) -> ApiResponseOrError<Workspace> {
let request = self.build().unwrap();
Workspace::create_new(request).await
}
}
impl WorkspaceUpdateBuilder {
pub async fn create(self) -> ApiResponseOrError<Workspace> {
let request = self.build().unwrap();
Workspace::update(request).await
}
}
impl WorkspaceArchiveBuilder {
pub async fn create(self) -> ApiResponseOrError<Workspace> {
let request = self.build().unwrap();
Workspace::archive(request).await
}
}
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct WorkspaceMember {
#[serde(rename = "type")]
pub member_type: String,
pub user_id: String,
pub workspace_id: String,
pub workspace_role: WorkspaceMemberRole,
}
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct WorkspaceMemberList {
pub data: Vec<WorkspaceMember>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct WorkspaceMemberDeleted {
#[serde(rename = "type")]
pub member_type: String,
pub user_id: String,
pub workspace_id: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum WorkspaceMemberRole {
WorkspaceUser,
WorkspaceDeveloper,
WorkspaceAdmin,
WorkspaceBilling,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceMemberListBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceMemberListRequest {
pub workspace_id: String,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub before_id: Option<String>,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub after_id: Option<String>,
#[builder(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceMemberBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceMemberRequest {
pub workspace_id: String,
pub user_id: String,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceMemberAddBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceMemberAddRequest {
#[serde(skip_serializing)]
pub workspace_id: String,
pub user_id: String,
pub workspace_role: WorkspaceMemberRole,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceMemberUpdateBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceMemberUpdateRequest {
#[serde(skip_serializing)]
pub workspace_id: String,
#[serde(skip_serializing)]
pub user_id: String,
pub workspace_role: WorkspaceMemberRole,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
#[derive(Serialize, Builder, Debug, Clone)]
#[builder(derive(Clone, Debug, PartialEq))]
#[builder(pattern = "owned")]
#[builder(name = "WorkspaceMemberDeleteBuilder")]
#[builder(setter(strip_option, into))]
pub struct WorkspaceMemberDeleteRequest {
pub workspace_id: String,
pub user_id: String,
#[serde(skip_serializing)]
#[builder(default)]
pub credentials: Option<Credentials>,
}
impl WorkspaceMemberList {
pub fn builder(workspace_id: impl Into<String>) -> WorkspaceMemberListBuilder {
WorkspaceMemberListBuilder::create_empty().workspace_id(workspace_id)
}
pub async fn create(request: WorkspaceMemberListRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!("organizations/workspaces/{}/members", request.workspace_id);
let mut query_params = Vec::new();
if let Some(before_id) = &request.before_id {
query_params.push(("before_id", before_id.clone()));
}
if let Some(after_id) = &request.after_id {
query_params.push(("after_id", after_id.clone()));
}
if let Some(limit) = request.limit {
query_params.push(("limit", limit.to_string()));
}
anthropic_request_json(
Method::GET,
&route,
|r| r.query(&query_params),
credentials_opt,
)
.await
}
}
impl WorkspaceMember {
pub fn builder(
workspace_id: impl Into<String>,
user_id: impl Into<String>,
) -> WorkspaceMemberBuilder {
WorkspaceMemberBuilder::create_empty()
.workspace_id(workspace_id)
.user_id(user_id)
}
pub async fn create(request: WorkspaceMemberRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!(
"organizations/workspaces/{}/members/{}",
request.workspace_id, request.user_id
);
anthropic_request_json(Method::GET, &route, |r| r, credentials_opt).await
}
pub fn add_builder(workspace_id: impl Into<String>) -> WorkspaceMemberAddBuilder {
WorkspaceMemberAddBuilder::create_empty().workspace_id(workspace_id)
}
pub async fn add(request: WorkspaceMemberAddRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!("organizations/workspaces/{}/members", request.workspace_id);
let body = serde_json::json!({
"user_id": request.user_id,
"workspace_role": request.workspace_role,
});
anthropic_request_json(Method::POST, &route, |r| r.json(&body), credentials_opt).await
}
pub fn update_builder(
workspace_id: impl Into<String>,
user_id: impl Into<String>,
) -> WorkspaceMemberUpdateBuilder {
WorkspaceMemberUpdateBuilder::create_empty()
.workspace_id(workspace_id)
.user_id(user_id)
}
pub async fn update(request: WorkspaceMemberUpdateRequest) -> ApiResponseOrError<Self> {
let credentials_opt = request.credentials.clone();
let route = format!(
"organizations/workspaces/{}/members/{}",
request.workspace_id, request.user_id
);
let body = serde_json::json!({
"workspace_role": request.workspace_role,
});
anthropic_request_json(Method::POST, &route, |r| r.json(&body), credentials_opt).await
}
pub fn delete_builder(
workspace_id: impl Into<String>,
user_id: impl Into<String>,
) -> WorkspaceMemberDeleteBuilder {
WorkspaceMemberDeleteBuilder::create_empty()
.workspace_id(workspace_id)
.user_id(user_id)
}
pub async fn delete(
request: WorkspaceMemberDeleteRequest,
) -> ApiResponseOrError<WorkspaceMemberDeleted> {
let credentials_opt = request.credentials.clone();
let route = format!(
"organizations/workspaces/{}/members/{}",
request.workspace_id, request.user_id
);
anthropic_request_json(Method::DELETE, &route, |r| r, credentials_opt).await
}
}
impl WorkspaceMemberListBuilder {
pub async fn create(self) -> ApiResponseOrError<WorkspaceMemberList> {
let request = self.build().unwrap();
WorkspaceMemberList::create(request).await
}
}
impl WorkspaceMemberBuilder {
pub async fn create(self) -> ApiResponseOrError<WorkspaceMember> {
let request = self.build().unwrap();
WorkspaceMember::create(request).await
}
}
impl WorkspaceMemberAddBuilder {
pub async fn create(self) -> ApiResponseOrError<WorkspaceMember> {
let request = self.build().unwrap();
WorkspaceMember::add(request).await
}
}
impl WorkspaceMemberUpdateBuilder {
pub async fn create(self) -> ApiResponseOrError<WorkspaceMember> {
let request = self.build().unwrap();
WorkspaceMember::update(request).await
}
}
impl WorkspaceMemberDeleteBuilder {
pub async fn create(self) -> ApiResponseOrError<WorkspaceMemberDeleted> {
let request = self.build().unwrap();
WorkspaceMember::delete(request).await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Credentials;
#[tokio::test]
#[ignore] async fn test_list_workspaces() {
let credentials = Credentials::from_env();
let workspaces = WorkspaceList::builder()
.credentials(credentials)
.create()
.await
.unwrap();
assert!(workspaces.data.len() > 0);
}
#[tokio::test]
#[ignore] async fn test_get_workspace() {
let credentials = Credentials::from_env();
let workspaces = WorkspaceList::builder()
.credentials(credentials.clone())
.create()
.await
.unwrap();
if let Some(workspace) = workspaces.data.first() {
let workspace_id = &workspace.id;
let workspace_details = Workspace::builder(workspace_id)
.credentials(credentials)
.create()
.await
.unwrap();
assert_eq!(workspace_details.id, *workspace_id);
}
}
#[tokio::test]
#[ignore] async fn test_list_workspace_members() {
let credentials = Credentials::from_env();
let workspaces = crate::admin::workspace::WorkspaceList::builder()
.credentials(credentials.clone())
.create()
.await
.unwrap();
if let Some(workspace) = workspaces.data.first() {
let workspace_id = &workspace.id;
let members = WorkspaceMemberList::builder(workspace_id)
.credentials(credentials)
.create()
.await
.unwrap();
assert!(!members.data.is_empty() || (members.data.is_empty() && !members.has_more));
}
}
#[tokio::test]
#[ignore] async fn test_get_workspace_member() {
let credentials = Credentials::from_env();
let workspaces = crate::admin::workspace::WorkspaceList::builder()
.credentials(credentials.clone())
.create()
.await
.unwrap();
if let Some(workspace) = workspaces.data.first() {
let workspace_id = &workspace.id;
let members = WorkspaceMemberList::builder(workspace_id)
.credentials(credentials.clone())
.create()
.await
.unwrap();
if let Some(member) = members.data.first() {
let user_id = &member.user_id;
let member_details = WorkspaceMember::builder(workspace_id, user_id)
.credentials(credentials)
.create()
.await
.unwrap();
assert_eq!(member_details.user_id, *user_id);
assert_eq!(member_details.workspace_id, *workspace_id);
}
}
}
}