automatons_github/resource/
license.rs

1use std::fmt::{Display, Formatter};
2
3use serde::{Deserialize, Serialize};
4use url::Url;
5
6use crate::name;
7use crate::resource::NodeId;
8
9name!(
10    /// License key
11    ///
12    /// Licenses have a unique key that identifies them.
13    LicenseKey
14);
15
16name!(
17    /// License name
18    ///
19    /// Licenses have a human-readable name.
20    LicenseName
21);
22
23name!(
24    /// SPDX identifier
25    ///
26    /// The Software Package Data Exchange (SDPX) maintains a list of licenses and assigns a unique
27    /// identifier to each license. This identifier is used by many tools and platforms to identify
28    /// licenses and exchange license information.
29    SpdxId
30);
31
32/// Software license
33///
34/// GitHub tries to detect the license of a project automatically. It checks for a license file and
35/// matches that against a known list of licenses, or reads the license fields in the package's
36/// manifest, e.g. in `package.json` or `Cargo.toml`.
37#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)]
38pub struct License {
39    key: LicenseKey,
40    name: LicenseName,
41    spdx_id: SpdxId,
42    url: Url,
43    node_id: NodeId,
44}
45
46impl License {
47    /// Returns the license's key.
48    #[cfg_attr(feature = "tracing", tracing::instrument)]
49    pub fn key(&self) -> &LicenseKey {
50        &self.key
51    }
52
53    /// Returns the license's name.
54    #[cfg_attr(feature = "tracing", tracing::instrument)]
55    pub fn name(&self) -> &LicenseName {
56        &self.name
57    }
58
59    /// Returns the license's SPDX identifier.
60    #[cfg_attr(feature = "tracing", tracing::instrument)]
61    pub fn spdx_id(&self) -> &SpdxId {
62        &self.spdx_id
63    }
64
65    /// Returns the API endpoint to query the license.
66    #[cfg_attr(feature = "tracing", tracing::instrument)]
67    pub fn url(&self) -> &Url {
68        &self.url
69    }
70
71    /// Returns the license's node id.
72    #[cfg_attr(feature = "tracing", tracing::instrument)]
73    pub fn node_id(&self) -> &NodeId {
74        &self.node_id
75    }
76}
77
78impl Display for License {
79    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
80        write!(f, "{}", self.name)
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use url::Url;
87
88    use crate::resource::NodeId;
89
90    use super::{License, LicenseKey, LicenseName, SpdxId};
91
92    #[test]
93    fn trait_deserialize() {
94        let license: License =
95            serde_json::from_str(include_str!("../../tests/fixtures/resource/license.json"))
96                .unwrap();
97
98        assert_eq!("apache-2.0", license.key().get());
99    }
100
101    #[test]
102    fn trait_display() {
103        let license = License {
104            key: LicenseKey::new("apache-2.0"),
105            name: LicenseName::new("Apache License 2.0"),
106            spdx_id: SpdxId::new("Apache-2.0"),
107            url: Url::parse("https://api.github.com/licenses/apache-2.0").unwrap(),
108            node_id: NodeId::new("MDc6TGljZW5zZTI="),
109        };
110
111        assert_eq!("Apache License 2.0", license.to_string());
112    }
113
114    #[test]
115    fn trait_send() {
116        fn assert_send<T: Send>() {}
117        assert_send::<License>();
118    }
119
120    #[test]
121    fn trait_sync() {
122        fn assert_sync<T: Sync>() {}
123        assert_sync::<License>();
124    }
125}