Skip to main content

asimov_cloud/
account.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::error::AccountBalanceError;
4use asimov_credit::Credits;
5use core::{error::Error, str::FromStr};
6use derive_more::Display;
7
8pub use asimov_id::{Id, IdError};
9
10#[derive(Clone, Debug, Display, Eq, Hash, Ord, PartialEq, PartialOrd)]
11#[display("@{}", self.0)]
12pub struct Account(pub(crate) Id);
13
14impl FromStr for Account {
15    type Err = IdError;
16
17    fn from_str(input: &str) -> Result<Self, Self::Err> {
18        Ok(Self(input.parse()?))
19    }
20}
21
22impl Account {
23    pub async fn open(id: Id) -> Result<Self, Box<dyn Error>> {
24        Ok(Self(id))
25    }
26
27    pub async fn has_credits(&self) -> Result<bool, AccountBalanceError> {
28        Ok(self.balance().await? > Credits::ZERO)
29    }
30
31    pub async fn balance(&self) -> Result<Credits, AccountBalanceError> {
32        let client = reqwest::Client::builder().user_agent("ASIMOV.rs").build()?;
33
34        let url = format!("https://asimov.credit/{}/balance.txt", self.0);
35        let response = client.get(url).send().await?;
36
37        if response.status() != reqwest::StatusCode::OK {
38            return Err(AccountBalanceError::UnexpectedResponse(response.status()));
39        }
40
41        let response_text = response.text().await?;
42
43        Ok(response_text.parse::<Credits>()?)
44    }
45}