pub mod version;
pub mod publisher;
pub mod compare;
pub mod fmri_list;
mod helpers;
#[cfg(test)]
mod tests;
use std::{
cmp::Ordering,
fmt::{Debug, Display, Formatter}
};
use serde::{Deserialize, Serialize};
use crate::helpers::{check_character_collision, remove_first_and_last_characters};
pub use self::{
compare::Compare,
version::Version,
publisher::Publisher,
fmri_list::FMRIList
};
#[derive(PartialEq, Serialize, Deserialize, Clone, Ord, Eq, PartialOrd)]
pub struct FMRI {
publisher: Option<Publisher>,
package_name: String,
version: Option<Version>,
}
impl FMRI {
pub fn new_from_package_name(mut package_name: String) -> Self {
if package_name.is_empty() {
panic!("package name can't be empty")
}
check_character_collision(&package_name);
package_name = remove_first_and_last_characters(&package_name, '/').to_owned();
Self {
publisher: None,
package_name,
version: None,
}
}
pub fn parse_raw(raw_fmri: &String) -> Self {
let mut publisher: Option<Publisher> = None;
let mut version: Option<Version> = None;
let mut package_name: String = raw_fmri.clone().trim_start_matches("fmri=").to_owned();
match Publisher::parse_publisher_from_raw_fmri(raw_fmri.clone()) {
None => {
package_name = package_name.trim_start_matches("pkg:/").to_owned();
}
Some(p) => {
publisher = Some(p);
let (_, end_str) = package_name.trim_start_matches("pkg://").split_once("/").expect("Fmri must contain \"/package_name\"");
package_name = end_str.to_owned()
}
}
match Version::parse_version_from_raw_fmri(raw_fmri.clone()) {
None => {}
Some(v) => {
version = Some(v);
let (start_str, _) = package_name.split_once("@").expect("error");
package_name = start_str.to_owned()
}
}
let mut fmri = Self::new_from_package_name(package_name);
if let Some(p) = publisher {
fmri.change_publisher(p);
}
if let Some(v) = version {
fmri.change_version(v);
}
fmri
}
pub fn package_name_eq(&self, comparing_to: &FMRI) -> bool {
if self.get_package_name_as_ref_string() == comparing_to.get_package_name_as_ref_string() {
return true;
}
false
}
pub fn package_name_ne(&self, comparing_to: &FMRI) -> bool {
if self.get_package_name_as_ref_string() != comparing_to.get_package_name_as_ref_string() {
return true;
}
false
}
pub fn get_package_name_as_string(self) -> String {
self.package_name
}
pub fn get_package_name_as_ref_string(&self) -> &String {
&self.package_name
}
pub fn get_package_name_as_ref_mut_string(&mut self) -> &mut String {
&mut self.package_name
}
pub fn get_publisher(self) -> Option<Publisher> {
self.publisher
}
pub fn get_publisher_ref(&self) -> &Option<Publisher> {
&self.publisher
}
pub fn get_publisher_ref_mut(&mut self) -> &mut Option<Publisher> {
&mut self.publisher
}
pub fn has_publisher(&self) -> bool {
if self.publisher == None {
return false;
}
true
}
pub fn change_publisher(&mut self, publisher: Publisher) {
self.publisher = Some(publisher);
}
pub fn get_publisher_as_ref_string(&self) -> Option<&String> {
if let Some(publisher) = &self.publisher {
return Some(publisher.get_as_ref_string());
}
None
}
pub fn remove_publisher(&mut self) {
self.publisher = None
}
pub fn get_version(self) -> Option<Version> {
self.version
}
pub fn get_version_ref(&self) -> &Option<Version> {
&self.version
}
pub fn get_version_ref_mut(&mut self) -> &mut Option<Version> {
&mut self.version
}
pub fn has_version(&self) -> bool {
if self.version == None {
return false;
}
true
}
pub fn change_version(&mut self, version: Version) {
self.version = Some(version)
}
pub fn get_version_as_string(&self) -> Option<String> {
if let Some(version) = &self.version {
return Some(format!("{}", version));
}
None
}
pub fn remove_version(&mut self) -> &mut FMRI {
self.version = None;
self
}
}
impl Compare for FMRI {
fn compare(&self, comparing_to: &Self) -> Ordering {
if self.package_name_ne(comparing_to) {
panic!("comparing FMRIs doesn't have same package names")
}
if !self.has_version() || !comparing_to.has_version() {
return Ordering::Equal;
}
self
.version
.as_ref()
.unwrap()
.compare(&comparing_to.version.as_ref().unwrap())
}
}
impl Display for FMRI {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut string: String = "".to_owned();
if self.has_publisher() {
string.push_str("pkg://");
string.push_str(self.get_publisher_as_ref_string().unwrap());
string.push_str("/");
} else {
string.push_str("pkg:/");
}
string.push_str(self.get_package_name_as_ref_string());
if self.has_version() {
string.push_str(&self.get_version_as_string().unwrap());
}
write!(f, "{}", string)
}
}
impl Debug for FMRI {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", format!("{}", self))
}
}