rbytes_consulta_cep/
lib.rs1use std::time::Duration;
3
4pub mod error;
5pub mod models;
6pub mod providers;
7pub mod validacao;
8
9pub use error::CepError;
11pub use models::Endereco;
12pub use providers::{ProviderType, consultar as consultar_provedor};
13pub use validacao::{normalizar_cep, formatar_cep};
14pub use providers::consultar;
15
16pub use providers::{
18 opencep,
19 brasilapi,
20 viacep,
21 apicep
22};
23
24const PROVEDORES_FALLBACK: &[ProviderType] = &[
25 ProviderType::OpenCep,
26 ProviderType::BrasilApi,
27 ProviderType::ViaCep,
28 ProviderType::ApiCep,
29];
30
31pub async fn consultar_com_fallback(
32 cep: &str,
33 timeout: Option<Duration>,
34) -> Result<Endereco, CepError> {
35 let cep_normalizado = validacao::normalizar_cep(cep)?;
36 let timeout = timeout.unwrap_or(Duration::from_secs(3));
37 let mut ultimo_erro = None;
38
39 for &provedor in PROVEDORES_FALLBACK {
40 match tokio::time::timeout(timeout, consultar_provedor(provedor, &cep_normalizado)).await {
41 Ok(Ok(endereco)) => return Ok(endereco),
42 Ok(Err(e)) => {
43 log::warn!("Falha no provedor {}: {}", provedor, e);
44 ultimo_erro = Some(e);
45 },
46 Err(_) => {
47 log::warn!("Timeout no provedor {}", provedor);
48 ultimo_erro = Some(CepError::ProvedorIndisponivel(provedor.to_string()));
49 },
50 }
51 }
52
53 Err(ultimo_erro.unwrap_or(CepError::SemProvedoresDisponiveis))
54}