land_core/
meta.rs

1use anyhow::Result;
2use rand::distributions::Alphanumeric;
3use rand::{thread_rng, Rng};
4use serde::{Deserialize, Serialize};
5use std::path::Path;
6
7/// DEFAULT_METADATA_FILE is the default Meta file name
8pub const DEFAULT_METADATA_FILE: &str = "meta.toml";
9
10/// Meta is the Meta struct
11#[derive(Debug, Default, Serialize, Deserialize)]
12pub struct Meta {
13    pub manifest: String,
14    pub project: String, // project name auto generated
15    pub name: String,
16    pub description: String,
17    pub authors: Vec<String>,
18    pub language: String,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub build: Option<MetadataBuild>,
21}
22
23/// MetadataBuild is the build section of the Meta
24#[derive(Debug, Clone, Default, Serialize, Deserialize)]
25pub struct MetadataBuild {
26    pub rust_target_dir: Option<String>,
27}
28
29impl Meta {
30    /// read Meta from toml file
31    pub fn from_file(path: &str) -> Result<Self> {
32        let content = std::fs::read_to_string(path)?;
33        let mut manifest: Meta = toml::from_str(&content)?;
34
35        // fill value to default for Option<T>
36        if manifest.build.is_none() {
37            manifest.build = Some(MetadataBuild::default());
38        }
39
40        Ok(manifest)
41    }
42
43    /// read Meta from binary
44    pub fn from_binary(data: &[u8]) -> Result<Self> {
45        let manifest: Meta = toml::from_str(std::str::from_utf8(data)?)?;
46        Ok(manifest)
47    }
48
49    /// write Meta to toml file
50    pub fn to_file(&self, path: &str) -> Result<()> {
51        let content = toml::to_string(&self)?;
52        std::fs::write(path, content)?;
53        Ok(())
54    }
55
56    /// get arch from Meta
57    pub fn get_arch(&self) -> String {
58        "wasm32-wasi".to_string()
59    }
60
61    /// is wasi
62    pub fn is_wasi(&self) -> bool {
63        self.get_arch() == "wasm32-wasi"
64    }
65
66    /// get compiled target
67    pub fn get_target(&self) -> String {
68        let target = self
69            .build
70            .clone()
71            .unwrap_or_default()
72            .rust_target_dir
73            .unwrap_or_else(|| "target".to_string());
74        let arch = self.get_arch();
75        let target_dir = Path::new(&target).join(arch).join("release");
76        let name = self.name.replace('-', "_") + ".wasm";
77        target_dir.join(name).to_str().unwrap().to_string()
78    }
79
80    /// get output file
81    pub fn get_output(&self) -> String {
82        self.get_target().replace(".wasm", ".component.wasm")
83    }
84
85    /// get src directory name
86    pub fn get_src_dir(&self) -> String {
87        if self.language == "js" {
88            return "dist/".to_string();
89        }
90        "src/".to_string()
91    }
92
93    /// get project name
94    pub fn get_project_name(&self) -> String {
95        self.project.clone()
96    }
97
98    /// generate project name with random string
99    pub fn generate_project_name(&mut self) -> String {
100        let rand_string: String = thread_rng()
101            .sample_iter(&Alphanumeric)
102            .take(8)
103            .map(char::from)
104            .collect();
105        self.project = format!("{}-{}", self.name, rand_string.to_lowercase());
106        self.project.clone()
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113    /// test manifest from_file
114    #[test]
115    fn from_file() {
116        let manifest = Meta::from_file("../../tests/data/meta.toml").unwrap();
117        assert_eq!(manifest.manifest, "v1");
118        assert_eq!(manifest.name, "rust-basic");
119        assert_eq!(manifest.description, "example rust project");
120        assert_eq!(manifest.authors, vec!["your-name"]);
121        assert_eq!(manifest.language, "rust");
122        assert_eq!(
123            manifest.build.as_ref().unwrap().rust_target_dir,
124            Some("./target".to_string())
125        );
126    }
127
128    /// test manifest to file
129    #[test]
130    fn to_file() {
131        let manifest = Meta::from_file("../../tests/data/meta.toml").unwrap();
132        manifest.to_file("../../tests/data/meta2.toml").unwrap();
133        let manifest2 = Meta::from_file("../../tests/data/meta2.toml").unwrap();
134        assert_eq!(manifest.manifest, manifest2.manifest);
135        assert_eq!(manifest.name, manifest2.name);
136        assert_eq!(manifest.description, manifest2.description);
137        assert_eq!(manifest.authors, manifest2.authors);
138        assert_eq!(manifest.language, manifest2.language);
139        assert_eq!(
140            manifest.build.as_ref().unwrap().rust_target_dir,
141            manifest2.build.as_ref().unwrap().rust_target_dir
142        );
143        std::fs::remove_file("../../tests/data/meta2.toml").unwrap();
144    }
145}