Moved hpk-package all the way back into tree, fixed some clippy lints

This commit is contained in:
Nathan Fisher 2023-04-16 10:36:43 -04:00
parent b1fcbd1f9f
commit 1e7a02e33d
30 changed files with 171 additions and 185 deletions

24
Cargo.lock generated
View File

@ -543,34 +543,22 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]] [[package]]
name = "hpk" name = "hpk"
version = "0.1.0" version = "0.1.0"
dependencies = [
"clap",
"hpk-package",
"indicatif",
"package-bootstrap",
"rayon",
"ron",
"serde",
"ureq",
"url",
"walkdir",
"zstd",
]
[[package]]
name = "hpk-package"
version = "0.1.0"
source = "git+https://git.hitchhiker-linux.org/jeang3nie/hpk-package.git#e6f392bd7a91ffe3f0b080627e915ea458eade5a"
dependencies = [ dependencies = [
"chrono", "chrono",
"clap",
"deku", "deku",
"indicatif",
"libc", "libc",
"package-bootstrap",
"rayon", "rayon",
"ron", "ron",
"serde", "serde",
"sha2", "sha2",
"thiserror", "thiserror",
"ureq",
"url",
"walkdir", "walkdir",
"zstd",
] ]
[[package]] [[package]]

View File

@ -21,12 +21,19 @@ path = "src/bootstrap.rs"
required-features = ["bootstrap"] required-features = ["bootstrap"]
[dependencies] [dependencies]
hpk-package = { git = "https://git.hitchhiker-linux.org/jeang3nie/hpk-package.git" } deku = "0.16"
libc = "0.2"
rayon = "1.7" rayon = "1.7"
ron = "0.8" ron = "0.8"
sha2 = "0.10"
thiserror = "1.0"
walkdir = "2.3" walkdir = "2.3"
zstd = "0.12" zstd = "0.12"
[dependencies.chrono]
version = "0.4"
features = ["serde"]
[dependencies.clap] [dependencies.clap]
version = "4.2" version = "4.2"
optional = true optional = true

View File

@ -1,3 +0,0 @@
/target
/Cargo.lock
tags

View File

@ -1,29 +0,0 @@
[package]
name = "hpk-package"
version = "0.1.0"
edition = "2021"
license = "GPL-3.0-only"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
deku = "0.16"
rayon = "1.7"
ron = "0.8"
sha2 = "0.10"
walkdir = "2.3"
thiserror = "1.0"
libc = "0.2"
[dependencies.chrono]
version = "0.4"
features = ["serde"]
[dependencies.serde]
version = "1.0"
features = ["derive"]
[profile.release]
codegen-units = 1
lto = true
strip = true

View File

@ -1,12 +0,0 @@
mod package;
mod plist;
pub mod tar;
mod version;
pub use {
deku,
package::{Arch, Dependency, Group, Package, Specs, User},
plist::*,
ron, sha2,
version::*,
};

View File

@ -1,6 +1,6 @@
use { use {
crate::{Item, ItemError, Package, Plist, Specs}, crate::{tar, Entry, Item, ItemError, Package, Plist, Specs},
hpk_package::{deku::DekuError, tar, Entry}, deku::DekuError,
rayon::prelude::{IntoParallelRefIterator, ParallelIterator}, rayon::prelude::{IntoParallelRefIterator, ParallelIterator},
std::{ std::{
borrow::BorrowMut, borrow::BorrowMut,

View File

@ -1,7 +1,7 @@
use { use {
crate::{Arch, Package, Repository, Version}, crate::{Arch, Package, Repository, Version},
hpk_package::ron::{self, ser::PrettyConfig},
rayon::prelude::*, rayon::prelude::*,
ron::{self, ser::PrettyConfig},
serde::{Deserialize, Serialize}, serde::{Deserialize, Serialize},
std::{ std::{
collections::HashMap, collections::HashMap,

View File

@ -1,7 +1,5 @@
use hpk_package::{Group, User};
use { use {
crate::InstallError, crate::{Group, InstallError, User},
std::{ std::{
path::PathBuf, path::PathBuf,
process::{Command, Output}, process::{Command, Output},

View File

@ -1,4 +1,5 @@
#![warn(clippy::all, clippy::pedantic)] #![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::missing_errors_doc)]
mod cli; mod cli;
use { use {
clap::ArgMatches, clap::ArgMatches,

View File

@ -2,13 +2,12 @@
pub use error::InstallError; pub use error::InstallError;
use { use {
crate::{Hooks, Pinstall}, crate::{
hpk_package::{
sha2::{Digest, Sha256},
tar::{Archive, Node}, tar::{Archive, Node},
Entry, Group, Package, User, Entry, Group, Hooks, Package, Pinstall, User,
}, },
rayon::prelude::{IntoParallelRefIterator, ParallelIterator}, rayon::prelude::{IntoParallelRefIterator, ParallelIterator},
sha2::{Digest, Sha256},
std::{ std::{
ffi::OsStr, ffi::OsStr,
fmt::Write as _, fmt::Write as _,
@ -102,60 +101,63 @@ impl<T: io::Read> Installer<T> {
let package = &self.package; let package = &self.package;
let hooks = Mutex::new(hooks); let hooks = Mutex::new(hooks);
let s = sender.clone(); let s = sender.clone();
archive.nodes.par_iter().try_for_each_with(s, |sender, node| { archive
let mut path = path.clone(); .nodes
let fpath = node.header.file_path()?; .par_iter()
if let Some(s) = node.header.prefix() { .try_for_each_with(s, |sender, node| {
if s.contains("/share/man/") { let mut path = path.clone();
let mut h = hooks.lock().unwrap(); let fpath = node.header.file_path()?;
if !h.contains(&Hooks::Man) { if let Some(s) = node.header.prefix() {
h.push(Hooks::Man); if s.contains("/share/man/") {
} let mut h = hooks.lock().unwrap();
} else if s.contains("/share/info") { if !h.contains(&Hooks::Man) {
hooks h.push(Hooks::Man);
.lock() }
.unwrap() } else if s.contains("/share/info") {
.push(Hooks::Info(fpath.to_str().unwrap().to_string())) hooks
} else if s.contains("/share/glib-2.0/schemas") { .lock()
let mut h = hooks.lock().unwrap(); .unwrap()
if !h.contains(&Hooks::GlibSchema) { .push(Hooks::Info(fpath.to_str().unwrap().to_string()))
h.push(Hooks::GlibSchema); } else if s.contains("/share/glib-2.0/schemas") {
let mut h = hooks.lock().unwrap();
if !h.contains(&Hooks::GlibSchema) {
h.push(Hooks::GlibSchema);
}
} }
} }
} // Match up a package entry with a tar node
// Match up a package entry with a tar node let entry = package
let entry = package .plist
.plist .entries
.entries .iter()
.iter() .find(|&x| match x {
.find(|&x| match x { Entry::File {
Entry::File { path,
path, sha256sum: _,
sha256sum: _, mode: _,
mode: _, size: _,
size: _, } => path == &fpath,
} => path == &fpath, Entry::Link { path, target: _ } => path == &fpath,
Entry::Link { path, target: _ } => path == &fpath, Entry::Directory { path, mode: _ } => path == &fpath,
Entry::Directory { path, mode: _ } => path == &fpath, })
}) .unwrap();
.unwrap(); path = path.join(&fpath);
path = path.join(&fpath); if let Some(parent) = path.parent() {
if let Some(parent) = path.parent() { if !parent.exists() {
if !parent.exists() { fs::create_dir_all(&parent)?;
fs::create_dir_all(&parent)?; }
} }
} if path.exists() {
if path.exists() { if path.is_dir() {
if path.is_dir() { fs::remove_dir(&path)?;
fs::remove_dir(&path)?; } else if path.is_symlink() || path.is_file() {
} else if path.is_symlink() || path.is_file() { fs::remove_file(&path)?;
fs::remove_file(&path)?; }
} }
} let msg = extract_entry(entry, node, path)?;
let msg = extract_entry(entry, node, path)?; sender.send(msg)?;
sender.send(msg)?; Ok::<(), InstallError>(())
Ok::<(), InstallError>(()) })?;
})?;
Ok(hooks.into_inner()?) Ok(hooks.into_inner()?)
} }
@ -252,8 +254,8 @@ fn pop_pinstall(
} }
mod error { mod error {
use crate::Hooks; use super::InstallMessage;
use hpk_package::tar; use crate::{tar, Hooks};
use std::{ use std::{
error::Error, error::Error,
fmt, io, fmt, io,
@ -263,7 +265,6 @@ mod error {
PoisonError, PoisonError,
}, },
}; };
use super::InstallMessage;
#[derive(Debug)] #[derive(Debug)]
pub enum InstallError { pub enum InstallError {
@ -331,8 +332,8 @@ mod error {
} }
} }
impl From<hpk_package::tar::Error> for InstallError { impl From<crate::tar::Error> for InstallError {
fn from(value: hpk_package::tar::Error) -> Self { fn from(value: crate::tar::Error) -> Self {
Self::Tar(value) Self::Tar(value)
} }
} }

View File

@ -1,17 +1,19 @@
use hpk_package::{ use {
crate::{
tar::{Error as TarError, Node, Owner},
Entry,
},
deku::DekuError, deku::DekuError,
sha2::{Digest, Sha256}, sha2::{Digest, Sha256},
tar::{Error as TarError, Node, Owner}, std::{
Entry, error::Error,
}; ffi::OsStr,
use std::{ fmt::{self, Write},
error::Error, fs,
ffi::OsStr, io::{self, Read},
fmt::{self, Write}, os::unix::fs::MetadataExt,
fs, path::{Path, PathBuf},
io::{self, Read}, },
os::unix::fs::MetadataExt,
path::{Path, PathBuf},
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View File

@ -1,10 +1,15 @@
#![warn(clippy::all, clippy::pedantic)] #![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::must_use_candidate, clippy::missing_errors_doc)]
mod creator; mod creator;
mod db; mod db;
mod hooks; mod hooks;
mod installer; mod installer;
mod item; mod item;
mod package;
mod plist;
mod repository; mod repository;
pub mod tar;
mod version;
use std::path::PathBuf; use std::path::PathBuf;
@ -12,10 +17,12 @@ pub use {
creator::{CreationError, Creator, Message}, creator::{CreationError, Creator, Message},
db::Database, db::Database,
hooks::{Hooks, Pinstall}, hooks::{Hooks, Pinstall},
hpk_package::{tar, Arch, Dependency, GitRev, Package, Plist, Rapid, SemVer, Specs, Version},
installer::{InstallError, InstallMessage, Installer}, installer::{InstallError, InstallMessage, Installer},
item::{Item, ItemError}, item::{Item, ItemError},
package::{Arch, Dependency, Group, Package, Specs, User},
plist::{Entry, Plist},
repository::Repository, repository::Repository,
version::{GitRev, Rapid, SemVer, Version},
}; };
const DB: [&str; 4] = ["var", "db", "hpk", "db.ron.zstd"]; const DB: [&str; 4] = ["var", "db", "hpk", "db.ron.zstd"];

View File

@ -1,6 +1,5 @@
use { use {
crate::Package, crate::Package,
hpk_package::ron,
rayon::prelude::*, rayon::prelude::*,
serde::{Deserialize, Serialize}, serde::{Deserialize, Serialize},
std::{ std::{

View File

@ -2,7 +2,7 @@ use crate::tar::Error;
use deku::prelude::*; use deku::prelude::*;
use std::{ use std::{
env, env,
ffi::CStr, ffi::{CStr, OsStr},
fmt::{self, Write}, fmt::{self, Write},
fs::{self, Metadata}, fs::{self, Metadata},
io, io,
@ -39,8 +39,6 @@ where
return FileType::Char; return FileType::Char;
} else if file_type.is_block_device() { } else if file_type.is_block_device() {
return FileType::Block; return FileType::Block;
} else if file_type.is_fifo() {
return FileType::FIFO;
} else if file_type.is_symlink() { } else if file_type.is_symlink() {
return FileType::Symlink; return FileType::Symlink;
} else if file_type.is_file() { } else if file_type.is_file() {
@ -122,7 +120,7 @@ impl Header {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Header; /// use hpk::tar::Header;
/// ///
/// let header = Header::new("test/1.txt").unwrap(); /// let header = Header::new("test/1.txt").unwrap();
/// let filename = header.filename().unwrap(); /// let filename = header.filename().unwrap();
@ -144,7 +142,7 @@ impl Header {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use hpk_package::tar::Header; /// use hpk::tar::Header;
/// ///
/// let header = Header::new("test/1.txt").unwrap(); /// let header = Header::new("test/1.txt").unwrap();
/// let mode = header.mode().unwrap(); /// let mode = header.mode().unwrap();
@ -230,7 +228,7 @@ impl Header {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use hpk_package::tar::Header; /// use hpk::tar::Header;
/// ///
/// let header = Header::new("test/1.txt").unwrap(); /// let header = Header::new("test/1.txt").unwrap();
/// let prefix = header.prefix().unwrap(); /// let prefix = header.prefix().unwrap();
@ -239,10 +237,10 @@ impl Header {
pub fn prefix(&self) -> Option<String> { pub fn prefix(&self) -> Option<String> {
let mut s = String::new(); let mut s = String::new();
for c in self.file_prefix { for c in self.file_prefix {
if c != 0 { if c == 0 {
write!(s, "{}", char::from(c)).ok()?;
} else {
break; break;
} else {
write!(s, "{}", char::from(c)).ok()?;
} }
} }
if s.is_empty() { if s.is_empty() {
@ -257,7 +255,7 @@ impl Header {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Header; /// use hpk::tar::Header;
/// use std::path::PathBuf; /// use std::path::PathBuf;
/// ///
/// let header = Header::new("test/1.txt").unwrap(); /// let header = Header::new("test/1.txt").unwrap();
@ -274,6 +272,7 @@ impl Header {
Ok(path) Ok(path)
} }
#[allow(clippy::missing_panics_doc)]
pub fn new(filename: &str) -> Result<Self, Error> { pub fn new(filename: &str) -> Result<Self, Error> {
let mut header = Header::default(); let mut header = Header::default();
let meta = fs::symlink_metadata(filename)?; let meta = fs::symlink_metadata(filename)?;
@ -282,7 +281,7 @@ impl Header {
// revision allows storing the path prefix separately, with 100 bytes // revision allows storing the path prefix separately, with 100 bytes
// reserved for the file name and 150 bytes for the rest of the path. // reserved for the file name and 150 bytes for the rest of the path.
let path = PathBuf::from(&filename); let path = PathBuf::from(&filename);
let name = match path.file_name().and_then(|n| n.to_str()) { let name = match path.file_name().and_then(OsStr::to_str) {
Some(n) => n.to_string(), Some(n) => n.to_string(),
None => { None => {
return Err(Error::Io(io::Error::new( return Err(Error::Io(io::Error::new(
@ -326,7 +325,7 @@ impl Header {
/* TODO: Find better way to get username */ /* TODO: Find better way to get username */
let key = "USER"; let key = "USER";
if let Ok(val) = env::var(key) { if let Ok(val) = env::var(key) {
header.username[..val.len()].copy_from_slice(val.as_bytes()) header.username[..val.len()].copy_from_slice(val.as_bytes());
} }
/* TODO: Find way to get groupname */ /* TODO: Find way to get groupname */
@ -336,6 +335,7 @@ impl Header {
Ok(header) Ok(header)
} }
#[allow(clippy::missing_panics_doc)]
pub fn new_from_meta( pub fn new_from_meta(
filename: &str, filename: &str,
meta: &Metadata, meta: &Metadata,
@ -347,7 +347,7 @@ impl Header {
// revision allows storing the path prefix separately, with 100 bytes // revision allows storing the path prefix separately, with 100 bytes
// reserved for the file name and 150 bytes for the rest of the path. // reserved for the file name and 150 bytes for the rest of the path.
let path = PathBuf::from(&filename); let path = PathBuf::from(&filename);
let name = match path.file_name().and_then(|n| n.to_str()) { let name = match path.file_name().and_then(OsStr::to_str) {
Some(n) => n.to_string(), Some(n) => n.to_string(),
None => { None => {
return Err(Error::Io(io::Error::new( return Err(Error::Io(io::Error::new(
@ -403,7 +403,7 @@ impl Header {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Header; /// use hpk::tar::Header;
/// let header = Header::default(); /// let header = Header::default();
/// if !header.validate_magic() { /// if !header.validate_magic() {
/// println!("Magic value is invalid"); /// println!("Magic value is invalid");
@ -418,7 +418,7 @@ impl Header {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Header; /// use hpk::tar::Header;
/// let header = Header::default(); /// let header = Header::default();
/// if header.validate_checksum().unwrap() { /// if header.validate_checksum().unwrap() {
/// println!("Checksum is valid"); /// println!("Checksum is valid");
@ -440,7 +440,7 @@ impl Header {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Header; /// use hpk::tar::Header;
/// let mut header = Header::default(); /// let mut header = Header::default();
/// ///
/// /* Fill in header information */ /// /* Fill in header information */

View File

@ -4,7 +4,7 @@ use std::{
path::PathBuf, path::PathBuf,
}; };
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator, IndexedParallelIterator}; use rayon::prelude::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
mod error; mod error;
mod header; mod header;
@ -37,7 +37,7 @@ impl Archive {
/// ///
/// ``` /// ```
/// use std::fs::File; /// use std::fs::File;
/// use hpk_package::tar::Archive; /// use hpk::tar::Archive;
/// ///
/// let data = Archive::new("test/1.txt").unwrap(); /// let data = Archive::new("test/1.txt").unwrap();
/// ///
@ -65,7 +65,7 @@ impl Archive {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Archive; /// use hpk::tar::Archive;
/// ///
/// let data = Archive::new("test/1.txt").unwrap(); /// let data = Archive::new("test/1.txt").unwrap();
/// ``` /// ```
@ -81,7 +81,7 @@ impl Archive {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Archive; /// use hpk::tar::Archive;
/// ///
/// let mut data = Archive::new("test/1.txt").unwrap(); /// let mut data = Archive::new("test/1.txt").unwrap();
/// data.append("test/1.txt").unwrap(); /// data.append("test/1.txt").unwrap();
@ -98,7 +98,7 @@ impl Archive {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Archive; /// use hpk::tar::Archive;
/// ///
/// Archive::open("test/1.tar").unwrap(); /// Archive::open("test/1.tar").unwrap();
/// ``` /// ```
@ -113,7 +113,7 @@ impl Archive {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Archive; /// use hpk::tar::Archive;
/// use std::{fs::File, io::BufReader}; /// use std::{fs::File, io::BufReader};
/// ///
/// let file = File::open("test/1.tar").unwrap(); /// let file = File::open("test/1.tar").unwrap();
@ -135,7 +135,7 @@ impl Archive {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Archive; /// use hpk::tar::Archive;
/// ///
/// let mut data = Archive::new("test/1.tar").unwrap(); /// let mut data = Archive::new("test/1.tar").unwrap();
/// data.remove("test/1.tar").unwrap(); /// data.remove("test/1.tar").unwrap();
@ -143,7 +143,11 @@ impl Archive {
pub fn remove(&mut self, filename: &str) -> Result<bool, Error> { pub fn remove(&mut self, filename: &str) -> Result<bool, Error> {
let mut name = [0u8; 100]; let mut name = [0u8; 100];
name[..filename.len()].copy_from_slice(filename.as_bytes()); name[..filename.len()].copy_from_slice(filename.as_bytes());
if let Some(i) = &self.nodes.par_iter().position_any(|x| x.header.fname == name) { if let Some(i) = &self
.nodes
.par_iter()
.position_any(|x| x.header.fname == name)
{
self.nodes.remove(*i); self.nodes.remove(*i);
return Ok(true); return Ok(true);
} }
@ -156,21 +160,24 @@ impl Archive {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use hpk_package::tar::Archive; /// use hpk::tar::Archive;
/// let archive = Archive::new("test/1.txt").unwrap(); /// let archive = Archive::new("test/1.txt").unwrap();
/// let node = archive.get("test/1.txt"); /// let node = archive.get("test/1.txt");
/// assert!(node.is_some()); /// assert!(node.is_some());
/// ``` /// ```
pub fn get(&self, filename: &str) -> Option<Node> { pub fn get(&self, filename: &str) -> Option<Node> {
self.nodes.par_iter().find_any(|x| { self.nodes
x.header.file_path() == Ok(PathBuf::from(filename)) .par_iter()
}).cloned() .find_any(|x| x.header.file_path() == Ok(PathBuf::from(filename)))
.cloned()
} }
pub fn pop(&mut self, filename: &str) -> Option<Node> { pub fn pop(&mut self, filename: &str) -> Option<Node> {
if let Some(i) = self.nodes.par_iter().position_any(|x| { if let Some(i) = self
x.header.file_path() == Ok(PathBuf::from(filename)) .nodes
}) { .par_iter()
.position_any(|x| x.header.file_path() == Ok(PathBuf::from(filename)))
{
let node = self.nodes.get(i).cloned(); let node = self.nodes.get(i).cloned();
self.nodes.remove(i); self.nodes.remove(i);
return node; return node;

View File

@ -34,7 +34,7 @@ impl Node {
Ok(written) Ok(written)
} }
/// Read a TarNode in from a file or something with a ``std::io::Read`` trait. /// Read a `Node` in from a file or something with a ``std::io::Read`` trait.
pub fn read<T: io::Read>(mut input: T) -> Result<Self, Error> { pub fn read<T: io::Read>(mut input: T) -> Result<Self, Error> {
let mut h = vec![0u8; 512]; let mut h = vec![0u8; 512];
input.read_exact(&mut h)?; input.read_exact(&mut h)?;
@ -57,7 +57,7 @@ impl Node {
}) })
} }
/// Open and read a file from the ``filename`` argument to a TarNode. /// Open and read a file from the ``filename`` argument to a `Node`.
pub fn read_file_to_tar(filename: &str) -> Result<Self, Error> { pub fn read_file_to_tar(filename: &str) -> Result<Self, Error> {
let header = Header::new(filename)?; let header = Header::new(filename)?;
if header.link_indicator[0] != FileType::Normal as u8 { if header.link_indicator[0] != FileType::Normal as u8 {

View File

@ -11,9 +11,9 @@ pub use {gitrev::GitRev, rapid::Rapid, semver::SemVer};
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
/// An enum representing the most common versioning schemes. /// An enum representing the most common versioning schemes.
/// Each scheme must implement Eq and Ord with itself, and /// Each scheme must implement `Eq` and `Ord` with itself, and
/// may optionally implement PartialEq and PartialOrd with /// may optionally implement `PartialEq` and `PartialOrd` with
/// other schemes. Number, Rapid, and SemVer do this, while /// other schemes. `Number`, `Rapid`, and `SemVer` do this, while
/// Git can only compare with itself. /// Git can only compare with itself.
pub enum Version { pub enum Version {
/// A single replease number, as in Firefox 102 /// A single replease number, as in Firefox 102

View File

@ -168,27 +168,47 @@ mod test {
#[test] #[test]
fn rapid_num_eq() { fn rapid_num_eq() {
let rapid = Rapid { major: 42, minor: 0 }; let rapid = Rapid {
major: 42,
minor: 0,
};
assert_eq!(rapid, 42); assert_eq!(rapid, 42);
} }
#[test] #[test]
fn rapid_num_gt() { fn rapid_num_gt() {
let rapid = Rapid { major: 1, minor: 42 }; let rapid = Rapid {
major: 1,
minor: 42,
};
assert!(rapid > 1); assert!(rapid > 1);
} }
#[test] #[test]
fn rapid_semver_eq() { fn rapid_semver_eq() {
let rapid = Rapid { major: 42, minor: 69 }; let rapid = Rapid {
let semver = SemVer { major: 42, minor: 69, patch: 0 }; major: 42,
minor: 69,
};
let semver = SemVer {
major: 42,
minor: 69,
patch: 0,
};
assert_eq!(rapid, semver); assert_eq!(rapid, semver);
} }
#[test] #[test]
fn rapid_semver_lt() { fn rapid_semver_lt() {
let rapid = Rapid { major: 42, minor: 69 }; let rapid = Rapid {
let semver = SemVer { major: 42, minor: 69, patch: 1 }; major: 42,
minor: 69,
};
let semver = SemVer {
major: 42,
minor: 69,
patch: 1,
};
assert!(rapid < semver); assert!(rapid < semver);
} }
} }