dtt/lib.rs
1#![forbid(unsafe_code)]
2// Copyright © 2025 DateTime (DTT) library. All rights reserved.
3// SPDX-License-Identifier: Apache-2.0 OR MIT
4
5//! `DateTime` (DTT) is a comprehensive library for date and time manipulation.
6//!
7//! # Overview
8//!
9//! This crate provides robust tools for handling dates, times, and timezones in Rust,
10//! with a focus on correctness, ergonomics, and performance.
11//!
12//! # Features
13//!
14//! - Create and parse dates in multiple formats
15//! - Timezone conversions and handling
16//! - Date and time arithmetic
17//! - Formatting and serialization
18//!
19//! # Error Handling
20//!
21//! This crate uses the `thiserror` crate for error handling. All errors are
22//! properly typed and implement standard error traits. Operations that may fail
23//! return `Result<T, AppError>`.
24//!
25//! # Examples
26//!
27//! ```rust
28//! use dtt::DateTime;
29//!
30//! let now = DateTime::new();
31//! println!("Current time: {}", now);
32//! ```
33
34#![doc = include_str!("../README.md")]
35#![doc(
36 html_favicon_url = "https://cloudcdn.pro/dtt/v1/favicon.ico",
37 html_logo_url = "https://cloudcdn.pro/dtt/v1/logos/dtt.svg",
38 html_root_url = "https://docs.rs/dtt"
39)]
40// Rust-level lints live in [lints.rust] in Cargo.toml. Universal clippy
41// allowances live in [lints.clippy]. The strict deny-list below applies
42// to the *library crate only* — integration tests, benches, and examples
43// are separate crates and remain free to use `unwrap`, `expect`, etc.
44#![deny(
45 rustdoc::broken_intra_doc_links,
46 clippy::pedantic,
47 clippy::nursery,
48 clippy::cargo,
49 clippy::unwrap_used,
50 clippy::expect_used,
51 clippy::panic,
52 clippy::result_unit_err,
53 clippy::clone_on_ref_ptr
54)]
55#![cfg_attr(docsrs, feature(doc_cfg))]
56
57// Standard library imports
58use std::env;
59
60/// Library constants and configuration values
61pub mod constants {
62 /// Current version of the library from Cargo.toml
63 pub const VERSION: &str = env!("CARGO_PKG_VERSION");
64
65 /// Environment variable controlling test mode
66 pub const TEST_MODE_ENV: &str = "DTT_TEST_MODE";
67
68 /// Value indicating test mode is enabled
69 pub const TEST_MODE_ENABLED: &str = "1";
70
71 /// Welcome message displayed during initialization
72 pub const WELCOME_MSG: &str = "Welcome to `DTT` 👋!";
73
74 /// Library description displayed during initialization
75 pub const DESCRIPTION: &str = "A Rust library for parsing, validating,manipulating, and formatting dates and times.";
76}
77
78// Re-exports with inline documentation
79#[doc(inline)]
80pub use crate::datetime::DateTime;
81#[doc(inline)]
82pub use crate::error::AppError;
83
84/// Core datetime functionality and operations.
85///
86/// This module contains the primary `DateTime` type and associated functionality
87/// for date and time manipulation.
88pub mod datetime;
89
90/// Error handling types and implementations.
91///
92/// Provides custom error types for handling various error conditions that may
93/// occur during datetime operations.
94pub mod error;
95
96/// Macro definitions for common operations.
97///
98/// Contains utility macros to simplify common datetime operations and reduce
99/// boilerplate code.
100pub mod macros;
101
102/// Commonly used types and traits.
103///
104/// Provides a convenient way to import commonly used types with a single use statement.
105pub mod prelude {
106 pub use crate::datetime::{DateTime, DateTimeBuilder};
107 pub use crate::error::{AppError, DateTimeError};
108}
109
110/// Runs the main library functionality with proper error handling.
111///
112/// This function initializes the library and performs basic setup operations.
113/// It checks for test mode and returns appropriate results based on the
114/// environment configuration.
115///
116/// # Errors
117///
118/// Returns `AppError::SimulatedError` in the following cases:
119/// - When the `DTT_TEST_MODE` environment variable is set to "1"
120/// - When environment variable access fails
121///
122/// # Examples
123///
124/// ```rust
125/// use dtt::prelude::*;
126///
127/// fn main() -> Result<(), AppError> {
128/// match dtt::run() {
129/// Ok(()) => println!("Library initialized successfully"),
130/// Err(e) => eprintln!("Error during initialization: {}", e),
131/// }
132/// Ok(())
133/// }
134/// ```
135pub fn run() -> Result<(), AppError> {
136 if is_test_mode() {
137 return Err(AppError::SimulatedError);
138 }
139
140 display_welcome_message();
141 Ok(())
142}
143
144/// Checks if the library is running in test mode.
145///
146/// Examines the environment variable `DTT_TEST_MODE` to determine if the library
147/// should operate in test mode.
148fn is_test_mode() -> bool {
149 env::var(constants::TEST_MODE_ENV)
150 .is_ok_and(|val| val == constants::TEST_MODE_ENABLED)
151}
152
153/// Displays the welcome message with library information.
154///
155/// Prints a welcome message along with the library description and current version.
156fn display_welcome_message() {
157 println!("{}", constants::WELCOME_MSG);
158 println!("{}", constants::DESCRIPTION);
159 println!("Version: {}", constants::VERSION);
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165
166 mod initialization {
167 use super::*;
168 use serial_test::serial;
169
170 #[test]
171 #[serial]
172 fn test_normal_run() {
173 env::remove_var(constants::TEST_MODE_ENV);
174 assert!(run().is_ok());
175 }
176
177 #[test]
178 #[serial]
179 fn test_simulated_error() {
180 env::set_var(
181 constants::TEST_MODE_ENV,
182 constants::TEST_MODE_ENABLED,
183 );
184 assert!(matches!(run(), Err(AppError::SimulatedError)));
185 env::remove_var(constants::TEST_MODE_ENV);
186 }
187 }
188
189 mod configuration {
190 use super::*;
191 use serial_test::serial;
192
193 #[test]
194 #[allow(clippy::const_is_empty)]
195 fn test_version_constant() {
196 assert!(
197 !constants::VERSION.is_empty(),
198 "Version string should not be empty"
199 );
200 }
201
202 #[test]
203 #[serial]
204 fn test_is_test_mode() {
205 env::remove_var(constants::TEST_MODE_ENV);
206 let first_check = is_test_mode();
207 assert!(
208 !first_check,
209 "Should not be in test mode by default"
210 );
211
212 env::set_var(
213 constants::TEST_MODE_ENV,
214 constants::TEST_MODE_ENABLED,
215 );
216 let second_check = is_test_mode();
217 assert!(
218 second_check,
219 "Should be in test mode after enabling it"
220 );
221 env::remove_var(constants::TEST_MODE_ENV);
222 }
223 }
224}