dia-semver 11.0.1

For handling Semantic Versions 2.0.0
Documentation
/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--

Dia-Semver

Copyright (C) 2018-2022  Anonymous

There are several releases over multiple years,
they are listed as ranges, such as: "2018-2022".

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/

//! # An implementation of <https://semver.org>
//!
//! ## Project
//!
//! - Repository: <https://bitbucket.org/de-marco/dia-semver>
//! - License: GNU Lesser General Public License, either version 3, or (at your option) any later version.
//! - _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    { () => { "11.0.1" }}

/// # 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, 11, 28);

/// # 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"));
}