harn_cli/package/lockfile/
exports.rs1use crate::package::*;
5
6#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
7pub struct PackageLockExports {
8 #[serde(default, skip_serializing_if = "Vec::is_empty")]
9 pub modules: Vec<PackageLockExport>,
10 #[serde(default, skip_serializing_if = "Vec::is_empty")]
11 pub tools: Vec<PackageLockExport>,
12 #[serde(default, skip_serializing_if = "Vec::is_empty")]
13 pub skills: Vec<PackageLockExport>,
14 #[serde(default, skip_serializing_if = "Vec::is_empty")]
15 pub personas: Vec<String>,
16}
17
18impl PackageLockExports {
19 pub(crate) fn is_empty(&self) -> bool {
20 self.modules.is_empty()
21 && self.tools.is_empty()
22 && self.skills.is_empty()
23 && self.personas.is_empty()
24 }
25}
26
27#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
28pub struct PackageLockExport {
29 pub name: String,
30 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub path: Option<String>,
32 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub symbol: Option<String>,
34}
35
36pub(crate) fn package_lock_exports_from_manifest(manifest: &Manifest) -> PackageLockExports {
37 let mut modules: Vec<PackageLockExport> = manifest
38 .exports
39 .iter()
40 .map(|(name, path)| PackageLockExport {
41 name: name.clone(),
42 path: Some(path.clone()),
43 symbol: None,
44 })
45 .collect();
46 modules.sort_by(|left, right| left.name.cmp(&right.name));
47
48 let (mut tools, mut skills) = manifest
49 .package
50 .as_ref()
51 .map(|package| {
52 let tools = package
53 .tools
54 .iter()
55 .map(|tool| PackageLockExport {
56 name: tool.name.clone(),
57 path: Some(tool.module.clone()),
58 symbol: Some(tool.symbol.clone()),
59 })
60 .collect::<Vec<_>>();
61 let skills = package
62 .skills
63 .iter()
64 .map(|skill| PackageLockExport {
65 name: skill.name.clone(),
66 path: Some(skill.path.clone()),
67 symbol: None,
68 })
69 .collect::<Vec<_>>();
70 (tools, skills)
71 })
72 .unwrap_or_default();
73 tools.sort_by(|left, right| left.name.cmp(&right.name));
74 skills.sort_by(|left, right| left.name.cmp(&right.name));
75
76 let mut personas: Vec<String> = manifest
77 .personas
78 .iter()
79 .filter_map(|persona| persona.name.clone())
80 .collect();
81 personas.sort();
82 personas.dedup();
83
84 PackageLockExports {
85 modules,
86 tools,
87 skills,
88 personas,
89 }
90}
91
92pub(crate) fn normalized_requirements(values: &[String]) -> Vec<String> {
93 let mut out: Vec<String> = values
94 .iter()
95 .map(|value| value.trim())
96 .filter(|value| !value.is_empty())
97 .map(str::to_string)
98 .collect();
99 out.sort();
100 out.dedup();
101 out
102}