Menu
Public repository / a0501370bec01f30f21f48fbebd95284b81aca77
AkurAI-Framework / crates/ui/src/http.rs
Latest change 3aae9f4e85241bcb775c31f5c03094becd3da56a - Pure-Rust UI layer: akurai-ui, akurai-crypto, Tailwind-grade akurai-css by Ólafur Búi Ólafsson
//! `fetch` with JSON helpers. Same-origin, cookies included.
use crate::callbacks;
use crate::host;
use akurai_json::Value;
/// A completed HTTP exchange. `status` is 0 on a network failure.
#[derive(Clone, Debug, PartialEq)]
pub struct Response {
pub status: u16,
pub body: String,
}
impl Response {
pub fn ok(&self) -> bool {
(200..300).contains(&self.status)
}
/// Parse the body as JSON (`Value::Null` when empty or invalid).
pub fn json(&self) -> Value {
akurai_json::parse(&self.body).unwrap_or(Value::Null)
}
/// The `error` field of a JSON error body, or a generic message.
pub fn error_message(&self) -> String {
match self.json().get("error").and_then(Value::as_str) {
Some(msg) => msg.to_string(),
None if self.status == 0 => "Network error — check your connection".to_string(),
None => format!("Request failed ({})", self.status),
}
}
}
/// Send a request; `done` runs when it completes.
pub fn fetch(method: &str, url: &str, body: Option<&str>, done: impl FnOnce(Response) + 'static) {
let mut done = Some(done);
let mut run = crate::dom::in_scope(crate::reactive::current_scope(), move |r: Response| {
if let Some(done) = done.take() {
done(r)
}
});
let id = callbacks::once(move |status, body| run(Response { status, body }));
host::fetch(method, url, body, id);
}
pub fn get(url: &str, done: impl FnOnce(Response) + 'static) {
fetch("GET", url, None, done)
}
/// Send `body` as JSON.
pub fn send_json(method: &str, url: &str, body: &Value, done: impl FnOnce(Response) + 'static) {
fetch(method, url, Some(&body.to_json()), done)
}