use crate::Error;
use serde::{Deserialize, Serialize, Serializer};
use std::fmt::{Display, Formatter};
use std::str::FromStr;
#[derive(Clone, Debug, Eq, PartialEq, Default, Deserialize)]
#[serde(from = "String")]
#[non_exhaustive]
pub enum License {
#[default]
CcZero10,
CcBy40,
Other(String),
}
impl From<String> for License {
fn from(s: String) -> Self {
match s.as_str() {
"CC0-1.0" => License::CcZero10,
"CC-BY-4.0" => License::CcBy40,
_ => License::Other(s),
}
}
}
impl Serialize for License {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.spdx())
}
}
impl Display for License {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.spdx())
}
}
impl License {
pub fn spdx(&self) -> &str {
match &self {
License::CcBy40 => "CC-BY-4.0",
License::CcZero10 => "CC0-1.0",
License::Other(l) => l,
}
}
}
impl FromStr for License {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"CC0-1.0" => License::CcZero10,
"CC-BY-4.0" => License::CcBy40,
l => License::Other(l.to_string()),
})
}
}
#[cfg(test)]
mod tests {
use crate::advisory::License;
#[test]
fn serialize_licenses() {
assert_eq!(
serde_json::to_string(&License::CcBy40).unwrap(),
"\"CC-BY-4.0\"".to_string()
);
assert_eq!(
serde_json::to_string(&License::Other("MPL-2.0".to_string())).unwrap(),
"\"MPL-2.0\"".to_string()
);
}
#[test]
fn deserialize_licenses() {
let l: License = serde_json::from_str("\"CC-BY-4.0\"").unwrap();
assert_eq!(l, License::CcBy40);
let l: License = serde_json::from_str("\"MPL-2.0\"").unwrap();
assert_eq!(l, License::Other("MPL-2.0".to_string()));
}
}