entrenar/cli/commands/research/
init.rs1use crate::cli::logging::log;
4use crate::cli::LogLevel;
5use crate::config::{ArtifactTypeArg, LicenseArg, ResearchInitArgs};
6use crate::research::{Affiliation, ArtifactType, Author, License, ResearchArtifact};
7
8fn convert_artifact_type(arg: &ArtifactTypeArg) -> ArtifactType {
10 match arg {
11 ArtifactTypeArg::Dataset => ArtifactType::Dataset,
12 ArtifactTypeArg::Paper => ArtifactType::Paper,
13 ArtifactTypeArg::Model => ArtifactType::Model,
14 ArtifactTypeArg::Code => ArtifactType::Code,
15 ArtifactTypeArg::Notebook => ArtifactType::Notebook,
16 ArtifactTypeArg::Workflow => ArtifactType::Workflow,
17 }
18}
19
20fn convert_license(arg: &LicenseArg) -> License {
22 match arg {
23 LicenseArg::CcBy4 => License::CcBy4,
24 LicenseArg::CcBySa4 => License::Custom("CC-BY-SA-4.0".to_string()),
25 LicenseArg::Cc0 => License::Cc0,
26 LicenseArg::Mit => License::Mit,
27 LicenseArg::Apache2 => License::Apache2,
28 LicenseArg::Gpl3 => License::Gpl3,
29 LicenseArg::Bsd3 => License::Bsd3,
30 }
31}
32
33fn build_author(args: &ResearchInitArgs) -> Result<Option<Author>, String> {
35 let Some(author_name) = &args.author else {
36 return Ok(None);
37 };
38 let mut author = Author::new(author_name);
39
40 if let Some(orcid) = &args.orcid {
41 author = author.with_orcid(orcid).map_err(|e| format!("Invalid ORCID: {e}"))?;
42 }
43 if let Some(affiliation) = &args.affiliation {
44 author = author.with_affiliation(Affiliation::new(affiliation));
45 }
46 Ok(Some(author))
47}
48
49pub fn run_research_init(args: ResearchInitArgs, level: LogLevel) -> Result<(), String> {
50 log(level, LogLevel::Normal, &format!("Initializing research artifact: {}", args.id));
51
52 let artifact_type = convert_artifact_type(&args.artifact_type);
53 let license = convert_license(&args.license);
54 let mut artifact = ResearchArtifact::new(&args.id, &args.title, artifact_type, license);
55
56 if let Some(author) = build_author(&args)? {
57 artifact = artifact.with_author(author);
58 }
59
60 if let Some(description) = &args.description {
61 artifact = artifact.with_description(description);
62 }
63 if let Some(keywords) = &args.keywords {
64 let kw: Vec<&str> = keywords.split(',').map(str::trim).collect();
65 artifact = artifact.with_keywords(kw);
66 }
67 if let Some(doi) = &args.doi {
68 artifact = artifact.with_doi(doi);
69 }
70
71 let yaml = serde_yaml::to_string(&artifact).map_err(|e| format!("Serialization error: {e}"))?;
72 std::fs::write(&args.output, &yaml).map_err(|e| format!("Failed to write file: {e}"))?;
73
74 log(level, LogLevel::Normal, &format!("Artifact saved to: {}", args.output.display()));
75
76 Ok(())
77}