use crate::tao::form::Crate;
use crate::tao::perspective::{BuildInfo, BuildInfoExtension};
use crate::tao::relation::attribute::{SupportsMembership, Version};
use std::convert::TryFrom;
use std::rc::Rc;
use zamm_yin::node_wrappers::{BaseNodeTrait, CommonNodeTrait};
use zamm_yin::tao::archetype::{ArchetypeFormTrait, ArchetypeTrait};
use zamm_yin::tao::form::data::StringConcept;
use zamm_yin::tao::form::FormTrait;
use zamm_yin::Wrapper;
pub trait CrateExtension: FormTrait + CommonNodeTrait + SupportsMembership {
fn set_implementation_name(&mut self, name: &str) {
BuildInfo::from(self.id()).set_implementation_name(name);
}
fn implementation_name(&self) -> Option<Rc<str>> {
BuildInfo::from(self.id()).implementation_name()
}
fn lookup(name: &str) -> Option<Crate> {
Crate::archetype()
.individuals()
.iter()
.map(|i| Crate::from(i.id()))
.find(|c| {
let crate_name = c.implementation_name();
crate_name.is_some() && &*crate_name.unwrap() == name
})
}
fn set_version(&mut self, version: &str) {
let mut version_string = StringConcept::new();
version_string.set_value(version.to_owned());
self.essence_mut()
.add_outgoing(Version::TYPE_ID, version_string.essence());
}
fn version(&self) -> Option<Rc<str>> {
self.essence()
.outgoing_nodes(Version::TYPE_ID)
.last()
.map(|f| Rc::from(StringConcept::from(*f).value().unwrap().as_str()))
}
fn version_at_least(&self, major: u64, minor: u64, patch: u64) -> bool {
match self.version() {
None => false,
Some(actual_version) => {
semver::Version::parse(&*actual_version).unwrap()
>= semver::Version::from((major, minor, patch))
}
}
}
const YIN_CRATE_NAME: &'static str = "zamm_yin";
const YANG_CRATE_NAME: &'static str = "zamm_yang";
const CURRENT_CRATE_INTERNAL_NAME: &'static str = "DUMMY-crate";
fn yin() -> Crate {
Crate::lookup(Self::YIN_CRATE_NAME).unwrap()
}
fn yang() -> Crate {
Crate::lookup(Self::YANG_CRATE_NAME).unwrap()
}
fn current() -> Crate {
Crate::try_from(Self::CURRENT_CRATE_INTERNAL_NAME).unwrap()
}
}
impl SupportsMembership for Crate {}
impl CrateExtension for Crate {}
#[cfg(test)]
mod tests {
use super::*;
use crate::tao::initialize_kb;
#[test]
fn test_const_crate_init() {
initialize_kb();
assert_ne!(Crate::yin(), Crate::yang());
assert_eq!(Crate::current().implementation_name(), None);
}
#[test]
fn set_and_retrieve_implementation_name() {
initialize_kb();
let mut c = Crate::new();
c.set_implementation_name("Yolo");
assert_eq!(c.implementation_name(), Some(Rc::from("Yolo")));
}
#[test]
fn test_override_implementation_name() {
initialize_kb();
let mut c = Crate::new();
c.set_implementation_name("Yolo");
assert_eq!(c.implementation_name(), Some(Rc::from("Yolo")));
c.set_implementation_name("Bolo");
assert_eq!(c.implementation_name(), Some(Rc::from("Bolo")));
}
#[test]
fn test_lookup_crate() {
initialize_kb();
let mut c1 = Crate::new();
c1.set_implementation_name("one");
let mut c2 = Crate::new();
c2.set_implementation_name("two");
assert_eq!(Crate::lookup("one"), Some(c1));
assert_eq!(Crate::lookup("two"), Some(c2));
assert_eq!(Crate::lookup("three"), None);
}
#[test]
fn add_and_retrieve_version() {
initialize_kb();
let mut c = Crate::new();
c.set_version("0.1.0");
assert_eq!(c.version(), Some(Rc::from("0.1.0")));
}
#[test]
fn test_override_version() {
initialize_kb();
let mut c = Crate::new();
c.set_version("0.1.0");
assert_eq!(c.version(), Some(Rc::from("0.1.0")));
c.set_version("0.2.0");
assert_eq!(c.version(), Some(Rc::from("0.2.0")));
}
#[test]
fn test_version_at_least() {
initialize_kb();
let mut c = Crate::new();
c.set_version("0.1.3");
assert!(c.version_at_least(0, 1, 0));
assert!(c.version_at_least(0, 1, 3));
assert!(!c.version_at_least(0, 1, 4));
assert!(!c.version_at_least(1, 0, 0));
}
}