Skip to main content

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}