cld/
lib.rs

1/*
2==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--
3
4CLD
5
6Copyright (C) 2019-2023  Anonymous
7
8There are several releases over multiple years,
9they are listed as ranges, such as: "2019-2023".
10
11This program is free software: you can redistribute it and/or modify
12it under the terms of the GNU Lesser General Public License as published by
13the Free Software Foundation, either version 3 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU Lesser General Public License for more details.
20
21You should have received a copy of the GNU Lesser General Public License
22along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
24::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
25*/
26
27//! # Command line duration
28//!
29//! ## Project
30//!
31//! - License: GNU Lesser General Public License, either version 3, or (at your option) any later version.
32//! - _This project follows [Semantic Versioning 2.0.0]_
33//!
34//! ## Features
35//!
36//! This project helps parse [`Duration`][core::time/Duration] from command line arguments.
37//!
38//! ## Notes
39//!
40//! Documentation is built with all features. Some of them are optional. If you see components from other crates, you can view source to see
41//! what features are required.
42//!
43//! [Semantic Versioning 2.0.0]: https://semver.org/spec/v2.0.0.html
44//! [core::time/Duration]: https://doc.rust-lang.org/core/time/struct.Duration.html
45
46#![warn(missing_docs)]
47#![no_std]
48#![forbid(unsafe_code)]
49
50// ╔═════════════════╗
51// ║   IDENTIFIERS   ║
52// ╚═════════════════╝
53
54macro_rules! code_name  { () => { "cld" }}
55macro_rules! version    { () => { "0.5.1" }}
56
57/// # Crate name
58pub const NAME: &str = "CLD";
59
60/// # Crate code name
61pub const CODE_NAME: &str = code_name!();
62
63/// # ID of this crate
64pub const ID: &str = concat!(
65    "2cf37bc5-bfd0f66b-7cbf8382-4eb3e3cb-d2a9e255-ef4858eb-07c2ffe7-0e0b66a7-",
66    "b29673a3-386a6335-9bf7dc3b-faad33d9-76db4b61-57f6a606-da001cbb-8ba95a71",
67);
68
69/// # Crate version
70pub const VERSION: &str = version!();
71
72/// # Crate release date (year/month/day)
73pub const RELEASE_DATE: (u16, u8, u8) = (2023, 2, 22);
74
75/// # Tag, which can be used for logging...
76pub const TAG: &str = concat!(code_name!(), "::2cf37bc5::", version!());
77
78// ╔════════════════════╗
79// ║   IMPLEMENTATION   ║
80// ╚════════════════════╝
81
82#[macro_use]
83extern crate alloc;
84
85#[cfg(feature="std")]
86extern crate std;
87
88/// # Makes new Error...
89macro_rules! err {
90    () => {
91        $crate::Error::new(line!(), module_path!(), None)
92    };
93    ($s: literal) => {
94        $crate::Error::new(line!(), module_path!(), Some(alloc::borrow::Cow::Borrowed($s)))
95    };
96    ($s: literal, $($arg: tt)+) => {
97        $crate::Error::new(line!(), module_path!(), Some(alloc::borrow::Cow::Owned(alloc::format!($s, $($arg)+))))
98    };
99    ($expr: expr, $err: expr) => {
100        $expr.ok_or_else(|| $err)
101    };
102}
103
104/// # Makes new Error...
105#[allow(unused_macros)]
106macro_rules! err_from {
107    ($($s: tt)+) => {
108        $crate::Error::new(line!(), module_path!(), Some(alloc::borrow::Cow::Borrowed(concat!($($s)+))))
109    };
110}
111
112/// # Maps Error...
113macro_rules! map_err {
114    ($e: expr) => {
115        $e.map_err(|e| err!("{}", e))
116    };
117    ($expr: expr, $err: expr) => {
118        $expr.map_err(|_| $err)
119    };
120}
121
122#[test]
123fn test_macro_err() {
124    use alloc::borrow::Cow;
125
126    macro_rules! s_test { () => { "test" }}
127
128    fn eq(first: Error, second: Error) -> bool {
129        first.line() == second.line() && first.module_path() == second.module_path() && first.msg() == second.msg()
130    }
131
132    assert!(eq(err!(), Error::new(line!(), module_path!(), None)));
133    assert!(eq(err!("test"), Error::new(line!(), module_path!(), Some(Cow::Borrowed(s_test!())))));
134    assert!(eq(err!("{s:?}", s=s_test!()), Error::new(line!(), module_path!(), Some(Cow::Owned(alloc::format!("{:?}", s_test!()))))));
135
136    assert!(eq(err_from!(s_test!(), s_test!()), Error::new(line!(), module_path!(), Some(Cow::Borrowed(concat!(s_test!(), s_test!()))))));
137    assert!(eq(err_from!("test"), map_err!(core::result::Result::<(), _>::Err(s_test!())).unwrap_err()));
138    assert!(eq(err_from!("test", "test"), Error::new(line!(), module_path!(), Some(Cow::Owned(s_test!().repeat(2))))));
139}
140
141pub mod version_info;
142
143mod cld;
144mod error;
145
146pub use self::{
147    cld::*,
148    error::*,
149};
150
151/// # Result type used in this crate
152pub type Result<T> = core::result::Result<T, Error>;
153
154#[test]
155fn test_crate_version() {
156    assert_eq!(VERSION, env!("CARGO_PKG_VERSION"));
157}