use crate::errors::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MemoryType {
#[default]
Fact,
Preference,
Procedure,
Guard,
Observation,
}
impl MemoryType {
#[allow(dead_code)] pub fn as_str(&self) -> &'static str {
match self {
MemoryType::Fact => "fact",
MemoryType::Preference => "preference",
MemoryType::Procedure => "procedure",
MemoryType::Guard => "guard",
MemoryType::Observation => "observation",
}
}
#[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Result<Self, Error> {
match s.to_lowercase().as_str() {
"fact" => Ok(MemoryType::Fact),
"preference" => Ok(MemoryType::Preference),
"procedure" => Ok(MemoryType::Procedure),
"guard" => Ok(MemoryType::Guard),
"observation" => Ok(MemoryType::Observation),
_ => Err(Error::InvalidInput(format!(
"Invalid memory type '{}'. Must be one of: fact, preference, procedure, guard, observation",
s
))),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MemoryStatus {
#[default]
Active,
Candidate,
Superseded,
Deprecated,
}
impl MemoryStatus {
#[allow(dead_code)] pub fn as_str(&self) -> &'static str {
match self {
MemoryStatus::Active => "active",
MemoryStatus::Candidate => "candidate",
MemoryStatus::Superseded => "superseded",
MemoryStatus::Deprecated => "deprecated",
}
}
#[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Result<Self, Error> {
match s.to_lowercase().as_str() {
"active" => Ok(MemoryStatus::Active),
"candidate" => Ok(MemoryStatus::Candidate),
"superseded" => Ok(MemoryStatus::Superseded),
"deprecated" => Ok(MemoryStatus::Deprecated),
_ => Err(Error::InvalidInput(format!(
"Invalid memory status '{}'. Must be one of: active, candidate, superseded, deprecated",
s
))),
}
}
pub fn is_valid_for_insert(self) -> bool {
matches!(self, MemoryStatus::Active | MemoryStatus::Candidate)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_memory_type_roundtrip() {
for (s, expected) in [
("fact", MemoryType::Fact),
("preference", MemoryType::Preference),
("procedure", MemoryType::Procedure),
("guard", MemoryType::Guard),
("observation", MemoryType::Observation),
] {
let parsed = MemoryType::from_str(s).unwrap();
assert_eq!(parsed, expected);
assert_eq!(parsed.as_str(), s);
}
}
#[test]
fn test_memory_type_case_insensitive() {
assert_eq!(MemoryType::from_str("FACT").unwrap(), MemoryType::Fact);
assert_eq!(MemoryType::from_str("Guard").unwrap(), MemoryType::Guard);
}
#[test]
fn test_memory_type_invalid() {
assert!(MemoryType::from_str("invalid").is_err());
assert!(MemoryType::from_str("").is_err());
}
#[test]
fn test_memory_status_roundtrip() {
for (s, expected) in [
("active", MemoryStatus::Active),
("candidate", MemoryStatus::Candidate),
("superseded", MemoryStatus::Superseded),
("deprecated", MemoryStatus::Deprecated),
] {
let parsed = MemoryStatus::from_str(s).unwrap();
assert_eq!(parsed, expected);
assert_eq!(parsed.as_str(), s);
}
}
#[test]
fn test_memory_status_invalid() {
assert!(MemoryStatus::from_str("invalid").is_err());
}
#[test]
fn test_is_valid_for_insert() {
assert!(MemoryStatus::Active.is_valid_for_insert());
assert!(MemoryStatus::Candidate.is_valid_for_insert());
assert!(!MemoryStatus::Superseded.is_valid_for_insert());
assert!(!MemoryStatus::Deprecated.is_valid_for_insert());
}
}