diff --git a/dsp-meta/src/api/convert/mod.rs b/dsp-meta/src/api/convert/mod.rs index 9c49a5a8..91ea7fc5 100644 --- a/dsp-meta/src/api/convert/mod.rs +++ b/dsp-meta/src/api/convert/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod axum; pub mod hcl; +pub mod serde; pub(crate) mod rdf; diff --git a/dsp-meta/src/api/convert/serde/draft_model.rs b/dsp-meta/src/api/convert/serde/draft_model.rs index e69de29b..c29cec7f 100644 --- a/dsp-meta/src/api/convert/serde/draft_model.rs +++ b/dsp-meta/src/api/convert/serde/draft_model.rs @@ -0,0 +1,240 @@ +use std::collections::HashMap; +use nonempty::NonEmpty; +use serde::{Deserialize, Serialize}; + +// This model corresponds to the json schema found in /data/schema-metadata-draft.json +// These data structures are able to parse all json metadata found in /data/json/.*json +// We can use them to produce TOML or YAML files as well + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftMetadata { + pub project: DraftProject, + pub datasets: Option>, + pub persons: Option>, + pub organizations: Option>, + pub grants: Option>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftProject { + #[serde(rename = "__id")] + pub id: String, + #[serde(rename = "__createdAt")] + pub created_at: Option, + #[serde(rename = "__createdBy")] + pub created_by: Option, + pub shortcode: String, + pub name: String, + pub description: Option, + pub start_date: DraftDate, + pub teaser_text: String, + pub datasets: NonEmpty, + pub keywords: NonEmpty, + pub disciplines: NonEmpty, + pub temporal_coverage: Option>, + pub spatial_coverage: Option>, + pub funders: Option>, + pub url: Option, + pub secondary_url: Option, + pub data_management_plan: Option, + pub end_date: Option, + pub contact_point: Option, + pub how_to_cite: Option, + pub publications: Option>, + pub grants: Option>, + pub alternative_names: Option>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub struct DraftPublication { + pub text: String, + pub url: Option>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftDataset { + #[serde(rename = "__id")] + pub id: String, + #[serde(rename = "__createdAt")] + pub created_at: Option, + #[serde(rename = "__createdBy")] + pub created_by: Option, + pub abstracts: Option>, + pub access_conditions: Option, + pub additional: Option>, + pub alternative_titles: Option>, + pub attributions: Option>, + pub date_created: Option, + pub date_modified: Option, + pub date_published: Option, + pub distribution: Option, + pub how_to_cite: Option, + pub languages: Option>, + pub licenses: Option>, + pub status: Option, + pub title: Option, + pub type_of_data: Option>, + pub urls: Option>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum DraftAccessCondition { + Open, + Restricted, + Closed, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub enum DraftStatus { + #[serde(rename = "In planning")] + InPlanning, + #[serde(rename = "Ongoing")] + OnGoing, + #[serde(rename = "On hold")] + OnHold, + Finished, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub enum DraftTypeOfData { + XML, + Text, + Image, + Video, + Audio, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftPerson { + #[serde(rename = "__id")] + pub id: String, + #[serde(rename = "__createdAt")] + pub created_at: Option, + #[serde(rename = "__createdBy")] + pub created_by: Option, + pub job_titles: Option>, + pub given_names: NonEmpty, + pub family_names: NonEmpty, + pub affiliation: Option>, + pub address: Option, + pub email: Option, + pub secondary_email: Option, + pub authority_refs: Option>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftOrganization { + #[serde(rename = "__id")] + pub id: String, + #[serde(rename = "__createdAt")] + pub created_at: Option, + #[serde(rename = "__createdBy")] + pub created_by: Option, + pub name: String, + pub url: Option, + pub address: Option, + pub email: Option, + pub alternative_names: Option>, + pub authority_refs: Option>, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftGrant { + #[serde(rename = "__id")] + pub id: String, + #[serde(rename = "__createdAt")] + pub created_at: Option, + #[serde(rename = "__createdBy")] + pub created_by: Option, + pub funders: NonEmpty, + pub number: Option, + pub name: Option, + pub url: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub struct DraftText(HashMap); + +#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Hash)] +pub struct DraftIsoCode(String); + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub struct DraftDate(String); + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftUrl { + pub url: String, + pub text: Option, + #[serde(rename = "type")] + #[serde(default = "DraftUrlType::default")] + pub url_type: DraftUrlType, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub enum DraftUrlType { + URL, + Geonames, + Pleiades, + Skos, + Periodo, + Chronontology, + GND, + VIAF, + Grid, + ORCID, + #[serde(rename = "Creative Commons")] + CreativeCommons, + DOI, + ARK, +} +impl DraftUrlType { + fn default() -> Self { DraftUrlType::URL } +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftAddress { + pub street: String, + pub postal_code: String, + pub locality: Option, + pub country: String, + pub canton: Option, + pub additional: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftDataManagementPlan { + pub available: bool, + pub url: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftAttribution { + pub agent: String, + pub roles: NonEmpty, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct DraftLicense { + pub license: DraftUrl, + pub date: DraftDate, + pub details: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(untagged)] +pub enum DraftTextOrUrl { + TextValue(DraftText), + UrlValue(DraftUrl), +} \ No newline at end of file diff --git a/dsp-meta/src/api/convert/serde/mod.rs b/dsp-meta/src/api/convert/serde/mod.rs index e69de29b..3c5f5b1c 100644 --- a/dsp-meta/src/api/convert/serde/mod.rs +++ b/dsp-meta/src/api/convert/serde/mod.rs @@ -0,0 +1 @@ +pub mod draft_model; \ No newline at end of file diff --git a/dsp-meta/tests/draft_schema_test.rs b/dsp-meta/tests/draft_schema_test.rs index 99f24efe..370b0cff 100644 --- a/dsp-meta/tests/draft_schema_test.rs +++ b/dsp-meta/tests/draft_schema_test.rs @@ -11,7 +11,7 @@ use dsp_meta::api; fn test_json_and_yaml_serialization_are_equal() { let path = "/Users/christian/git/dasch/dsp-meta/data/examples/sgv.json"; let contents_json = fs::read_to_string(path).expect("Read JSON"); - let metadata_json = serde_json::from_str::(&*contents_json).expect("From JSON"); + let metadata_json = serde_json::from_str::(&*contents_json).expect("From JSON"); let contents_yaml = fs::read_to_string("/Users/christian/git/dasch/dsp-meta/data/examples/sgv.yaml").expect("Read YML"); let metadata_yaml = serde_yaml::from_str(&*contents_yaml).expect("From YAML"); assert_eq!(metadata_json, metadata_yaml); @@ -21,9 +21,9 @@ fn test_json_and_yaml_serialization_are_equal() { fn test_json_and_toml_serialization_are_equal() { let path = "/Users/christian/git/dasch/dsp-meta/data/examples/sgv.json"; let contents_json = fs::read_to_string(path).expect("Read JSON"); - let metadata_json = serde_json::from_str::(&*contents_json).expect("From JSON"); + let metadata_json = serde_json::from_str::(&*contents_json).expect("From JSON"); let contents_toml = fs::read_to_string("/Users/christian/git/dasch/dsp-meta/data/examples/sgv.toml").expect("Read TOML"); - let metadata_toml = toml::from_str::(&*contents_toml).expect("From TOML"); + let metadata_toml = toml::from_str::(&*contents_toml).expect("From TOML"); assert_eq!(metadata_json, metadata_toml); } @@ -51,7 +51,7 @@ fn test_deserialization_data() { println!("Checking {}:", path.to_str().get_or_insert("")); let contents = fs::read_to_string(path) .expect("Should have been able to read the file"); - let metadata = serde_json::from_str::(&*contents); + let metadata = serde_json::from_str::(&*contents); match metadata { Ok(_data) => { success = success + 1;