Files
memoscli/src/client.rs

131 lines
4.1 KiB
Rust

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<Self> {
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<Memo> {
let url = format!("{}/api/v1/memos", self.base_url);
let visibility_str = visibility.map(|v| v.to_string());
let request = CreateMemoRequest {
content: content.to_string(),
state: "STATE_UNSPECIFIED".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, page_size: Option<i32>, page_token: Option<&str>) -> Result<Vec<Memo>> {
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(ps) = page_size {
request = request.query(&[("pageSize", ps.to_string())]);
}
if let Some(token) = page_token {
request = request.query(&[("pageToken", token)]);
}
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)
}
pub async fn list_memos_with_token(&self, page_size: Option<i32>, page_token: Option<&str>) -> Result<ListMemosResponse> {
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(ps) = page_size {
request = request.query(&[("pageSize", ps.to_string())]);
}
if let Some(token) = page_token {
request = request.query(&[("pageToken", token)]);
}
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)
}
pub async fn list_all_memos(&self) -> Result<Vec<Memo>> {
let mut all_memos = Vec::new();
let mut page_token: Option<String> = None;
let page_size = 100;
loop {
let response = self.list_memos_with_token(Some(page_size), page_token.as_deref()).await?;
let memos = response.memos;
if memos.is_empty() {
break;
}
all_memos.extend(memos);
page_token = response.next_page_token;
if page_token.is_none() || page_token.as_ref().map_or(true, |t| t.is_empty()) {
break;
}
}
Ok(all_memos)
}
}