use crate::error::Result;
use crate::paths::Paths;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Tap {
pub name: String,
pub url: String,
#[serde(default)]
pub pinned: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TapManager {
#[serde(default)]
taps: HashMap<String, Tap>,
}
impl Default for TapManager {
fn default() -> Self {
let mut taps = HashMap::new();
taps.insert(
"neul-labs/stout-index".to_string(),
Tap {
name: "neul-labs/stout-index".to_string(),
url: "https://raw.githubusercontent.com/neul-labs/stout-index/main".to_string(),
pinned: false,
},
);
Self { taps }
}
}
impl TapManager {
pub fn load(paths: &Paths) -> Result<Self> {
let taps_file = paths.stout_dir.join("taps.toml");
if taps_file.exists() {
let contents = std::fs::read_to_string(&taps_file)?;
let manager: TapManager = toml::from_str(&contents)?;
Ok(manager)
} else {
Ok(Self::default())
}
}
pub fn save(&self, paths: &Paths) -> Result<()> {
let taps_file = paths.stout_dir.join("taps.toml");
if let Some(parent) = taps_file.parent() {
std::fs::create_dir_all(parent)?;
}
let contents = toml::to_string_pretty(self)?;
std::fs::write(&taps_file, contents)?;
Ok(())
}
pub fn add(&mut self, tap: Tap) {
self.taps.insert(tap.name.clone(), tap);
}
pub fn remove(&mut self, name: &str) {
self.taps.remove(name);
}
pub fn get(&self, name: &str) -> Option<&Tap> {
self.taps.get(name)
}
pub fn list(&self) -> Vec<&Tap> {
let mut taps: Vec<_> = self.taps.values().collect();
taps.sort_by(|a, b| a.name.cmp(&b.name));
taps
}
pub fn urls(&self) -> Vec<(&str, &str)> {
self.taps
.iter()
.map(|(name, tap)| (name.as_str(), tap.url.as_str()))
.collect()
}
pub fn contains(&self, name: &str) -> bool {
self.taps.contains_key(name)
}
pub fn pin(&mut self, name: &str) -> bool {
if let Some(tap) = self.taps.get_mut(name) {
tap.pinned = true;
true
} else {
false
}
}
pub fn unpin(&mut self, name: &str) -> bool {
if let Some(tap) = self.taps.get_mut(name) {
tap.pinned = false;
true
} else {
false
}
}
}