provident/lib.rs
1// SPDX-License-Identifier: GPL-3.0-only
2
3// Layout (for contributors): endpoints are grouped by feature area, not by URL. Each area is a
4// public field of `Client` backed by `src/<area>/mod.rs`, with one file per operation (e.g.
5// `src/auth/login.rs`) holding an `impl` block for the area. Request/response types live in
6// `models`, whose tree mirrors the portal's URLs; the area module maps the friendly name
7// (`login`) to the wire endpoint (`LoginService.aspx/ProcessLogin`). All areas share one HTTP
8// client, so the session cookie set by `auth.login` authorizes every later call.
9
10// The README is the crate documentation (docs.rs and crates.io show the same text) and its
11// example is compiled as a doctest. It is async-only, so blocking builds get a short summary.
12#![cfg_attr(feature = "async", doc = include_str!("../README.md"))]
13#![cfg_attr(
14 not(feature = "async"),
15 doc = "Unofficial client for the Provident (MeterConnex) utility metering portal (blocking API)."
16)]
17#![warn(missing_docs)]
18
19#[cfg(all(feature = "async", feature = "blocking"))]
20compile_error!(
21 "features `async` and `blocking` are mutually exclusive; use `default-features = false` with `blocking`"
22);
23#[cfg(not(any(feature = "async", feature = "blocking")))]
24compile_error!("enable exactly one of the `async` or `blocking` features");
25
26pub mod account;
27pub mod auth;
28mod error;
29pub mod http;
30pub mod models;
31pub mod usage;
32
33pub use error::{Error, Result};
34pub use http::ClientConfig;
35
36/// Entry point. Cheap to clone; clones share connections and the session.
37#[derive(Debug, Clone)]
38pub struct Client {
39 /// Session check and sign-in (`/login/LoginService.aspx`).
40 pub auth: auth::Auth,
41 /// Data for the signed-in account (`/secure/…`); requires [`auth::Auth::login`].
42 pub account: account::Account,
43 /// Consumption history for meters and groups; requires [`auth::Auth::login`].
44 pub usage: usage::Usage,
45}
46
47impl Client {
48 /// Client for the default base URL ([`http::constants::DEFAULT_BASE_URL`]).
49 pub fn new() -> Result<Self> {
50 Self::with_config(ClientConfig::default())
51 }
52
53 /// Client for a custom [`ClientConfig`] (base URL, timeouts, headers, user agent).
54 pub fn with_config(config: ClientConfig) -> Result<Self> {
55 let http = http::Client::new(config)?;
56 Ok(Self {
57 auth: auth::Auth::new(http.clone()),
58 account: account::Account::new(http.clone()),
59 usage: usage::Usage::new(http),
60 })
61 }
62}