[go: up one dir, main page]

license/
lib.rs

1//! **Embedded license information from [SPDX](https://spdx.org).**
2//!
3//! Use the licenses directly.
4//!
5//! ```
6//! use license::License;
7//! use license::licenses::Bsd3Clause;
8//!
9//! let bsd3 = Bsd3Clause;
10//! assert!(bsd3.is_osi_approved());
11//! assert_eq!(bsd3.name(), r#"BSD 3-Clause "New" or "Revised" License"#);
12//! ```
13//!
14//! Get the license by parsing the license id.
15//!
16//! ```
17//! use license::License;
18//!
19//! let apache2: &dyn License = "Apache-2.0".parse().unwrap();
20//! assert_eq!(apache2.name(), "Apache License 2.0");
21//! ```
22//!
23//! License exceptions are also supported.
24//!
25//! ```
26//! use license::Exception;
27//!
28//! let gcc: &dyn Exception = "GCC-exception-3.1".parse().unwrap();
29//! assert_eq!(gcc.name(), "GCC Runtime Library exception 3.1");
30//! ```
31//!
32//! [Serde](https://crates.io/crates/serde) is supported with the `serde` feature.
33
34#![no_std]
35#![doc(html_root_url = "https://docs.rs/license")]
36#![deny(missing_docs, unsafe_code)]
37
38#[cfg(feature = "serde")]
39mod serde;
40
41use core::error::Error;
42use core::fmt::{self, Debug, Display, Formatter};
43use core::str::FromStr;
44
45/// All supported licenses.
46pub mod licenses {
47    include!(concat!(env!("OUT_DIR"), "/licenses.rs"));
48}
49
50/// All supported exceptions.
51pub mod exceptions {
52    include!(concat!(env!("OUT_DIR"), "/exceptions.rs"));
53}
54
55/// Base functionality for all licenses.
56pub trait License {
57    /// The identifier of the license.
58    ///
59    /// Corresponds to the *Identifier* column from [spdx.org/licenses](https://spdx.org/licenses/).
60    fn id(&self) -> &'static str;
61
62    /// The name of the license.
63    ///
64    /// Corresponds to the *Full name* column from [spdx.org/licenses](https://spdx.org/licenses/).
65    fn name(&self) -> &'static str;
66
67    /// The license text.
68    fn text(&self) -> &'static str;
69
70    /// The standard license header.
71    fn header(&self) -> Option<&'static str>;
72
73    /// Says if the license is OSI approved.
74    ///
75    /// Corresponds to the *OSI Approved?* column from [spdx.org/licenses](https://spdx.org/licenses/).
76    fn is_osi_approved(&self) -> bool;
77
78    /// Says if the license is FSF Libre.
79    ///
80    /// Corresponds to the *FSF Free/Libre?* column from [spdx.org/licenses](https://spdx.org/licenses/).
81    fn is_fsf_libre(&self) -> bool;
82
83    /// Says if the license is deprecated.
84    fn is_deprecated(&self) -> bool;
85
86    /// The license comments.
87    fn comments(&self) -> Option<&'static str>;
88
89    /// Relevant sources.
90    fn see_also(&self) -> &'static [&'static str];
91}
92
93/// Base functionality for all license exceptions.
94pub trait Exception {
95    /// The identifier of the exceptions.
96    fn id(&self) -> &'static str;
97
98    /// The name of the exception.
99    fn name(&self) -> &'static str;
100
101    /// The exception text.
102    fn text(&self) -> &'static str;
103
104    /// Says if the exception is deprecated.
105    fn is_deprecated(&self) -> bool;
106
107    /// The exception comments.
108    fn comments(&self) -> Option<&'static str>;
109
110    /// Relevant sources.
111    fn see_also(&self) -> &'static [&'static str];
112}
113
114impl Display for dyn License {
115    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
116        Display::fmt(self.name(), f)
117    }
118}
119
120impl Display for dyn Exception {
121    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
122        Display::fmt(self.name(), f)
123    }
124}
125
126impl Debug for dyn License {
127    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
128        Debug::fmt(self.id(), f)
129    }
130}
131
132impl Debug for dyn Exception {
133    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
134        Debug::fmt(self.id(), f)
135    }
136}
137
138impl FromStr for &dyn License {
139    type Err = ParseError;
140
141    fn from_str(s: &str) -> Result<Self, Self::Err> {
142        licenses::parse_id(s).ok_or(ParseError(()))
143    }
144}
145
146impl FromStr for &dyn Exception {
147    type Err = ParseError;
148
149    fn from_str(s: &str) -> Result<Self, Self::Err> {
150        exceptions::parse_id(s).ok_or(ParseError(()))
151    }
152}
153
154/// Error returned when parsing license and exception ids.
155#[derive(Clone, Debug, Eq, PartialEq)]
156pub struct ParseError(());
157
158impl Display for ParseError {
159    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
160        Display::fmt("SPDX id not found", f)
161    }
162}
163
164impl Error for ParseError {}