Skip to main content

commonmeta_schema/
lib.rs

1#![forbid(unsafe_code)]
2
3use include_dir::{include_dir, Dir};
4
5/// The complete tree of Commonmeta conformance fixtures, embedded at compile
6/// time. Organized as `<format>/<name>.<ext>` (e.g. `commonmeta/journal_article.json`,
7/// `crossref/journal_article.json`, `orcid/0000-0002-0068-716X.xml`).
8///
9/// Consumers can look up a single file with [`fixture_str`] / [`fixture_bytes`],
10/// or iterate a subtree via `FIXTURES.get_dir("commonmeta").unwrap().files()`.
11pub static FIXTURES: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/fixtures");
12
13/// Return an embedded fixture's raw bytes by relative path, e.g.
14/// `fixture_bytes("commonmeta/journal_article.json")`.
15pub fn fixture_bytes(path: &str) -> Option<&'static [u8]> {
16    FIXTURES.get_file(path).map(|f| f.contents())
17}
18
19/// Return an embedded fixture's UTF-8 contents by relative path, e.g.
20/// `fixture_str("crossref/journal_article.json")`. Returns `None` if the file
21/// is absent or not valid UTF-8.
22pub fn fixture_str(path: &str) -> Option<&'static str> {
23    FIXTURES.get_file(path).and_then(|f| f.contents_utf8())
24}
25
26/// Embedded Commonmeta schema v1.0rc1.
27pub const COMMONMETA_SCHEMA_V1_0RC1: &str = include_str!("../schemas/commonmeta_v1.0rc1.json");
28
29/// Embedded Commonmeta schema v1.0rc2.
30pub const COMMONMETA_SCHEMA_V1_0RC2: &str = include_str!("../schemas/commonmeta_v1.0rc2.json");
31
32/// Embedded Commonmeta journal article fixture.
33pub const COMMONMETA_FIXTURE_JOURNAL_ARTICLE: &str =
34    include_str!("../fixtures/commonmeta/journal_article.json");
35
36/// Return an embedded schema by Commonmeta version string.
37///
38/// Currently supported: "1.0rc1", "1.0rc2".
39pub fn schema(version: &str) -> Option<&'static str> {
40    match version {
41        "1.0rc1" => Some(COMMONMETA_SCHEMA_V1_0RC1),
42        "1.0rc2" => Some(COMMONMETA_SCHEMA_V1_0RC2),
43        _ => None,
44    }
45}
46
47/// Return an embedded Commonmeta fixture by name.
48///
49/// Currently supported: "journal_article".
50pub fn fixture(name: &str) -> Option<&'static str> {
51    match name {
52        "journal_article" => Some(COMMONMETA_FIXTURE_JOURNAL_ARTICLE),
53        _ => None,
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::{fixture, schema};
60
61    #[test]
62    fn known_version_is_available() {
63        assert!(schema("1.0rc1").is_some());
64        assert!(schema("1.0rc2").is_some());
65    }
66
67    #[test]
68    fn unknown_version_is_none() {
69        assert!(schema("nope").is_none());
70    }
71
72    #[test]
73    fn known_fixture_is_available() {
74        assert!(fixture("journal_article").is_some());
75    }
76
77    #[test]
78    fn unknown_fixture_is_none() {
79        assert!(fixture("nope").is_none());
80    }
81
82    #[test]
83    fn embedded_fixtures_are_available() {
84        use super::{fixture_bytes, fixture_str, FIXTURES};
85        // A known commonmeta fixture is reachable by relative path.
86        assert!(fixture_str("commonmeta/journal_article.json").is_some());
87        // A non-JSON fixture (ORCID XML) is reachable as bytes.
88        assert!(fixture_bytes("orcid/0000-0002-0068-716X.xml").is_some());
89        // Subtree iteration works and the commonmeta dir is non-empty.
90        let commonmeta = FIXTURES.get_dir("commonmeta").expect("commonmeta dir");
91        assert!(commonmeta.files().count() > 0);
92        // Absent paths return None rather than panicking.
93        assert!(fixture_str("nope/missing.json").is_none());
94    }
95}