diff --git a/README.md b/README.md
@@ -59,12 +59,14 @@ Each entry in the list should contain the following fields:
* **`author`:** The name of the author of the picture
* **`author-url` (optional):** A URL to a webpage by/on the picture's author
* **`license`:** The license type of the picture. Should be one of `PD` (public
- domain), `CC0`, `CC-BY-1`, `CC-BY-2`, `CC-BY-3`, `CC-BY-4`, `CC-BY-SA-1`,
- `CC-BY-SA-2`, `CC-BY-SA-3`, `CC-BY-SA-4`, `CC-BY-NC-1`, `CC-BY-NC-2`,
- `CC-BY-NC-3`, `CC-BY-NC-4`, `CC-BY-NC-SA-1`, `CC-BY-NC-SA-2`,
- `CC-BY-NC-SA-3`, `CC-BY-NC-SA-4`, `CC-BY-ND-1`, `CC-BY-ND-2`, `CC-BY-ND-3`,
- `CC-BY-ND-4`, `CC-BY-NC-ND-1`, `CC-BY-NC-ND-2`, `CC-BY-NC-ND-3` or
- `CC-BY-NC-ND-4`
+ domain), `CC0`, `CC-BY-1`, `CC-BY-2`, `CC-BY-2.1`, `CC-BY-2.5`, `CC-BY-3`,
+ `CC-BY-4`, `CC-BY-SA-1`, `CC-BY-SA-2`, `CC-BY-SA-2.1`, `CC-BY-SA-2.5`,
+ `CC-BY-SA-3`, `CC-BY-SA-4`, `CC-BY-NC-1`, `CC-BY-NC-2`, `CC-BY-NC-2.1`,
+ `CC-BY-NC-2.5`, `CC-BY-NC-3`, `CC-BY-NC-4`, `CC-BY-NC-SA-1`, `CC-BY-NC-SA-2`,
+ `CC-BY-NC-SA-2.1`, `CC-BY-NC-SA-2.5`, `CC-BY-NC-SA-3`, `CC-BY-NC-SA-4`,
+ `CC-BY-ND-1`, `CC-BY-ND-2`, `CC-BY-ND-2.1`, `CC-BY-ND-2.5`, `CC-BY-ND-3`,
+ `CC-BY-ND-4`, `CC-BY-NC-ND-1`, `CC-BY-NC-ND-2`, `CC-BY-NC-ND-2.1`,
+ `CC-BY-NC-ND-2.5`, `CC-BY-NC-ND-3` or `CC-BY-NC-ND-4`
For best accessibility, the `alt` field should contain a concise visual
description of the picture in question (including subjects, colors and scenery)
diff --git a/src/gallery_entry.rs b/src/gallery_entry.rs
@@ -9,26 +9,38 @@ const LICENSES: &[&str] = &[
"CC0",
"CC-BY-1",
"CC-BY-2",
+ "CC-BY-2.1",
+ "CC-BY-2.5",
"CC-BY-3",
"CC-BY-4",
"CC-BY-SA-1",
"CC-BY-SA-2",
+ "CC-BY-SA-2.1",
+ "CC-BY-SA-2.5",
"CC-BY-SA-3",
"CC-BY-SA-4",
"CC-BY-NC-1",
"CC-BY-NC-2",
+ "CC-BY-NC-2.1",
+ "CC-BY-NC-2.5",
"CC-BY-NC-3",
"CC-BY-NC-4",
"CC-BY-NC-SA-1",
"CC-BY-NC-SA-2",
+ "CC-BY-NC-SA-2.1",
+ "CC-BY-NC-SA-2.5",
"CC-BY-NC-SA-3",
"CC-BY-NC-SA-4",
"CC-BY-ND-1",
"CC-BY-ND-2",
+ "CC-BY-ND-2.1",
+ "CC-BY-ND-2.5",
"CC-BY-ND-3",
"CC-BY-ND-4",
"CC-BY-NC-ND-1",
"CC-BY-NC-ND-2",
+ "CC-BY-NC-ND-2.1",
+ "CC-BY-NC-ND-2.5",
"CC-BY-NC-ND-3",
"CC-BY-NC-ND-4",
];
@@ -40,286 +52,127 @@ pub struct GalleryEntry {
pub file_name: String,
pub alt: String,
pub caption: Option<String>,
- pub license: Option<LicenseType>,
+ pub license: LicenseType,
pub author: String,
pub author_url: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct LicenseType(CreativeCommons);
+pub enum LicenseType {
+ PublicDomain,
+ Cc(CreativeCommons),
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct CreativeCommons(CcInternal);
+
+#[derive(Debug, Clone, Copy)]
+/// Wrapper for printing the url of a Creative Commons license
+pub struct LicenseUrl(CcInternal);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-enum CreativeCommons {
+enum CcInternal {
/// Creative Commons (without attribution)
Cc0,
/// Creative Commons Attributions (derivatives allowed)
CcBy {
- version: CreativeCommonsVersion,
+ version: CcVersion,
non_commercial: bool,
share_alike: bool,
},
// The ND (non-derivatives) option excludes the SA (share alike) option
/// Creative Commons Attributions Non-Derivatives
CcByNd {
- version: CreativeCommonsVersion,
+ version: CcVersion,
non_commercial: bool,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-enum CreativeCommonsVersion {
+enum CcVersion {
One,
Two,
+ TwoOne,
+ TwoFive,
Three,
Four,
}
-impl LicenseType {
- pub const fn url(&self) -> &'static str {
- match self.0 {
- // CC0
- CreativeCommons::Cc0 => {
- "https://creativecommons.org/publicdomain/zero/1.0/"
- },
- // CC-BY-1
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::One,
- non_commercial: false,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by/1.0/",
- // CC-BY-2
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Two,
- non_commercial: false,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by/2.0/",
- // CC-BY-3
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Three,
- non_commercial: false,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by/3.0/",
- // CC-BY-4
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Four,
- non_commercial: false,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by/4.0/",
- // CC-BY-SA-1
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::One,
- non_commercial: false,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-sa/1.0/",
- // CC-BY-SA-2
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Two,
- non_commercial: false,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-sa/2.0/",
- // CC-BY-SA-3
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Three,
- non_commercial: false,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-sa/3.0/",
- // CC-BY-SA-4
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Four,
- non_commercial: false,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-sa/4.0/",
- // CC-BY-NC-1
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::One,
- non_commercial: true,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by-nc/1.0/",
- // CC-BY-NC-2
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Two,
- non_commercial: true,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by-nc/2.0/",
- // CC-BY-NC-3
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Three,
- non_commercial: true,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by-nc/3.0/",
- // CC-BY-NC-4
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Four,
- non_commercial: true,
- share_alike: false,
- } => "http://creativecommons.org/licenses/by-nc/4.0/",
- // CC-BY-NC-SA-1
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::One,
- non_commercial: true,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-nc-sa/1.0/",
- // CC-BY-NC-SA-2
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Two,
- non_commercial: true,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-nc-sa/2.0/",
- // CC-BY-NC-SA-3
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Three,
- non_commercial: true,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-nc-sa/3.0/",
- // CC-BY-NC-SA-4
- CreativeCommons::CcBy {
- version: CreativeCommonsVersion::Four,
- non_commercial: true,
- share_alike: true,
- } => "http://creativecommons.org/licenses/by-nc-sa/4.0/",
- // CC-BY-ND-1
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::One,
- non_commercial: false,
- } => "http://creativecommons.org/licenses/by-nd/1.0/",
- // CC-BY-ND-2
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::Two,
- non_commercial: false,
- } => "http://creativecommons.org/licenses/by-nd/2.0/",
- // CC-BY-ND-3
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::Three,
- non_commercial: false,
- } => "http://creativecommons.org/licenses/by-nd/3.0/",
- // CC-BY-ND-4
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::Four,
- non_commercial: false,
- } => "http://creativecommons.org/licenses/by-nd/4.0/",
- // CC-BY-NC-ND-1
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::One,
- non_commercial: true,
- } => "http://creativecommons.org/licenses/by-nc-nd/1.0/",
- // CC-BY-NC-ND-2
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::Two,
- non_commercial: true,
- } => "http://creativecommons.org/licenses/by-nc-nd/2.0/",
- // CC-BY-NC-ND-3
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::Three,
- non_commercial: true,
- } => "http://creativecommons.org/licenses/by-nc-nd/3.0/",
- // CC-BY-NC-ND-4
- CreativeCommons::CcByNd {
- version: CreativeCommonsVersion::Four,
- non_commercial: true,
- } => "http://creativecommons.org/licenses/by-nc-nd/4.0/",
- }
+impl CreativeCommons {
+ pub const fn url(&self) -> LicenseUrl {
+ LicenseUrl(self.0)
}
+}
- pub fn parse(s: &str) -> Result<Option<Self>, ()> {
+impl LicenseType {
+ pub fn parse(s: &str) -> Result<Self, ()> {
if !LICENSES.contains(&s) {
return Err(());
}
if s == "PD" {
- return Ok(None);
+ return Ok(Self::PublicDomain);
} else if s == "CC0" {
- return Ok(Some(Self(CreativeCommons::Cc0)));
+ return Ok(Self::Cc(CreativeCommons(CcInternal::Cc0)));
}
assert!(s.len() >= 3,
"if s is in LICENSES it should contain at least 3 chars");
- let version = match &s[s.len() - 1..] {
- "1" => CreativeCommonsVersion::One,
- "2" => CreativeCommonsVersion::Two,
- "3" => CreativeCommonsVersion::Three,
- "4" => CreativeCommonsVersion::Four,
- _ => {
+ let (license, version) = s.rsplit_once('-').ok_or(())?;
+
+ let version = match version {
+ "1" => CcVersion::One,
+ "2" => CcVersion::Two,
+ "2.1" => CcVersion::TwoOne,
+ "2.5" => CcVersion::TwoFive,
+ "3" => CcVersion::Three,
+ "4" => CcVersion::Four,
+ _ => {
unreachable!("if s is in LICENSES we should be able to parse the license version")
},
};
- match &s[..s.len() - 1] {
- "CC-BY-" => {
- Ok(
- Some(
- Self(
- CreativeCommons::CcBy {
- version,
- non_commercial: false,
- share_alike: false,
- }
- )
- )
- )
+ match license {
+ "CC-BY" => {
+ Ok(Self::Cc(CreativeCommons(CcInternal::CcBy {
+ version,
+ non_commercial: false,
+ share_alike: false,
+ })))
},
- "CC-BY-NC-" => {
- Ok(
- Some(
- Self(
- CreativeCommons::CcBy {
- version,
- non_commercial: true,
- share_alike: false,
- }
- )
- )
- )
+ "CC-BY-NC" => {
+ Ok(Self::Cc(CreativeCommons(CcInternal::CcBy {
+ version,
+ non_commercial: true,
+ share_alike: false,
+ })))
},
- "CC-BY-SA-" => {
- Ok(
- Some(
- Self(
- CreativeCommons::CcBy {
- version,
- non_commercial: false,
- share_alike: true,
- }
- )
- )
- )
+ "CC-BY-SA" => {
+ Ok(Self::Cc(CreativeCommons(CcInternal::CcBy {
+ version,
+ non_commercial: false,
+ share_alike: true,
+ })))
},
- "CC-BY-NC-SA-" => {
- Ok(
- Some(
- Self(
- CreativeCommons::CcBy {
- version,
- non_commercial: true,
- share_alike: true,
- }
- )
- )
- )
+ "CC-BY-NC-SA" => {
+ Ok(Self::Cc(CreativeCommons(CcInternal::CcBy {
+ version,
+ non_commercial: true,
+ share_alike: true,
+ })))
},
- "CC-BY-ND-" => {
- Ok(
- Some(
- Self(
- CreativeCommons::CcByNd {
- version,
- non_commercial: false,
- }
- )
- )
- )
+ "CC-BY-ND" => {
+ Ok(Self::Cc(CreativeCommons(CcInternal::CcByNd {
+ version,
+ non_commercial: false,
+ })))
},
- "CC-BY-NC-ND-" => {
- Ok(
- Some(
- Self(
- CreativeCommons::CcByNd {
- version,
- non_commercial: true,
- }
- )
- )
- )
+ "CC-BY-NC-ND" => {
+ Ok(Self::Cc(CreativeCommons(CcInternal::CcByNd {
+ version,
+ non_commercial: true,
+ })))
},
_ => {
unreachable!("if s is in LICENSES we should be able to parse the license-type")
@@ -376,11 +229,11 @@ impl<'de> Deserialize<'de> for GalleryEntry {
}
}
-impl Display for LicenseType {
+impl Display for CreativeCommons {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self.0 {
- CreativeCommons::Cc0 => write!(f, "CC0"),
- CreativeCommons::CcBy { version, non_commercial, share_alike } => {
+ CcInternal::Cc0 => write!(f, "CC0"),
+ CcInternal::CcBy { version, non_commercial, share_alike } => {
write!(f, "CC-BY")?;
if non_commercial {
write!(f, "-NC")?;
@@ -390,7 +243,7 @@ impl Display for LicenseType {
}
write!(f, " {version}")
},
- CreativeCommons::CcByNd { version, non_commercial } => {
+ CcInternal::CcByNd { version, non_commercial } => {
write!(f, "CC-BY")?;
if non_commercial {
write!(f, "-NC")?;
@@ -401,13 +254,81 @@ impl Display for LicenseType {
}
}
-impl Display for CreativeCommonsVersion {
+impl Display for CcVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
- CreativeCommonsVersion::One => write!(f, "1.0"),
- CreativeCommonsVersion::Two => write!(f, "2.0"),
- CreativeCommonsVersion::Three => write!(f, "3.0"),
- CreativeCommonsVersion::Four => write!(f, "4.0"),
+ CcVersion::One => write!(f, "1.0"),
+ CcVersion::Two => write!(f, "2.0"),
+ CcVersion::TwoOne => write!(f, "2.1"),
+ CcVersion::TwoFive => write!(f, "2.5"),
+ CcVersion::Three => write!(f, "3.0"),
+ CcVersion::Four => write!(f, "4.0"),
+ }
+ }
+}
+
+impl Display for LicenseUrl {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+ match self.0 {
+ // CC0
+ CcInternal::Cc0 => {
+ write!(f, "https://creativecommons.org/publicdomain/zero/1.0/")
+ },
+ // CC-BY-x
+ CcInternal::CcBy {
+ version,
+ non_commercial: false,
+ share_alike: false,
+ } => {
+ write!(f, "http://creativecommons.org/licenses/by/{version}/")
+ }
+ // CC-BY-SA-x
+ CcInternal::CcBy {
+ version,
+ non_commercial: false,
+ share_alike: true,
+ } => {
+ write!(
+ f,
+ "http://creativecommons.org/licenses/by-sa/{version}/"
+ )
+ }
+ // CC-BY-NC-x
+ CcInternal::CcBy {
+ version,
+ non_commercial: true,
+ share_alike: false,
+ } => {
+ write!(
+ f,
+ "http://creativecommons.org/licenses/by-nc/{version}/"
+ )
+ }
+ // CC-BY-NC-SA-x
+ CcInternal::CcBy {
+ version,
+ non_commercial: true,
+ share_alike: true,
+ } => {
+ write!(
+ f,
+ "http://creativecommons.org/licenses/by-nc-sa/{version}/"
+ )
+ }
+ // CC-BY-ND-x
+ CcInternal::CcByNd { version, non_commercial: false, } => {
+ write!(
+ f,
+ "http://creativecommons.org/licenses/by-nd/{version}/"
+ )
+ }
+ // CC-BY-NC-ND-x
+ CcInternal::CcByNd { version, non_commercial: true, } => {
+ write!(
+ f,
+ "http://creativecommons.org/licenses/by-nc-nd/{version}/"
+ )
+ }
}
}
}
diff --git a/src/main.rs b/src/main.rs
@@ -10,7 +10,7 @@ use std::{
process::ExitCode,
sync::mpsc,
};
-use gallery_entry::GalleryEntry;
+use gallery_entry::{GalleryEntry, LicenseType};
use threadpool::ThreadPool;
mod gallery_entry;
@@ -370,7 +370,7 @@ fn render_pic_page(pic: &GalleryEntry) -> io::Result<()> {
writeln!(f, "{}", Escaped(&pic.author))?;
}
writeln!(f, "<br>")?;
- if let Some(license) = &pic.license {
+ if let LicenseType::Cc(license) = &pic.license {
writeln!(f, "licensed under <a role=\"license\" href=\"{url}\">{license}</a>",
url = license.url())?;
} else {