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 license: Option<String>,
42 #[serde(default)]
44 pub update_url: Option<String>,
45 #[serde(default)]
47 pub manifest_url: Option<String>,
48 #[serde(default)]
50 pub min_runtime_version: Option<String>,
51 #[serde(default)]
53 pub notes: Vec<String>,
54 #[serde(default)]
56 pub legacy_filenames: Vec<String>,
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
61pub struct AvailableVersion {
62 pub version: String,
64 #[serde(default)]
66 pub note: Option<String>,
67 #[serde(default)]
69 pub additions: Vec<AvailableAddition>,
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
74pub struct AvailableAddition {
75 pub name: String,
77 pub version: String,
79 #[serde(default)]
81 pub note: Option<String>,
82}
83
84#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86pub struct EnvKey {
87 pub key: String,
89 pub value: String,
91}
92
93#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
95pub struct Checksum {
96 pub algorithm: String,
98 pub value: String,
100}
101
102#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
104#[serde(tag = "kind", rename_all = "kebab-case")]
105pub enum InstallSource {
106 Directory { path: PathBuf },
108 File { path: PathBuf },
110 Url {
112 url: String,
113 #[serde(default)]
114 headers: BTreeMap<String, String>,
115 },
116}
117
118#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
120pub struct InstallArtifact {
121 pub name: String,
123 pub version: String,
125 pub source: InstallSource,
127 #[serde(default)]
129 pub note: Option<String>,
130 #[serde(default)]
132 pub checksum: Option<Checksum>,
133}
134
135#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
137pub struct InstallPlan {
138 pub plugin: String,
140 pub version: String,
142 pub main: InstallArtifact,
144 #[serde(default)]
146 pub additions: Vec<InstallArtifact>,
147 #[serde(default)]
149 pub legacy_filenames: Vec<String>,
150}
151
152#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
154pub struct InstalledArtifact {
155 pub name: String,
157 pub version: String,
159 pub path: PathBuf,
161 #[serde(default)]
163 pub note: Option<String>,
164}
165
166#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
168pub struct InstalledRuntime {
169 pub plugin: String,
171 pub version: String,
173 pub root_dir: PathBuf,
175 pub main: InstalledArtifact,
177 #[serde(default)]
179 pub additions: Vec<InstalledArtifact>,
180}
181
182impl InstalledRuntime {
183 pub fn main_path(&self) -> &Path {
185 &self.main.path
186 }
187
188 pub fn relocate(&self, new_root: &Path) -> Self {
193 let relocate_path = |p: &Path| -> PathBuf {
194 p.strip_prefix(&self.root_dir)
195 .map(|rel| new_root.join(rel))
196 .unwrap_or_else(|_| p.to_path_buf())
197 };
198 Self {
199 plugin: self.plugin.clone(),
200 version: self.version.clone(),
201 root_dir: new_root.to_path_buf(),
202 main: InstalledArtifact {
203 path: relocate_path(&self.main.path),
204 ..self.main.clone()
205 },
206 additions: self
207 .additions
208 .iter()
209 .map(|a| InstalledArtifact {
210 path: relocate_path(&a.path),
211 ..a.clone()
212 })
213 .collect(),
214 }
215 }
216}