1use std::collections::BTreeMap;
4use std::path::{Path, PathBuf};
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "kebab-case")]
11pub enum PluginBackendKind {
12 Lua,
14 Wasi,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20pub struct PluginManifest {
21 pub name: String,
23 pub backend: PluginBackendKind,
25 pub source: PathBuf,
27 #[serde(default)]
29 pub description: Option<String>,
30 #[serde(default)]
32 pub aliases: Vec<String>,
33 #[serde(default)]
35 pub version: Option<String>,
36 #[serde(default)]
38 pub homepage: Option<String>,
39 #[serde(default)]
41 pub update_url: Option<String>,
42 #[serde(default)]
44 pub manifest_url: Option<String>,
45 #[serde(default)]
47 pub min_runtime_version: Option<String>,
48 #[serde(default)]
50 pub notes: Vec<String>,
51 #[serde(default)]
53 pub legacy_filenames: Vec<String>,
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58pub struct AvailableVersion {
59 pub version: String,
61 #[serde(default)]
63 pub note: Option<String>,
64 #[serde(default)]
66 pub additions: Vec<AvailableAddition>,
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
71pub struct AvailableAddition {
72 pub name: String,
74 pub version: String,
76 #[serde(default)]
78 pub note: Option<String>,
79}
80
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
83pub struct EnvKey {
84 pub key: String,
86 pub value: String,
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
92pub struct Checksum {
93 pub algorithm: String,
95 pub value: String,
97}
98
99#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
101#[serde(tag = "kind", rename_all = "kebab-case")]
102pub enum InstallSource {
103 Directory { path: PathBuf },
105 File { path: PathBuf },
107 Url {
109 url: String,
110 #[serde(default)]
111 headers: BTreeMap<String, String>,
112 },
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
117pub struct InstallArtifact {
118 pub name: String,
120 pub version: String,
122 pub source: InstallSource,
124 #[serde(default)]
126 pub note: Option<String>,
127 #[serde(default)]
129 pub checksum: Option<Checksum>,
130}
131
132#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
134pub struct InstallPlan {
135 pub plugin: String,
137 pub version: String,
139 pub main: InstallArtifact,
141 #[serde(default)]
143 pub additions: Vec<InstallArtifact>,
144 #[serde(default)]
146 pub legacy_filenames: Vec<String>,
147}
148
149#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
151pub struct InstalledArtifact {
152 pub name: String,
154 pub version: String,
156 pub path: PathBuf,
158 #[serde(default)]
160 pub note: Option<String>,
161}
162
163#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
165pub struct InstalledRuntime {
166 pub plugin: String,
168 pub version: String,
170 pub root_dir: PathBuf,
172 pub main: InstalledArtifact,
174 #[serde(default)]
176 pub additions: Vec<InstalledArtifact>,
177}
178
179impl InstalledRuntime {
180 pub fn main_path(&self) -> &Path {
182 &self.main.path
183 }
184
185 pub fn relocate(&self, new_root: &Path) -> Self {
190 let relocate_path = |p: &Path| -> PathBuf {
191 p.strip_prefix(&self.root_dir)
192 .map(|rel| new_root.join(rel))
193 .unwrap_or_else(|_| p.to_path_buf())
194 };
195 Self {
196 plugin: self.plugin.clone(),
197 version: self.version.clone(),
198 root_dir: new_root.to_path_buf(),
199 main: InstalledArtifact {
200 path: relocate_path(&self.main.path),
201 ..self.main.clone()
202 },
203 additions: self
204 .additions
205 .iter()
206 .map(|a| InstalledArtifact {
207 path: relocate_path(&a.path),
208 ..a.clone()
209 })
210 .collect(),
211 }
212 }
213}