1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// License: see LICENSE file at root directory of main branch

//! # An implementation of <https://semver.org>
//!
//! ## Project
//!
//! - Repository: <https://bitbucket.org/haibison/dia-semver>
//! - License: Nice License 2.0.0 _(see LICENSE file at root directory of main branch)_
//! - _This project follows [Semantic Versioning 2.0.0]_
//!
//! ## Features
//!
//! - Supporting [2.0.0 specification](https://semver.org/spec/v2.0.0.html).
//! - Tolerant parser: leading/trailing white spaces are ignored; minor and patch version numbers are optional. This parser is added
//!   by the crate author, and is not described in official specification. See [`Semver`][struct:Semver] for more details.
//! - Handy functions: [`is_stable()`][fn:Semver#is_stable], [`is_early()`][fn:Semver#is_early],
//!   [`parse_pre_release()`][fn:Semver#parse_pre_release], [`new_major()`][fn:Semver#new_major], [`new_minor()`][fn:Semver#new_minor],
//!   [`new_patch()`][fn:Semver#new_patch]...
//!
//! ## Notes
//!
//! Documentation is built with all features. Some of them are optional. If you see components from other crates, you can view source to see
//! what features are required.
//!
//! [Semantic Versioning 2.0.0]: https://semver.org/spec/v2.0.0.html
//! [struct:Semver]: struct.Semver.html
//! [fn:Semver#is_stable]: struct.Semver.html#method.is_stable
//! [fn:Semver#is_early]: struct.Semver.html#method.is_early
//! [fn:Semver#parse_pre_release]: struct.Semver.html#method.parse_pre_release
//! [fn:Semver#new_major]: struct.Semver.html#method.new_major
//! [fn:Semver#new_minor]: struct.Semver.html#method.new_minor
//! [fn:Semver#new_patch]: struct.Semver.html#method.new_patch

#![warn(missing_docs)]
#![no_std]

// ╔═════════════════╗
// ║   IDENTIFIERS   ║
// ╚═════════════════╝

macro_rules! code_name  { () => { "dia-semver" }}
macro_rules! version    { () => { "10.0.0" }}

/// # Crate name
pub const NAME: &str = "Dia-semver";

/// # Crate code name
pub const CODE_NAME: &str = code_name!();

/// # ID of this crate
pub const ID: &str = concat!(
    "af689fae-61017e3f-351f0b5a-2db0c53a-d2536361-c9b37bd2-db807b5d-c46e6e53-",
    "ff22efd1-0f308e5a-8cfbb056-640af5db-7736e6eb-7f67b62a-be63deee-226e148c",
);

/// # Crate version
pub const VERSION: &str = version!();

/// # Crate release date (year/month/day)
pub const RELEASE_DATE: (u16, u8, u8) = (2022, 10, 19);

/// # Tag, which can be used for logging...
pub const TAG: &str = concat!(code_name!(), "::af689fae::", version!());

// ╔════════════════════╗
// ║   IMPLEMENTATION   ║
// ╚════════════════════╝

extern crate alloc;

#[cfg(feature="std")]
extern crate std;

/// # Makes new Error with formatted string, or without one
macro_rules! err {
    () => {
        crate::Error::new(line!(), module_path!(), None)
    };
    ($s: literal) => {
        crate::Error::new(line!(), module_path!(), Some(alloc::borrow::Cow::Borrowed($s)))
    };
    ($static_str: path) => {
        crate::Error::new(line!(), module_path!(), Some(alloc::borrow::Cow::Borrowed($static_str)))
    };
    ($s: literal, $($arg: tt)+) => {
        crate::Error::new(line!(), module_path!(), Some(alloc::borrow::Cow::Owned(alloc::format!($s, $($arg)+))))
    };
}

#[test]
fn test_macro_err() {
    use alloc::borrow::Cow;

    macro_rules! s_test { () => { "test" }}

    fn eq(first: Error, second: Error) -> bool {
        first.line() == second.line() && first.module_path() == second.module_path() && first.msg() == second.msg()
    }

    assert!(eq(err!(), Error::new(line!(), module_path!(), None)));
    assert!(eq(err!("test"), Error::new(line!(), module_path!(), Some(Cow::Borrowed(s_test!())))));
    assert!(eq(err!("{s:?}", s=s_test!()), Error::new(line!(), module_path!(), Some(Cow::Owned(alloc::format!("{:?}", s_test!()))))));
}

mod error;
mod pre_release;
mod range;
mod semver;

pub use self::{
    error::*,
    pre_release::*,
    semver::*,
};

pub use self::{
    range::*,
};

pub mod specification;
pub mod version_info;

/// # Result type used in this crate
pub type Result<T> = core::result::Result<T, Error>;

#[test]
fn test_crate_version() {
    assert_eq!(VERSION, env!("CARGO_PKG_VERSION"));
}