use std::sync::Arc;
use serde_json::Value;
use crate::core::{Config, Error, HttpClient, Json, RequestOptions, Result, RetryConfig};
#[derive(Clone, Debug)]
pub struct LegacyService {
pub server: String,
}
impl Default for LegacyService {
fn default() -> Self {
Self {
server: "https://gateway.apibrasil.io/api/v2/".to_string(),
}
}
}
impl LegacyService {
pub fn new() -> Self {
Self::default()
}
pub fn with_server(server: impl Into<String>) -> Self {
Self {
server: server.into(),
}
}
pub async fn request(&self, service: &str, dados: &str) -> Result<Json> {
let payload: Value = serde_json::from_str(dados).map_err(|error| {
Error::validation(format!("JSON inválido na requisição legada: {error}"))
.with_source(error)
})?;
let credentials = payload
.get("credentials")
.filter(|value| value.is_object())
.ok_or_else(|| Error::validation("invalid request, missing credentials"))?;
let body = payload
.get("body")
.filter(|value| value.is_object())
.ok_or_else(|| Error::validation("invalid request, missing body"))?
.clone();
let client = Arc::new(HttpClient::new(
Config {
base_url: Some(self.server.clone()),
bearer_token: string_field(credentials, "BearerToken"),
device_token: string_field(credentials, "DeviceToken"),
retry: Some(RetryConfig::none()),
..Default::default()
}
.header("User-Agent", "APIBRASIL/RUST-SDK"),
));
let mut path = service.to_string();
if let Some(action) = payload.get("action").and_then(Value::as_str) {
if !action.is_empty() {
path.push('/');
path.push_str(action);
}
}
match client
.post(&path, Some(body), &RequestOptions::default())
.await
{
Ok(response) => Ok(response),
Err(error) => match (&error.response, error.status) {
(Some(Value::Object(body)), _) => Ok(Value::Object(body.clone())),
(_, Some(_)) => Ok(serde_json::json!({
"error": true,
"message": error.message,
})),
_ => Err(error),
},
}
}
pub async fn whatsapp(&self, dados: &str) -> Result<Json> {
self.request("whatsapp", dados).await
}
pub async fn sms(&self, dados: &str) -> Result<Json> {
self.request("sms", dados).await
}
pub async fn cpf(&self, dados: &str) -> Result<Json> {
self.request("cpf/dados", dados).await
}
pub async fn cnpj(&self, dados: &str) -> Result<Json> {
self.request("dados", dados).await
}
}
fn string_field(source: &Value, key: &str) -> Option<String> {
Some(source.get(key)?.as_str()?.to_string())
}