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 {}