whmcs/lib.rs
1#![deny(missing_docs)]
2#![deny(missing_debug_implementations)]
3#![cfg_attr(not(test), warn(unused_crate_dependencies))]
4#![cfg_attr(test, deny(warnings))]
5#![warn(clippy::pedantic)]
6#![warn(clippy::cargo)]
7#![warn(clippy::nursery)]
8#![allow(clippy::multiple_crate_versions)]
9
10//! # whmcs
11//!
12//! Async HTTP client for the [WHMCS][whmcs-api] remote API (`includes/api.php`).
13//! It sends `application/x-www-form-urlencoded` bodies, asks WHMCS for JSON
14//! (`responsetype=json`), and maps the envelope `result: success | error` to `Result<T, WhmcsError>`
15//! ([`WhmcsError`]).
16//!
17//! Typical use looks like this:
18//!
19//! - Build a [`WhmcsClient`] (usually with [`WhmcsBuilder`] when the **`builder`** feature is enabled, which is the default).
20//! - Call typed helpers such as [`WhmcsClient::get_clients`], or the generic [`WhmcsClient::request`] for any WHMCS action.
21//! - Use types from [`models`] for request parameters and deserialized responses.
22//!
23//! ## Quick start
24//!
25//! ```no_run
26//! use whmcs::{WhmcsBuilder, WhmcsError};
27//! use whmcs::models::clients::{GetClientParams, GetClientsResponse};
28//!
29//! async fn example() -> Result<(), WhmcsError> {
30//! let client = WhmcsBuilder::new()
31//! .url("https://billing.example.com/includes/api.php")
32//! .api_identifier("your-api-identifier")
33//! .api_secret("your-api-secret")
34//! .timeout(30_u64)
35//! .build()?;
36//!
37//! let list: GetClientsResponse = client
38//! .get_clients(GetClientParams::default().search("user@example.com"))
39//! .await?;
40//!
41//! println!("total matches: {}", list.total_results);
42//! Ok(())
43//! }
44//! ```
45//!
46//! ## Building a client
47//!
48//! With the default **`builder`** feature, use [`WhmcsBuilder`] to set the API URL, credentials,
49//! and optional timeout, then call [`WhmcsBuilder::build`]. Any field you omit on the builder is
50//! filled from environment variables when `build` runs:
51//!
52//! | Builder field | Environment variable |
53//! |---------------|------------------------|
54//! | URL | `WHMCS_URL` |
55//! | Identifier | `WHMCS_API_IDENTIFIER` |
56//! | Secret | `WHMCS_API_SECRET` |
57//! | Timeout (seconds) | `WHMCS_TIMEOUT` (falls back to `30`) |
58//!
59//! If the URL path does not end with `api.php`, the builder normalizes it so requests target
60//! `.../includes/api.php` under your WHMCS base path.
61//!
62//! With **`default-features = false`** (disabling **`builder`**), construct [`WhmcsClient`] with
63//! [`WhmcsClient::new`] and supply URL and secrets yourself.
64//!
65//! ## Requests and responses
66//!
67//! - **Typed helpers** — Methods on [`WhmcsClient`] (implemented in this crate’s `resources`
68//! modules) call [`WhmcsClient::request`] with the correct WHMCS `action` name and serde types.
69//! - **Generic access** — [`WhmcsClient::request`] accepts any `P` that implements `serde::Serialize`
70//! into a JSON **object** (flat key/value pairs), and any success body type `T` that implements
71//! `serde::de::DeserializeOwned` for the payload after the `result` field is handled by [`WhmcsRawResponse`].
72//!
73//! WHMCS often encodes booleans and nested lists in non-standard ways; this crate uses custom
74//! deserializers in [`models`] where needed.
75//!
76//! ## Errors
77//!
78//! See [`WhmcsError`] for request, JSON, and WHMCS-level failures. Configuration problems when
79//! using the builder are reported as [`BuilderError`].
80//!
81//! ## Cargo features
82//!
83//! | Feature | Default | Description |
84//! |---------|---------|-------------|
85//! | **`builder`** | yes | [`WhmcsBuilder`], [`BuilderError`], and `BuilderError` inside [`WhmcsError`]. |
86//!
87//! ## Further reading
88//!
89//! - [WHMCS API index][whmcs-api] — official action names, parameters, and behaviour.
90//!
91//! [whmcs-api]: https://developers.whmcs.com/api/
92
93pub mod models;
94
95#[cfg(feature = "builder")]
96mod builder;
97mod client;
98mod error;
99mod resources;
100#[cfg(test)]
101mod test;
102
103#[cfg(feature = "builder")]
104pub use crate::{builder::WhmcsBuilder, error::BuilderError};
105pub use client::WhmcsClient;
106pub use error::WhmcsError;
107pub use models::{WhmcsRawResponse, WhmcsSorting};