gmbm/pkg/
mod.rs

1pub(crate) mod build;
2pub(crate) mod clone;
3pub(crate) mod init;
4pub(crate) mod process;
5
6use std::{io::Read, path::PathBuf};
7use url::Url;
8
9pub struct Package<'a> {
10	pub name: &'a str,
11	pub repo_url: Url,
12	pub mpath: PathBuf, // Current exe dir by default
13
14	pub cache: PathBuf,
15	pub repo: PathBuf,
16	pub(crate) filemap: Option<pelite::FileMap>,
17}
18
19use serde::{Deserialize, Serialize};
20#[derive(Deserialize, Serialize)]
21struct PackageInfo<'a> {
22	name: &'a str,
23	repo_url: &'a str,
24}
25
26#[derive(Debug, thiserror::Error)]
27pub enum CreationError {
28	#[error("Package already exists")]
29	Exists,
30	#[error("IO Error: `{0}`")]
31	IO(std::io::Error),
32	#[error("Error when initializing: `{0}`")]
33	Init(init::InitError),
34}
35
36#[derive(Debug, thiserror::Error)]
37pub enum PackageOpenError {
38	#[error("Package does not exist")]
39	DoesNotExist,
40	#[error("Package is malformed. Missing pkg.toml")]
41	Malformed,
42	#[error("IO Error: `{0}`")]
43	IO(#[from] std::io::Error),
44	#[error("Could not parse pkg.toml: `{0}`")]
45	TomlParse(#[from] toml::de::Error),
46	#[error("Could not parse URL `{0}`")]
47	UrlParse(#[from] url::ParseError),
48}
49
50impl<'a> Package<'a> {
51	pub fn create(name: &'a str, repo_url: Url, mpath: PathBuf) -> Result<Self, CreationError> {
52		let cache = mpath.join("cache").join(name);
53
54		if cache.exists() {
55			return Err(CreationError::Exists);
56		}
57
58		let repo_dir = cache.join("repo");
59
60		if let Err(why) = std::fs::create_dir_all(&cache) {
61			return Err(CreationError::IO(why));
62		}
63
64		let this = Self {
65			name,
66			repo_url,
67			mpath,
68
69			cache,
70			repo: repo_dir,
71			filemap: None,
72		};
73
74		this.init().map_err(CreationError::Init)?;
75
76		Ok(this)
77	}
78
79	pub fn open(name: &'a str, mpath: PathBuf) -> Result<Self, PackageOpenError> {
80		let cache = mpath.join("cache").join(name);
81
82		if !cache.exists() {
83			return Err(PackageOpenError::DoesNotExist);
84		}
85
86		let info = cache.join("pkg.toml");
87		if !info.exists() {
88			return Err(PackageOpenError::Malformed);
89		}
90
91		let mut toml = std::fs::File::open(info)?;
92		let mut buf = String::new();
93		toml.read_to_string(&mut buf)?;
94
95		let data: PackageInfo = toml::from_str(&buf)?;
96		let repo_url = url::Url::parse(data.repo_url)?;
97
98		let repo_dir = cache.join("repo");
99
100		Ok(Self {
101			name,
102			repo_url,
103			mpath,
104
105			cache,
106			repo: repo_dir,
107			filemap: None,
108		})
109	}
110}