use std::{collections::HashMap, fs::File, io, path::Path};
use serde::{Serialize, Deserialize};
use serde_json::{Value, Result};
use crate::{Cask, Formula};
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Package {
#[serde(rename = "casks")]
casks: Vec<Cask>,
#[serde(rename = "formulae")]
formulae: Vec<Formula>,
#[serde(skip)]
pub value: HashMap<String, Value>,
#[serde(skip)]
pub name: String,
#[serde(skip)]
pub full_name: String,
#[serde(skip)]
pub tap: String,
#[serde(skip)]
pub desc: String,
#[serde(skip)]
pub homepage: String,
}
impl Package {
pub fn from(json_str: &str) -> anyhow::Result<Self> {
let mut pkg: Package = Self::from_all(json_str)?;
let (name, full_name, tap, desc, homepage) = if pkg.is_cask() {
let p = pkg.cask();
let desc = p.desc.clone().unwrap_or_default();
(
p.token.clone(),
p.full_token.clone(),
p.tap.clone(),
desc,
p.homepage.clone(),
)
} else {
let p = pkg.formula();
(
p.name.clone(),
p.full_name.clone(),
p.tap.clone(),
p.desc.clone(),
p.homepage.clone(),
)
};
pkg.name = name;
pkg.full_name = full_name;
pkg.tap = tap;
pkg.desc = desc;
pkg.homepage = homepage;
Ok(pkg)
}
pub fn from_all(json_str: &str) -> anyhow::Result<Self> {
let mut pkg: Package = serde_json::from_str(json_str)?;
let value: HashMap<String, Value> = serde_json::from_str(json_str)?;
pkg.value = value;
Ok(pkg)
}
pub fn is_cask(&self) -> bool {
!self.casks.is_empty()
}
pub fn is_installed(&self) -> bool {
if self.is_cask() {
self.cask().is_installed()
} else {
self.formula().is_installed()
}
}
pub fn formulae(&self) -> &Vec<Formula> {
&self.formulae
}
pub fn formula(&self) -> &Formula {
&self.formulae[0]
}
pub fn casks(&self) -> &Vec<Cask> {
&self.casks
}
pub fn cask(&self) -> &Cask {
&self.casks[0]
}
pub fn to_writer<T>(&self, writer: T) -> Result<()>
where T: io::Write
{
serde_json::to_writer(writer, &self.value)
}
pub fn to_file<T>(&self, path: T) -> anyhow::Result<()>
where T: AsRef<Path>
{
let file =File::create(path)?;
Ok(self.to_writer(&file)?)
}
}