veloren_voxygen/credits.rs
1use serde::Deserialize;
2use std::path::PathBuf;
3
4// NOTE: we are free to split the manifest asset format and the format processed
5// for display into separate structs but they happen to be identical for now
6
7// See best practices for attribution: https://wiki.creativecommons.org/wiki/Best_practices_for_attribution
8
9#[expect(dead_code)]
10#[derive(Clone, Deserialize)]
11pub struct Art {
12 /// Name of the art.
13 pub name: String,
14 /// Link if the asset is from or derived from an external source that can be
15 /// linked.
16 #[serde(default)]
17 pub source_link: String,
18 /// List of authors for the credited art, field can be omitted if there are
19 /// no authors to list.
20 #[serde(default)]
21 pub authors: Vec<String>,
22 /// Relative path to the asset from the top level asset folder.
23 /// Used so we can keep track of the actual files, but not currently used in
24 /// the credits screen to display anything.
25 pub asset_path: PathBuf,
26 /// License that the art is under, can be omitted, if not present assumed to
27 /// be GPL3.
28 #[serde(default)]
29 pub license: String,
30 /// Link to the license if one is available.
31 #[serde(default)]
32 pub license_link: String,
33 /// Notes on any modifications that were made if the original work was
34 /// modified by us.
35 #[serde(default)]
36 pub modifications: String,
37 /// Any additional attribution notes that may be desired and/or required by
38 /// the respective license that can't be conveyed or would be awkward to
39 /// convey with the other provided fields.
40 #[serde(default)]
41 pub notes: String,
42}
43
44#[expect(dead_code)]
45#[derive(Clone, Deserialize, Debug)]
46pub struct Sounds {
47 /// List of authors in this credit
48 pub authors: Vec<String>,
49 /// List of files created by authors
50 pub files: Vec<PathBuf>,
51 /// License that the art is under, can be omitted, if not present assumed to
52 /// be GPL3.
53 #[serde(default)]
54 pub license: String,
55 /// Link to the license if one is available.
56 #[serde(default)]
57 pub license_link: String,
58 #[serde(default)]
59 /// Any additional attribution notes that may be desired and/or required by
60 /// the respective license that can't be conveyed or would be awkward to
61 /// convey with the other provided fields.
62 pub notes: String,
63}
64
65#[derive(Clone, Deserialize)]
66pub struct Contributor {
67 pub name: String,
68 /// Short note or description of the contributions
69 /// Optional, can be left empty/omitted
70 #[serde(default)]
71 pub contributions: String,
72}
73
74/// Credits manifest processed into format for display in the UI
75#[derive(Clone, Deserialize)]
76pub struct Credits {
77 pub music: Vec<Art>,
78 pub sounds: Vec<Sounds>,
79 pub fonts: Vec<Art>,
80 pub other_art: Vec<Art>,
81 pub contributors: Vec<Contributor>,
82 // TODO: include credits for dependencies where the license requires attribution?
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88 use common::assets::{self, AssetExt, Ron};
89
90 #[test]
91 fn all_art_asset_paths_exists() {
92 let credits = Ron::<Credits>::load_expect_cloned("credits").into_inner();
93
94 credits
95 .music
96 .into_iter()
97 .chain(credits.fonts)
98 .chain(credits.other_art)
99 .for_each(|art| {
100 assert!(
101 assets::ASSETS_PATH.join(&art.asset_path).exists(),
102 "assets/{} does not exist!",
103 art.asset_path.display(),
104 );
105 });
106 }
107
108 #[test]
109 fn all_sounds_asset_paths_exists() {
110 let credits = Ron::<Credits>::load_expect_cloned("credits").into_inner();
111 let sfx_path = assets::ASSETS_PATH.join(PathBuf::from("voxygen/audio/sfx/"));
112
113 credits.sounds.into_iter().for_each(|sounds| {
114 sounds.files.iter().for_each(|path| {
115 assert!(
116 sfx_path.join(path).exists(),
117 "assets/{} does not exist!",
118 path.display(),
119 );
120 });
121 });
122 }
123}