use crate::version::GoVersion;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Release {
pub version: String,
pub stable: bool,
pub files: Vec<ReleaseFile>,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
#[allow(dead_code)]
pub struct ReleaseFile {
pub filename: String,
pub os: String,
pub arch: String,
pub sha256: String,
pub size: u64,
pub kind: String,
}
impl Release {
pub fn go_version(&self) -> Option<GoVersion> {
GoVersion::parse(&self.version).ok()
}
pub fn archive_for(&self, os: &str, arch: &str) -> Option<&ReleaseFile> {
self.files
.iter()
.find(|f| f.os == os && f.arch == arch && f.kind == "archive")
}
pub fn source_file(&self) -> Option<&ReleaseFile> {
self.files.iter().find(|f| f.kind == "source")
}
}
#[cfg(test)]
mod tests {
use super::*;
fn release() -> Release {
Release {
version: "go1.22.4".to_string(),
stable: true,
files: vec![
ReleaseFile {
filename: "go1.22.4.linux-amd64.tar.gz".to_string(),
os: "linux".to_string(),
arch: "amd64".to_string(),
sha256: "abc123".to_string(),
size: 100,
kind: "archive".to_string(),
},
ReleaseFile {
filename: "go1.22.4.windows-amd64.zip".to_string(),
os: "windows".to_string(),
arch: "amd64".to_string(),
sha256: "def456".to_string(),
size: 200,
kind: "archive".to_string(),
},
ReleaseFile {
filename: "go1.22.4.src.tar.gz".to_string(),
os: String::new(),
arch: String::new(),
sha256: "ghi789".to_string(),
size: 300,
kind: "source".to_string(),
},
ReleaseFile {
filename: "go1.22.4.linux-amd64.msi".to_string(),
os: "linux".to_string(),
arch: "amd64".to_string(),
sha256: "jkl012".to_string(),
size: 400,
kind: "installer".to_string(),
},
],
}
}
#[test]
fn go_version_parses_the_version_field() {
let r = release();
let v = r.go_version().unwrap();
assert_eq!(v.tag(), "go1.22.4");
}
#[test]
fn go_version_returns_none_for_unparsable_version() {
let mut r = release();
r.version = "go1.22.4rc1-weird".to_string();
assert!(r.go_version().is_none());
}
#[test]
fn archive_for_finds_matching_os_and_arch() {
let r = release();
let file = r.archive_for("linux", "amd64").unwrap();
assert_eq!(file.filename, "go1.22.4.linux-amd64.tar.gz");
}
#[test]
fn archive_for_ignores_non_archive_kind() {
let r = release();
let file = r.archive_for("linux", "amd64").unwrap();
assert_eq!(file.kind, "archive");
}
#[test]
fn archive_for_returns_none_when_no_match() {
let r = release();
assert!(r.archive_for("plan9", "amd64").is_none());
}
#[test]
fn source_file_finds_the_source_kind() {
let r = release();
let file = r.source_file().unwrap();
assert_eq!(file.filename, "go1.22.4.src.tar.gz");
}
#[test]
fn source_file_returns_none_when_absent() {
let mut r = release();
r.files.retain(|f| f.kind != "source");
assert!(r.source_file().is_none());
}
}