rbytes_consulta_cep 0.1.0

Consulta de CEP brasileiro com multi-provedores (ViaCEP, BrasilAPI, etc). Inclui fallback automático, timeout configurável e formatação de endereços.
Documentation
// src/providers/brasilapi.rs
use crate::{models::Endereco, error::CepError, validacao::normalizar_cep};
use reqwest::{Client, StatusCode};
use serde::Deserialize;
use std::time::Duration;

#[derive(Debug, Deserialize)]
struct BrasilApiResponse {
    cep: String,
    street: String,
    neighborhood: String,
    city: String,
    state: String,
    #[serde(rename = "service")]
    service_name: String,
}

pub async fn consultar(cep: &str) -> Result<Endereco, CepError> {
    let cep_normalizado = normalizar_cep(cep)?;
    let url = format!("https://brasilapi.com.br/api/cep/v1/{}", cep_normalizado);
    
    let response = Client::new()
        .get(&url)
        .timeout(Duration::from_secs(2))
        .send()
        .await
        .map_err(|e| CepError::FalhaRequisicao(e.to_string()))?; // Correção aqui

    match response.status() {
        StatusCode::OK => {
            let brasilapi_response: BrasilApiResponse = response.json()
                .await
                .map_err(|e| CepError::ParseError(e.to_string()))?; // E aqui
            
            Ok(Endereco {
                cep: brasilapi_response.cep,
                logradouro: Some(brasilapi_response.street),
                complemento: None,
                bairro: Some(brasilapi_response.neighborhood),
                localidade: brasilapi_response.city,
                uf: brasilapi_response.state,
                ibge: None,
                gia: None,
                ddd: None,
                siafi: None,
            })
        },
        StatusCode::NOT_FOUND => Err(CepError::CepNaoEncontrado),
        StatusCode::TOO_MANY_REQUESTS => Err(CepError::RateLimitExcedido("BrasilAPI".into())),
        _ => Err(CepError::ProvedorIndisponivel("BrasilAPI".into())),
    }
}