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, 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}