#[cfg(feature = "blocking")]
pub mod blocking;
mod client;
mod error;
pub mod models;
pub use client::{Client, ClientBuilder};
pub use error::Error;
pub use models::*;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub(crate) const DEFAULT_BASE_URL: &str = "https://ip-api.io";
pub(crate) const USER_AGENT: &str = concat!("ip-api-io-rust/", env!("CARGO_PKG_VERSION"));
pub const MAX_BATCH_SIZE: usize = 100;
pub(crate) fn check_batch(items: &[&str], name: &str) -> Result<(), Error> {
if items.is_empty() {
return Err(Error::InvalidArgument(format!("{name} must not be empty")));
}
if items.len() > MAX_BATCH_SIZE {
return Err(Error::InvalidArgument(format!(
"{name} must contain at most {MAX_BATCH_SIZE} items"
)));
}
Ok(())
}
pub(crate) fn encode_segment(segment: &str) -> String {
let mut encoded = String::with_capacity(segment.len());
for byte in segment.bytes() {
match byte {
b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => {
encoded.push(byte as char)
}
_ => encoded.push_str(&format!("%{byte:02X}")),
}
}
encoded
}