snarkvm_debug/file/
manifest.rs1use crate::{
16 prelude::{Network, ProgramID},
17 synthesizer::Program,
18};
19
20use anyhow::{anyhow, ensure, Result};
21use core::str::FromStr;
22use std::{
23 fs::{self, File},
24 io::Write,
25 path::{Path, PathBuf},
26};
27
28const MANIFEST_FILE_NAME: &str = "program.json";
29
30pub struct Manifest<N: Network> {
31 path: PathBuf,
33 program_id: ProgramID<N>,
35}
36
37impl<N: Network> Manifest<N> {
38 pub fn create(directory: &Path, id: &ProgramID<N>) -> Result<Self> {
40 ensure!(directory.exists(), "The program directory does not exist: '{}'", directory.display());
42 ensure!(!Program::is_reserved_keyword(id.name()), "Program name is invalid (reserved): {id}");
44
45 let manifest_string = format!(
47 r#"{{
48 "program": "{id}",
49 "version": "0.0.0",
50 "description": "",
51 "license": "MIT"
52}}
53"#
54 );
55
56 let path = directory.join(MANIFEST_FILE_NAME);
58 ensure!(!path.exists(), "Manifest file already exists: '{}'", path.display());
60
61 File::create(&path)?.write_all(manifest_string.as_bytes())?;
63
64 Ok(Self { path, program_id: *id })
66 }
67
68 pub fn open(directory: &Path) -> Result<Self> {
70 ensure!(directory.exists(), "The program directory does not exist: '{}'", directory.display());
72
73 let path = directory.join(MANIFEST_FILE_NAME);
75 ensure!(path.exists(), "Manifest file is missing: '{}'", path.display());
77
78 let manifest_string = fs::read_to_string(&path)?;
80 let json: serde_json::Value = serde_json::from_str(&manifest_string)?;
81
82 let id_string = json["program"].as_str().ok_or_else(|| anyhow!("Program ID not found."))?;
84 let id = ProgramID::from_str(id_string)?;
85 ensure!(!Program::is_reserved_keyword(id.name()), "Program name is invalid (reserved): {id}");
87
88 Ok(Self { path, program_id: id })
90 }
91
92 pub fn exists_at(directory: &Path) -> bool {
94 let path = directory.join(MANIFEST_FILE_NAME);
96 path.is_file() && path.exists()
98 }
99
100 pub const fn file_name() -> &'static str {
102 MANIFEST_FILE_NAME
103 }
104
105 pub const fn path(&self) -> &PathBuf {
107 &self.path
108 }
109
110 pub const fn program_id(&self) -> &ProgramID<N> {
112 &self.program_id
113 }
114}