Skip to main content

hyperi_rustlib/
lib.rs

1// Project:   hyperi-rustlib
2// File:      src/lib.rs
3// Purpose:   Main library entry point and public API exports
4// Language:  Rust
5//
6// License:   FSL-1.1-ALv2
7// Copyright: (c) 2026 HYPERI PTY LIMITED
8
9//! # hyperi-rustlib
10//!
11//! Shared utility library for HyperI Rust applications.
12//!
13//! Provides configuration management, structured logging, Prometheus metrics,
14//! and environment detection - matching the functionality of hyperi-pylib (Python)
15//! and hyperi-golib (Go).
16//!
17//! ## Quick Start
18//!
19//! ```rust,no_run
20//! use hyperi_rustlib::{env, config, logger, metrics};
21//!
22//! fn main() -> Result<(), Box<dyn std::error::Error>> {
23//!     // Detect runtime environment
24//!     let environment = env::Environment::detect();
25//!     println!("Running in: {:?}", environment);
26//!
27//!     // Initialise logger (respects LOG_LEVEL env var)
28//!     logger::setup_default()?;
29//!
30//!     // Load configuration with 7-layer cascade
31//!     config::setup(config::ConfigOptions {
32//!         env_prefix: "MYAPP".into(),
33//!         ..Default::default()
34//!     })?;
35//!
36//!     // Access config
37//!     let cfg = config::get();
38//!     let db_host = cfg.get_string("database.host").unwrap_or_default();
39//!
40//!     // Create metrics
41//!     let metrics_mgr = metrics::MetricsManager::new("myapp");
42//!     let _counter = metrics_mgr.counter("requests_total", "Total requests processed");
43//!
44//!     tracing::info!(db_host = %db_host, "Application started");
45//!     Ok(())
46//! }
47//! ```
48//!
49//! See [`docs/CORE-PILLARS.md`] for the auto-wiring architecture.
50
51#![deny(unsafe_code)]
52#![warn(clippy::pedantic)]
53#![allow(clippy::module_name_repetitions)]
54#![allow(clippy::doc_markdown)] // Allow brand names without backticks
55#![allow(clippy::cast_precision_loss)] // Metrics values are fine with f64 precision
56#![allow(clippy::missing_panics_doc)] // MVP does not require exhaustive docs
57#![allow(clippy::missing_errors_doc)] // MVP does not require exhaustive docs
58#![allow(clippy::double_must_use)] // Return types already marked must_use
59#![allow(clippy::unused_async)] // Async for future compatibility
60#![allow(clippy::redundant_closure_for_method_calls)] // Clearer with explicit closure
61#![allow(clippy::result_large_err)] // figment::Error is large by design
62#![allow(clippy::needless_pass_by_value)]
63// API cleaner with owned values
64// Test code allowances - unwrap is acceptable in tests for cleaner assertions
65#![cfg_attr(test, allow(clippy::unwrap_used))]
66#![cfg_attr(test, allow(clippy::field_reassign_with_default))]
67
68// Core modules (always available)
69pub mod env;
70pub mod kafka_config;
71pub mod sensitive;
72
73#[cfg(feature = "runtime")]
74pub mod runtime;
75
76#[cfg(feature = "shutdown")]
77pub mod shutdown;
78
79#[cfg(feature = "health")]
80pub mod health;
81
82#[cfg(feature = "config")]
83pub mod config;
84
85#[cfg(feature = "logger")]
86pub mod logger;
87
88#[cfg(any(feature = "metrics", feature = "otel-metrics"))]
89pub mod metrics;
90
91#[cfg(feature = "transport")]
92pub mod transport;
93
94#[cfg(feature = "http")]
95pub mod http_client;
96
97#[cfg(feature = "http-server")]
98pub mod http_server;
99
100#[cfg(feature = "database")]
101pub mod database;
102
103#[cfg(feature = "cache")]
104pub mod cache;
105
106#[cfg(feature = "spool")]
107pub mod spool;
108
109#[cfg(feature = "tiered-sink")]
110pub mod tiered_sink;
111
112#[cfg(feature = "secrets")]
113pub mod secrets;
114
115#[cfg(feature = "directory-config")]
116pub mod directory_config;
117
118#[cfg(feature = "memory")]
119pub mod memory;
120
121#[cfg(feature = "scaling")]
122pub mod scaling;
123
124#[cfg(feature = "worker")]
125pub mod worker;
126
127#[cfg(feature = "cli")]
128pub mod cli;
129
130#[cfg(feature = "top")]
131pub mod top;
132
133#[cfg(feature = "io")]
134pub mod io;
135
136#[cfg(feature = "dlq")]
137pub mod dlq;
138
139#[cfg(feature = "output-file")]
140pub mod output;
141
142#[cfg(feature = "expression")]
143pub mod expression;
144
145#[cfg(feature = "deployment")]
146pub mod deployment;
147
148#[cfg(feature = "version-check")]
149pub mod version_check;
150
151// Re-export common types at crate root
152pub use env::Environment;
153pub use kafka_config::{
154    DfeSource, KafkaConfigError, KafkaConfigResult, ServiceRole, TOPIC_SUFFIX_LAND,
155    TOPIC_SUFFIX_LOAD, config_from_file, config_from_properties_str,
156};
157pub use sensitive::SensitiveString;
158
159#[cfg(feature = "runtime")]
160pub use runtime::RuntimePaths;
161
162#[cfg(feature = "health")]
163pub use health::{HealthRegistry, HealthStatus};
164
165#[cfg(feature = "config")]
166pub use config::{Config, ConfigError, ConfigOptions};
167
168#[cfg(feature = "config")]
169pub use config::flat_env::{ApplyFlatEnv, EnvVarDoc, Normalize};
170
171#[cfg(feature = "config-reload")]
172pub use config::reloader::{ConfigReloader, ReloaderConfig};
173
174#[cfg(feature = "config-reload")]
175pub use config::shared::SharedConfig;
176
177#[cfg(feature = "config-postgres")]
178pub use config::postgres::{
179    FallbackMode, PostgresConfig, PostgresConfigError, PostgresConfigSource,
180};
181
182#[cfg(feature = "logger")]
183pub use logger::{
184    LogFormat, LoggerError, LoggerOptions, SecurityEvent, SecurityOutcome, ThrottleConfig,
185};
186
187#[cfg(any(feature = "metrics", feature = "otel-metrics"))]
188pub use metrics::{DfeMetrics, MetricsConfig, MetricsError, MetricsManager};
189
190#[cfg(feature = "otel-metrics")]
191pub use metrics::{OtelMetricsConfig, OtelProtocol};
192
193#[cfg(feature = "transport")]
194pub use transport::{
195    CommitToken, Message, PayloadFormat, SendResult, Transport, TransportConfig, TransportError,
196    TransportResult, TransportType,
197};
198
199#[cfg(feature = "http-server")]
200pub use http_server::{HttpServer, HttpServerConfig, HttpServerError};
201
202#[cfg(feature = "spool")]
203pub use spool::{Spool, SpoolConfig, SpoolError};
204
205#[cfg(feature = "tiered-sink")]
206pub use tiered_sink::{
207    CircuitBreaker, CircuitState, CompressionCodec, DrainStrategy, OrderingMode, Sink, SinkError,
208    TieredSink, TieredSinkConfig, TieredSinkError,
209};
210
211#[cfg(feature = "secrets")]
212pub use secrets::{
213    CacheConfig, FileProvider, RotationEvent, SecretMetadata, SecretProvider, SecretSource,
214    SecretValue, SecretsConfig, SecretsError, SecretsManager, SecretsResult,
215};
216
217#[cfg(feature = "secrets-vault")]
218pub use secrets::{OpenBaoAuth, OpenBaoConfig, OpenBaoProvider};
219
220#[cfg(feature = "secrets-aws")]
221pub use secrets::{AwsConfig, AwsProvider};
222
223#[cfg(feature = "directory-config")]
224pub use directory_config::{
225    ChangeEvent, ChangeOperation, DirectoryConfigError, DirectoryConfigResult,
226    DirectoryConfigStore, DirectoryConfigStoreConfig, WriteMode, WriteResult,
227};
228
229#[cfg(feature = "memory")]
230pub use memory::{MemoryGuard, MemoryGuardConfig, MemoryPressure, detect_memory_limit};
231
232#[cfg(feature = "scaling")]
233pub use scaling::{
234    ComponentSnapshot, GateType, PressureSnapshot, RateWindow, ScalingComponent, ScalingPressure,
235    ScalingPressureConfig,
236};
237
238#[cfg(feature = "worker")]
239pub use worker::{
240    AdaptiveWorkerPool, BatchPipeline, BatchProcessor, PipelineStats, PipelineStatsSnapshot,
241    ScalingDecision, ScalingInput, WorkerPoolConfig,
242};
243
244#[cfg(feature = "cli")]
245pub use cli::{CliError, CommonArgs, DfeApp, StandardCommand, VersionInfo};
246
247#[cfg(feature = "io")]
248pub use io::{FileWriterConfig, NdjsonWriter, RotationPeriod};
249
250#[cfg(feature = "dlq")]
251pub use dlq::{
252    Dlq, DlqBackend, DlqConfig, DlqEntry, DlqError, DlqMode, DlqSource, FileDlq, FileDlqConfig,
253};
254
255#[cfg(feature = "dlq-kafka")]
256pub use dlq::{DlqRouting, KafkaDlq, KafkaDlqConfig};
257
258#[cfg(feature = "dlq-http")]
259pub use dlq::{HttpDlq, HttpDlqConfig};
260
261#[cfg(feature = "dlq-redis")]
262pub use dlq::{RedisDlq, RedisDlqConfig};
263
264#[cfg(feature = "output-file")]
265pub use output::{FileOutput, FileOutputConfig, OutputError};
266
267#[cfg(feature = "expression")]
268pub use expression::{
269    ALLOWED_FUNCTIONS, DISALLOWED_FUNCTIONS, ExpressionError, ExpressionResult, build_context,
270    compile, evaluate, evaluate_condition, validate,
271};
272
273#[cfg(feature = "deployment")]
274pub use deployment::{
275    ContractMismatch, DeploymentContract, DeploymentError, HealthContract, KedaConfig, KedaContract,
276};
277
278#[cfg(feature = "version-check")]
279pub use version_check::{VersionCheck, VersionCheckConfig, VersionCheckResponse};
280
281/// Library version
282pub const VERSION: &str = env!("CARGO_PKG_VERSION");
283
284/// Initialise all library components with default settings.
285///
286/// This is a convenience function that:
287/// 1. Detects the runtime environment
288/// 2. Sets up the logger with auto-detection
289/// 3. Loads configuration with the given env prefix
290///
291/// # Errors
292///
293/// Returns an error if logger or config initialisation fails.
294#[cfg(all(feature = "config", feature = "logger"))]
295pub fn init(env_prefix: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
296    logger::setup_default()?;
297    config::setup(config::ConfigOptions {
298        env_prefix: env_prefix.to_string(),
299        ..Default::default()
300    })?;
301    Ok(())
302}