Skip to main content

rbytes_consulta_cep/
lib.rs

1// src/lib.rs
2use std::time::Duration;
3
4pub mod error;
5pub mod models;
6pub mod providers;
7pub mod validacao;
8
9// Exporte todas as funções públicas
10pub 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
16// Reexportar os provedores específicos que deseja expor
17pub 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}