use super::{HttpClient, PaginatedResponse};
use crate::verify::NucleusError;
use serde::Deserialize;
use std::sync::Arc;
#[derive(Debug, Clone, Deserialize)]
pub struct NucleusUser {
pub id: String,
pub email: String,
pub email_verified: bool,
pub username: Option<String>,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub avatar_url: Option<String>,
pub metadata: serde_json::Value,
pub created_at: String,
pub updated_at: String,
}
#[derive(Debug, Default)]
pub struct ListUsersParams {
pub limit: Option<u32>,
pub cursor: Option<String>,
pub email_contains: Option<String>,
}
#[derive(Clone)]
pub struct UsersApi {
http: Arc<HttpClient>,
}
impl UsersApi {
pub(crate) fn new(http: Arc<HttpClient>) -> Self {
Self { http }
}
pub async fn get(&self, user_id: &str) -> Result<NucleusUser, NucleusError> {
self.http.get(&format!("/users/{user_id}")).await
}
pub async fn list(
&self,
params: Option<ListUsersParams>,
) -> Result<PaginatedResponse<NucleusUser>, NucleusError> {
let mut query_parts: Vec<String> = Vec::new();
if let Some(p) = ¶ms {
if let Some(limit) = p.limit {
query_parts.push(format!("limit={limit}"));
}
if let Some(cursor) = &p.cursor {
query_parts.push(format!("cursor={cursor}"));
}
if let Some(email) = &p.email_contains {
query_parts.push(format!("email_contains={email}"));
}
}
let path = if query_parts.is_empty() {
"/users".to_string()
} else {
format!("/users?{}", query_parts.join("&"))
};
self.http.get(&path).await
}
pub async fn delete(&self, user_id: &str) -> Result<(), NucleusError> {
self.http.delete(&format!("/users/{user_id}")).await
}
pub async fn ban(&self, user_id: &str) -> Result<(), NucleusError> {
self.http
.post::<serde_json::Value>(&format!("/users/{user_id}/ban"))
.await?;
Ok(())
}
pub async fn unban(&self, user_id: &str) -> Result<(), NucleusError> {
self.http
.post::<serde_json::Value>(&format!("/users/{user_id}/unban"))
.await?;
Ok(())
}
}