nifi_rust_client/lib.rs
1//! An idiomatic Rust client for the [Apache NiFi](https://nifi.apache.org) 2.x
2//! REST API.
3//!
4//! This crate provides two usage modes that trade off compile-time determinism
5//! against runtime flexibility:
6//!
7//! ## Static mode (default)
8//!
9//! Compile against exactly one NiFi version via a Cargo feature flag. The API
10//! surface is fully typed, every endpoint is statically resolved, and the
11//! compiler catches any version drift between your code and the server.
12//!
13//! ```no_run
14//! use nifi_rust_client::NifiClientBuilder;
15//!
16//! # async fn example() -> Result<(), nifi_rust_client::NifiError> {
17//! let client = NifiClientBuilder::new("https://nifi.example.com:8443")?.build()?;
18//! client.login("admin", "adminpassword123").await?;
19//!
20//! # #[cfg(not(feature = "dynamic"))]
21//! let about = client.flow().get_about_info().await?;
22//! # #[cfg(not(feature = "dynamic"))]
23//! println!("Connected to NiFi {:?}", about.version);
24//! # Ok(())
25//! # }
26//! ```
27//!
28//! Enable a specific version via Cargo features:
29//!
30//! <!-- LIB_STATIC_FEATURE_EXAMPLE_START -->
31//! ```toml
32//! [dependencies]
33//! nifi-rust-client = { version = "0.12", features = ["nifi-2-9-0"] }
34//! ```
35//! <!-- LIB_STATIC_FEATURE_EXAMPLE_END -->
36//!
37//! ## Dynamic mode (`dynamic` feature)
38//!
39//! Compile all supported versions and detect the NiFi server version at
40//! runtime via `/flow/about`. Use this when your code must talk to multiple
41//! server versions without recompilation.
42//!
43//! ```no_run
44//! # #[cfg(feature = "dynamic")]
45//! # async fn example() -> Result<(), nifi_rust_client::NifiError> {
46//! use nifi_rust_client::NifiClientBuilder;
47//! use nifi_rust_client::dynamic::VersionResolutionStrategy;
48//!
49//! let client = NifiClientBuilder::new("https://nifi.example.com:8443")?
50//! .version_strategy(VersionResolutionStrategy::Closest)
51//! .build_dynamic()?;
52//!
53//! // login() authenticates AND auto-detects the NiFi version.
54//! client.login("admin", "adminpassword123").await?;
55//! # Ok(())
56//! # }
57//! ```
58//!
59//! Enable via:
60//!
61//! <!-- LIB_DYNAMIC_FEATURE_EXAMPLE_START -->
62//! ```toml
63//! [dependencies]
64//! nifi-rust-client = { version = "0.12", features = ["dynamic"] }
65//! ```
66//! <!-- LIB_DYNAMIC_FEATURE_EXAMPLE_END -->
67//!
68//! ## Entry points
69//!
70//! - [`NifiClientBuilder`] — construct a client with timeouts, proxies, TLS
71//! options, credential providers, and retry policy.
72//! - [`NifiClient`] — the client handle itself; resource accessors like
73//! `.flow()`, `.processors()`, etc. return borrowed resource structs.
74//! - [`NifiError`] — `#[non_exhaustive]` error type with typed variants
75//! (`Unauthorized`, `Forbidden`, `NotFound`, `Conflict`,
76//! `UnsupportedEndpoint`, etc.) and helpers like `status_code()` and
77//! `is_retryable()`.
78//! - [`AuthProvider`] and its impls (`PasswordAuth`, `EnvPasswordAuth`,
79//! `StaticTokenAuth`) in the [`config::auth`] module — used with
80//! [`NifiClientBuilder::auth_provider`] to enable auto-refresh on 401.
81//! - [`config::retry::RetryPolicy`] — exponential-backoff retry on transient
82//! errors, configured via [`NifiClientBuilder::retry_policy`].
83//!
84//! ## Running examples
85//!
86//! ```bash
87//! NIFI_URL=https://localhost:8443 \
88//! NIFI_USERNAME=admin NIFI_PASSWORD=adminpassword123 \
89//! cargo run --example basic_static
90//! ```
91//!
92//! All examples accept the same environment variables. See `examples/` in
93//! the repository for the full set.
94//!
95//! ## Feature flags
96//!
97//! | Feature | Purpose |
98//! |---|---|
99//! <!-- NIFI_FEATURE_FLAGS_START -->
100//! | `nifi-2-6-0`, `nifi-2-7-2`, `nifi-2-8-0`, `nifi-2-9-0` | Compile against a specific NiFi version. The semver-latest is the default. |
101//! <!-- NIFI_FEATURE_FLAGS_END -->
102//! | `dynamic` | Compile all versions and enable runtime version detection. Pulls in every version feature. |
103//!
104//! At least one version feature (or `dynamic`) must be enabled — builds with
105//! none fail at both build-script time and compile time.
106
107#![warn(missing_docs)]
108
109// `has_dynamic_or_version` is a rustc-cfg emitted by build.rs whenever it
110// runs successfully with at least one NiFi version feature or the `dynamic`
111// feature enabled. The flag is invisible to users — it isn't a Cargo
112// feature and can't be set externally. If build.rs is ever bypassed
113// entirely (some `cargo doc` / rust-analyzer configurations), the flag is
114// unset and this compile_error! fires with an actionable message. The
115// primary zero-features guard is the runtime check in build.rs itself;
116// this is defence in depth.
117#[cfg(not(has_dynamic_or_version))]
118compile_error!(
119 "nifi-rust-client requires at least one NiFi feature to be \
120 enabled. Enable one of: `nifi-2-6-0`, `nifi-2-7-2`, \
121 `nifi-2-8-0`, `nifi-2-9-0`, or `dynamic`."
122);
123
124/// Client builder: configure timeouts, TLS, credentials, and retry before connecting.
125pub mod builder;
126/// One-shot bulk-control helpers for process groups.
127pub mod bulk;
128/// The connected client handle and resource accessor methods.
129pub mod client;
130/// Server-quirk compatibility shims (e.g. [`FlexibleString`] for date-time
131/// fields that some NiFi versions emit as numbers despite the spec).
132pub mod compat;
133/// Configuration types: credential providers and retry policy.
134pub mod config;
135/// Error type returned by all client operations.
136pub mod error;
137/// Pagination helpers for NiFi REST endpoints that support offset/count paging.
138pub mod pagination;
139mod require;
140/// Streaming byte responses for large binary downloads.
141pub mod streaming;
142/// Polling helpers for state transitions and async queries.
143pub mod wait;
144pub use builder::NifiClientBuilder;
145pub use bytes::Bytes;
146pub use client::NifiClient;
147pub use compat::FlexibleString;
148pub use config::auth::AuthProvider;
149pub use error::NifiError;
150pub use require::RequireField;
151pub use streaming::BytesStream;
152
153// Generated: version modules, re-exports, dynamic module
154include!(concat!(env!("OUT_DIR"), "/generated_lib.rs"));