refactor: move types to lib.rs

This is so that they can be more easily tested in a REPL.
This commit is contained in:
Colin Woodbury
2023-11-27 14:53:52 +09:00
parent 55fc12153b
commit 2bc4b8c7b5
2 changed files with 143 additions and 125 deletions

141
src/lib.rs Normal file
View File

@@ -0,0 +1,141 @@
//! Independently testable types and functions.
use serde::Deserialize;
use std::{
ops::Not,
path::{Path, PathBuf},
};
pub enum GitHost {
Github,
Gitlab,
}
impl GitHost {
pub fn source(&self, package: &Package) -> String {
match self {
GitHost::Github => format!(
"{}/releases/download/v$pkgver/{}-$pkgver-x86_64.tar.gz",
package.repository, package.name
),
GitHost::Gitlab => format!(
"{}/-/archive/v$pkgver/{}-$pkgver-x86_64.tar.gz",
package.repository, package.name
),
}
}
}
#[derive(Deserialize, Debug)]
pub struct Package {
pub name: String,
pub version: String,
pub authors: Vec<String>,
pub description: String,
pub homepage: String,
pub repository: String,
pub license: String,
pub metadata: Option<Metadata>,
}
impl Package {
/// The name of the tarball that should be produced from this `Package`.
pub fn tarball(&self, output: &Path) -> PathBuf {
output.join(format!("{}-{}-x86_64.tar.gz", self.name, self.version))
}
pub fn git_host(&self) -> Option<GitHost> {
if self.repository.starts_with("https://github") {
Some(GitHost::Github)
} else if self.repository.starts_with("https://gitlab") {
Some(GitHost::Gitlab)
} else {
None
}
}
}
// {
// Package {
// name: "aura".to_string(),
// version: "1.2.3".to_string(),
// authors: vec![],
// description: "".to_string(),
// homepage: "".to_string(),
// repository: "".to_string(),
// license: "".to_string(),
// metadata: None,
// }.tarball(Path::new("foobar"))
// }
#[derive(Deserialize, Debug)]
pub struct Metadata {
/// Deprecated.
#[serde(default)]
pub depends: Vec<String>,
/// Deprecated.
#[serde(default)]
pub optdepends: Vec<String>,
/// > [package.metadata.aur]
pub aur: Option<AUR>,
}
impl std::fmt::Display for Metadata {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Reconcile which section to read extra dependency information from.
// The format we hope the user is using is:
//
// > [package.metadata.aur]
//
// But version 1.5 originally supported:
//
// > [package.metadata]
//
// To avoid a sudden breakage for users, we support both definition
// locations but favour the newer one.
//
// We print a warning to the user elsewhere if they're still using the
// old way.
let (deps, opts) = if let Some(aur) = self.aur.as_ref() {
(aur.depends.as_slice(), aur.optdepends.as_slice())
} else {
(self.depends.as_slice(), self.optdepends.as_slice())
};
match deps {
[middle @ .., last] => {
write!(f, "depends=(")?;
for item in middle {
write!(f, "\"{}\" ", item)?;
}
if opts.is_empty().not() {
writeln!(f, "\"{}\")", last)?;
} else {
write!(f, "\"{}\")", last)?;
}
}
[] => {}
}
match opts {
[middle @ .., last] => {
write!(f, "optdepends=(")?;
for item in middle {
write!(f, "\"{}\" ", item)?;
}
write!(f, "\"{}\")", last)?;
}
[] => {}
}
Ok(())
}
}
#[derive(Deserialize, Debug)]
pub struct AUR {
#[serde(default)]
depends: Vec<String>,
#[serde(default)]
optdepends: Vec<String>,
}

View File

@@ -1,6 +1,7 @@
mod error;
use crate::error::Error;
use cargo_aur::{GitHost, Package};
use colored::*;
use gumdrop::{Options, ParsingStyle};
use hmac_sha256::Hash;
@@ -39,8 +40,7 @@ struct Args {
help: bool,
/// Display the current version of this software.
version: bool,
/// Set custom output directory
/// Set a custom output directory (default: target/).
output: Option<PathBuf>,
/// Unused.
#[options(free)]
@@ -51,26 +51,6 @@ struct Args {
dryrun: bool,
}
enum GitHost {
Github,
Gitlab,
}
impl GitHost {
fn source(&self, package: &Package) -> String {
match self {
GitHost::Github => format!(
"{}/releases/download/v$pkgver/{}-$pkgver-x86_64.tar.gz",
package.repository, package.name
),
GitHost::Gitlab => format!(
"{}/-/archive/v$pkgver/{}-$pkgver-x86_64.tar.gz",
package.repository, package.name
),
}
}
}
#[derive(Deserialize, Debug)]
struct Config {
package: Package,
@@ -88,114 +68,11 @@ impl Config {
}
}
#[derive(Deserialize, Debug)]
struct Package {
name: String,
version: String,
authors: Vec<String>,
description: String,
homepage: String,
repository: String,
license: String,
metadata: Option<Metadata>,
}
#[derive(Deserialize, Debug)]
struct Metadata {
/// Deprecated.
#[serde(default)]
depends: Vec<String>,
/// Deprecated.
#[serde(default)]
optdepends: Vec<String>,
/// > [package.metadata.aur]
aur: Option<AUR>,
}
#[derive(Deserialize, Debug)]
struct AUR {
#[serde(default)]
depends: Vec<String>,
#[serde(default)]
optdepends: Vec<String>,
}
impl std::fmt::Display for Metadata {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Reconcile which section to read extra dependency information from.
// The format we hope the user is using is:
//
// > [package.metadata.aur]
//
// But version 1.5 originally supported:
//
// > [package.metadata]
//
// To avoid a sudden breakage for users, we support both definition
// locations but favour the newer one.
//
// We print a warning to the user elsewhere if they're still using the
// old way.
let (deps, opts) = if let Some(aur) = self.aur.as_ref() {
(aur.depends.as_slice(), aur.optdepends.as_slice())
} else {
(self.depends.as_slice(), self.optdepends.as_slice())
};
match deps {
[middle @ .., last] => {
write!(f, "depends=(")?;
for item in middle {
write!(f, "\"{}\" ", item)?;
}
if opts.is_empty().not() {
writeln!(f, "\"{}\")", last)?;
} else {
write!(f, "\"{}\")", last)?;
}
}
[] => {}
}
match opts {
[middle @ .., last] => {
write!(f, "optdepends=(")?;
for item in middle {
write!(f, "\"{}\" ", item)?;
}
write!(f, "\"{}\")", last)?;
}
[] => {}
}
Ok(())
}
}
#[derive(Deserialize, Debug)]
struct Binary {
name: String,
}
impl Package {
/// The name of the tarball that should be produced from this `Package`.
fn tarball(&self, output: &PathBuf) -> String {
let mut output = output.clone();
output.push(format!("{}-{}-x86_64.tar.gz", self.name, self.version));
output.to_str().unwrap().to_string()
}
fn git_host(&self) -> Option<GitHost> {
if self.repository.starts_with("https://github") {
Some(GitHost::Github)
} else if self.repository.starts_with("https://gitlab") {
Some(GitHost::Gitlab)
} else {
None
}
}
}
fn main() -> ExitCode {
let args = Args::parse_args_or_exit(ParsingStyle::AllOptions);