scratch_io/
itch_manifest.rs1use crate::{errors::FilesystemError, filesystem, itch_api::types::*};
2use std::path::{Path, PathBuf};
3
4const MANIFEST_FILENAME: &str = ".itch.toml";
5const MANIFEST_PLAY_ACTION: &str = "play";
6
7impl ManifestAction {
8 pub async fn get_canonical_path(&self, folder: &Path) -> Result<PathBuf, FilesystemError> {
9 filesystem::get_canonical_path(&folder.join(&self.path)).await
10 }
11}
12
13pub async fn read_manifest(upload_folder: &Path) -> Result<Option<Manifest>, String> {
15 let manifest_path = upload_folder.join(MANIFEST_FILENAME);
16
17 if !filesystem::exists(&manifest_path).await? {
18 return Ok(None);
19 }
20
21 let manifest_text: String = tokio::fs::read_to_string(&manifest_path)
22 .await
23 .map_err(|e| e.to_string())?;
24
25 toml::from_str::<Manifest>(&manifest_text)
26 .map(Some)
27 .map_err(|e| {
28 format!(
29 "Couldn't parse itch manifest: {}\n{e}",
30 manifest_path.to_string_lossy()
31 )
32 })
33}
34
35pub async fn launch_action(
37 upload_folder: &Path,
38 action_name: Option<&str>,
39) -> Result<Option<ManifestAction>, String> {
40 let Some(manifest) = read_manifest(upload_folder).await? else {
41 return Ok(None);
42 };
43
44 let action_name = action_name.unwrap_or(MANIFEST_PLAY_ACTION);
45
46 Ok(
47 manifest
48 .actions
49 .unwrap_or_default()
50 .into_iter()
51 .find(|a| a.name == action_name),
52 )
53}