use nagisa_types::error::{Error, Result};
pub fn log_wire(dir: &'static str, frame: &str) {
tracing::debug!(target: "nagisa::wire", dir, "{frame}");
}
pub fn base64_encode(data: &[u8]) -> String {
const ALPHABET: &[u8; 64] =
b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let mut out = String::with_capacity(data.len().div_ceil(3) * 4);
for chunk in data.chunks(3) {
let b0 = chunk[0] as u32;
let b1 = *chunk.get(1).unwrap_or(&0) as u32;
let b2 = *chunk.get(2).unwrap_or(&0) as u32;
let n = (b0 << 16) | (b1 << 8) | b2;
out.push(ALPHABET[((n >> 18) & 0x3f) as usize] as char);
out.push(ALPHABET[((n >> 12) & 0x3f) as usize] as char);
if chunk.len() > 1 {
out.push(ALPHABET[((n >> 6) & 0x3f) as usize] as char);
} else {
out.push('=');
}
if chunk.len() > 2 {
out.push(ALPHABET[(n & 0x3f) as usize] as char);
} else {
out.push('=');
}
}
out
}
pub fn http_action_envelope<P>(action: &str, status: u16, body: &str, parse: P) -> Result<serde_json::Value>
where
P: FnOnce(&str) -> Result<Envelope>,
{
if status == 404 {
return Err(Error::Unsupported(action.to_string()));
}
let env = parse(body)?;
if env.status == "ok" && env.retcode == 0 {
Ok(env.data.unwrap_or(serde_json::Value::Null))
} else {
Err(Error::Action {
retcode: env.retcode,
message: env.message.unwrap_or_default(),
kind: env.classify,
})
}
}
pub struct Envelope {
pub status: String,
pub retcode: i64,
pub data: Option<serde_json::Value>,
pub message: Option<String>,
pub classify: nagisa_types::error::ActionErrorKind,
}