Skip to main content

zoi_core/
pin.rs

1use serde::{Deserialize, Serialize};
2use std::fs::{self, File};
3use std::io::{self, Read, Write};
4use std::path::PathBuf;
5
6#[derive(Serialize, Deserialize, Debug, Clone)]
7pub struct PinnedPackage {
8    pub source: String,
9    pub version: String,
10}
11
12fn get_pinned_json_path() -> Result<PathBuf, io::Error> {
13    let home_dir = dirs::home_dir()
14        .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Could not find home directory"))?;
15    let zoi_dir = home_dir.join(".zoi");
16    if !zoi_dir.exists() {
17        fs::create_dir_all(&zoi_dir)?;
18    }
19    Ok(zoi_dir.join("pinned.json"))
20}
21
22pub fn get_pinned_packages() -> Result<Vec<PinnedPackage>, io::Error> {
23    let path = get_pinned_json_path()?;
24    if !path.exists() {
25        return Ok(Vec::new());
26    }
27
28    let mut file = File::open(path)?;
29    let mut contents = String::new();
30    file.read_to_string(&mut contents)?;
31
32    let packages: Vec<PinnedPackage> =
33        serde_json::from_str(&contents).unwrap_or_else(|_| Vec::new());
34    Ok(packages)
35}
36
37pub fn write_pinned_packages(packages: &[PinnedPackage]) -> Result<(), io::Error> {
38    let path = get_pinned_json_path()?;
39    let mut file = File::create(path)?;
40    let contents = serde_json::to_string_pretty(packages)?;
41    file.write_all(contents.as_bytes())?;
42    Ok(())
43}
44
45pub fn get_pinned_version(source: &str) -> Result<Option<String>, io::Error> {
46    let pinned_packages = get_pinned_packages()?;
47    Ok(pinned_packages
48        .iter()
49        .find(|p| p.source == source)
50        .map(|p| p.version.clone()))
51}
52
53pub fn is_pinned(source: &str) -> Result<bool, io::Error> {
54    let pinned_packages = get_pinned_packages()?;
55    Ok(pinned_packages.iter().any(|p| p.source == source))
56}