summaryrefslogtreecommitdiffstats
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..84262d7
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,100 @@
+//! Rust client for the public CEP API at [cep.is](https://cep.is). Official
+//! Correios data (DNE), refreshed every two weeks.
+//!
+//! Quick use — for a script, the free functions are enough:
+//!
+//! ```no_run
+//! let address = cepis::lookup("01001-000")?;
+//! println!("{} {}", address.localidade, address.uf); // São Paulo SP
+//! # Ok::<_, cepis::Error>(())
+//! ```
+//!
+//! In an application — build a [`Client`] once and reuse it:
+//!
+//! ```no_run
+//! use std::time::Duration;
+//!
+//! let client = cepis::Client::builder()
+//! .timeout(Duration::from_secs(5))
+//! .total_timeout(Some(Duration::from_secs(15)))
+//! .build();
+//!
+//! let address = client.lookup("01001000")?;
+//! # Ok::<_, cepis::Error>(())
+//! ```
+//!
+//! Pointing at a local instance (the API repo brings one up with `just up`):
+//!
+//! ```no_run
+//! let client = cepis::Client::builder()
+//! .base_url("http://localhost:8080")
+//! .build();
+//! # let _ = client;
+//! ```
+//!
+//! Errors are one type, split by decision — whether retrying helps or not:
+//!
+//! ```no_run
+//! # let cep_from_form = "01001000";
+//! match cepis::lookup(cep_from_form) {
+//! Ok(address) => println!("{}", address.localidade),
+//! Err(cepis::Error::NotFound { .. }) => {} // ask the user for another CEP
+//! Err(err) if err.is_retriable() => {} // network, server, rate limit
+//! Err(err) => eprintln!("{err}"),
+//! }
+//! ```
+//!
+//! Note on field names: the API surface is English, but the **data fields keep
+//! the API's own Portuguese names** (`logradouro`, `bairro`, `localidade`).
+//! What you read in the JSON is what you access on the value.
+//!
+//! The free functions share one default client, built on first use. It keeps no
+//! state between calls and is safe to share across threads. Anyone needing
+//! different settings should build their own [`Client`].
+
+#![forbid(unsafe_code)]
+#![warn(missing_docs)]
+
+mod client;
+mod csv;
+mod error;
+mod model;
+mod retry;
+
+pub use crate::client::{
+ Client, ClientBuilder, DEFAULT_URL, MAX_BATCH, RETRIABLE_STATUS, normalize_cep,
+};
+pub use crate::error::{Error, Result};
+pub use crate::model::{Address, Geo, Health};
+
+/// The version of this library, as sent in the `User-Agent`.
+pub const VERSION: &str = env!("CARGO_PKG_VERSION");
+
+use std::sync::OnceLock;
+
+fn default_client() -> &'static Client {
+ static DEFAULT: OnceLock<Client> = OnceLock::new();
+ DEFAULT.get_or_init(Client::new)
+}
+
+/// Look up a CEP using the default configuration.
+///
+/// Shorthand for `Client::new().lookup(cep)`; see [`Client::lookup`].
+pub fn lookup(cep: &str) -> Result<Address> {
+ default_client().lookup(cep)
+}
+
+/// Look up many CEPs in one batch, using the default configuration.
+///
+/// Shorthand for [`Client::lookup_many`] — read that one, especially the
+/// warning that batches carry no coordinate.
+pub fn lookup_many(ceps: &[impl AsRef<str>]) -> Result<Vec<Option<Address>>> {
+ default_client().lookup_many(ceps)
+}
+
+/// Query the API's health using the default configuration.
+///
+/// Shorthand for [`Client::health`].
+pub fn health() -> Result<Health> {
+ default_client().health()
+}