pub mod admin; use crate::error::{AppError, AppResult}; use reqwest::{Client, Response}; use serde::de::DeserializeOwned; use std::time::Duration; /// Thin REST client for the mycelium daemon's HTTP API. /// /// The base URL is set after the sidecar reports ready; clients are cheap /// to clone (the inner `reqwest::Client` keeps a shared connection pool). #[derive(Debug, Clone)] pub struct MyceliumClient { base: String, http: Client, } impl MyceliumClient { pub fn new(base: impl Into) -> Self { let http = Client::builder() .timeout(Duration::from_secs(10)) .build() .expect("reqwest client build"); Self { base: base.into(), http, } } pub fn base_url(&self) -> &str { &self.base } pub(crate) fn url(&self, path: &str) -> String { format!("{}/api/v1{}", self.base, path) } pub(crate) async fn parse(resp: Response) -> AppResult { let status = resp.status(); if status.is_success() { resp.json::().await.map_err(AppError::from) } else { let body = resp.text().await.unwrap_or_default(); Err(AppError::DaemonStatus { status: status.as_u16(), body, }) } } #[allow(dead_code)] // wired in P2 (peers add/remove) pub(crate) async fn check_status(resp: Response) -> AppResult<()> { let status = resp.status(); if status.is_success() { Ok(()) } else { let body = resp.text().await.unwrap_or_default(); Err(AppError::DaemonStatus { status: status.as_u16(), body, }) } } pub(crate) fn http(&self) -> &Client { &self.http } }