Skip to main content

entrenar/research/archive/
metadata.rs

1//! Deposit metadata types.
2
3use crate::research::artifact::ResearchArtifact;
4use crate::research::citation::CitationMetadata;
5use serde::{Deserialize, Serialize};
6
7use super::identifiers::RelatedIdentifier;
8
9/// Resource type for archives
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
11pub enum ResourceType {
12    Dataset,
13    Software,
14    Publication,
15    Presentation,
16    Poster,
17    Image,
18    Video,
19    Other,
20}
21
22impl ResourceType {
23    /// Convert from artifact type
24    pub fn from_artifact_type(artifact_type: crate::research::artifact::ArtifactType) -> Self {
25        use crate::research::artifact::ArtifactType;
26        match artifact_type {
27            ArtifactType::Dataset => Self::Dataset,
28            ArtifactType::Model | ArtifactType::Code => Self::Software,
29            ArtifactType::Paper => Self::Publication,
30            ArtifactType::Notebook | ArtifactType::Workflow => Self::Other,
31        }
32    }
33
34    /// Get Zenodo upload type string
35    pub fn zenodo_type(&self) -> &'static str {
36        match self {
37            Self::Dataset => "dataset",
38            Self::Software => "software",
39            Self::Publication => "publication",
40            Self::Presentation => "presentation",
41            Self::Poster => "poster",
42            Self::Image => "image",
43            Self::Video => "video",
44            Self::Other => "other",
45        }
46    }
47}
48
49/// Deposit metadata for archive submission
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct DepositMetadata {
52    /// Title
53    pub title: String,
54    /// Description/abstract
55    pub description: String,
56    /// Authors (names)
57    pub authors: Vec<String>,
58    /// Keywords
59    pub keywords: Vec<String>,
60    /// License identifier (e.g., "cc-by-4.0")
61    pub license: String,
62    /// Resource type
63    pub resource_type: ResourceType,
64    /// Related identifiers (DOIs, URLs)
65    pub related_identifiers: Vec<RelatedIdentifier>,
66}
67
68impl DepositMetadata {
69    /// Create from a research artifact
70    pub fn from_artifact(artifact: &ResearchArtifact) -> Self {
71        Self {
72            title: artifact.title.clone(),
73            description: artifact
74                .description
75                .clone()
76                .unwrap_or_else(|| format!("{} - {}", artifact.title, artifact.artifact_type)),
77            authors: artifact.authors.iter().map(|a| a.name.clone()).collect(),
78            keywords: artifact.keywords.clone(),
79            license: artifact.license.to_string().to_lowercase(),
80            resource_type: ResourceType::from_artifact_type(artifact.artifact_type),
81            related_identifiers: artifact
82                .doi
83                .iter()
84                .map(RelatedIdentifier::is_identical_to)
85                .collect(),
86        }
87    }
88
89    /// Create from citation metadata
90    pub fn from_citation(citation: &CitationMetadata) -> Self {
91        let mut metadata = Self::from_artifact(&citation.artifact);
92        if let Some(url) = &citation.url {
93            metadata.related_identifiers.push(RelatedIdentifier::is_supplement_to(url));
94        }
95        metadata
96    }
97}