use crate::models::{CreateMemoRequest, ListMemosResponse, Memo}; use anyhow::Result; use reqwest::Client; #[derive(Clone)] pub struct MemosClient { client: Client, base_url: String, user_token: String, } impl MemosClient { pub fn new(base_url: &str, user_token: &str) -> Result { let base_url = base_url.trim_end_matches('/'); Ok(Self { client: Client::new(), base_url: base_url.to_string(), user_token: user_token.to_string(), }) } pub async fn create_memo(&self, content: &str, visibility: Option<&str>) -> Result { let url = format!("{}/api/v1/memos", self.base_url); let visibility_str = visibility.map(|v| { if v.starts_with("VISIBILITY_") { v.to_string() } else { format!("VISIBILITY_{}", v.to_uppercase()) } }); let request = CreateMemoRequest { content: content.to_string(), visibility: visibility_str, }; let response = self .client .post(&url) .header("Authorization", format!("Bearer {}", self.user_token)) .header("Content-Type", "application/json") .json(&request) .send() .await?; if !response.status().is_success() { let status = response.status(); let error_text = response.text().await.unwrap_or_default(); anyhow::bail!("Failed to create memo: {} - {}", status, error_text); } let mut memo: Memo = response.json().await?; memo.id = Memo::extract_id(&memo.name); Ok(memo) } pub async fn list_memos(&self, limit: Option, offset: Option) -> Result> { let url = format!("{}/api/v1/memos", self.base_url); let mut request = self .client .get(&url) .header("Authorization", format!("Bearer {}", self.user_token)); if let Some(l) = limit { request = request.query(&[("limit", l.to_string())]); } if let Some(o) = offset { request = request.query(&[("offset", o.to_string())]); } let response = request.send().await?; if !response.status().is_success() { let status = response.status(); let error_text = response.text().await.unwrap_or_default(); anyhow::bail!("Failed to list memos: {} - {}", status, error_text); } let result: ListMemosResponse = response.json().await?; Ok(result.memos) } }