1use anyhow::{Context, Result};
2use indexmap::IndexMap;
3use serde::{Deserialize, Serialize};
4use std::path::{Path, PathBuf};
5use tokio::fs;
6
7use crate::{polyfill::Polyfill, TargetVersion};
8
9pub const DEFAULT_MANIFEST_PATH: &str = "dalbit.toml";
10
11#[derive(Debug, Deserialize, Serialize)]
13pub struct Manifest {
14 input: PathBuf,
15 output: PathBuf,
16 file_extension: Option<String>,
17 target_version: TargetVersion,
18 pub minify: bool,
19 modifiers: IndexMap<String, bool>,
20 polyfill: Option<Polyfill>,
21 #[serde(skip)]
22 path: PathBuf,
23}
24
25impl Default for Manifest {
26 fn default() -> Self {
27 Self {
28 input: Path::new("input.luau").to_owned(),
29 output: Path::new("output.lua").to_owned(),
30 file_extension: Some("lua".to_owned()),
31 target_version: TargetVersion::Lua53,
32 minify: true,
33 modifiers: IndexMap::new(),
34 polyfill: Some(Polyfill::default()),
35 path: Path::new(DEFAULT_MANIFEST_PATH).to_owned(),
36 }
37 }
38}
39
40impl Manifest {
41 pub async fn from_file(path: impl Into<PathBuf>) -> Result<Self> {
43 let path = path.into();
44 let manifest = fs::read_to_string(&path).await?;
45 let mut manifest: Manifest = toml::from_str(&manifest)
46 .with_context(|| format!("Failed to parse manifest file: {:?}", path))?;
47 manifest.path = path;
48 Ok(manifest)
49 }
50
51 pub async fn write(&self, path: impl Into<PathBuf>) -> Result<()> {
53 fs::write(path.into(), toml::to_string(self)?).await?;
54 Ok(())
55 }
56
57 #[inline]
58 pub fn input(&self) -> PathBuf {
59 let path = self.path.parent().unwrap().join(&self.input);
60 log::debug!("manifest input path: {:?}", path);
61 path
62 }
63
64 #[inline]
65 pub fn output(&self) -> PathBuf {
66 let path = self.path.parent().unwrap().join(&self.output);
67 log::debug!("manifest output path: {:?}", path);
68 path
69 }
70
71 #[inline]
72 pub fn file_extension(&self) -> &Option<String> {
73 &self.file_extension
74 }
75
76 #[inline]
77 pub fn modifiers(&self) -> &IndexMap<String, bool> {
78 &self.modifiers
79 }
80
81 #[inline]
82 pub fn target_version(&self) -> &TargetVersion {
83 &self.target_version
84 }
85
86 #[inline]
87 pub fn polyfill(&self) -> &Option<Polyfill> {
88 &self.polyfill
89 }
90}