use crate::error::{PoaError, PoaResult};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LifespanPolicy {
Transient,
Persistent,
}
impl Default for LifespanPolicy {
fn default() -> Self {
Self::Transient
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum IdAssignmentPolicy {
System,
User,
}
impl Default for IdAssignmentPolicy {
fn default() -> Self {
Self::System
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum IdUniquenessPolicy {
Unique,
Multiple,
}
impl Default for IdUniquenessPolicy {
fn default() -> Self {
Self::Unique
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ImplicitActivationPolicy {
NoImplicit,
Implicit,
}
impl Default for ImplicitActivationPolicy {
fn default() -> Self {
Self::NoImplicit
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ServantRetentionPolicy {
Retain,
NonRetain,
}
impl Default for ServantRetentionPolicy {
fn default() -> Self {
Self::Retain
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RequestProcessingPolicy {
UseActiveObjectMapOnly,
UseDefaultServant,
UseServantManager,
}
impl Default for RequestProcessingPolicy {
fn default() -> Self {
Self::UseActiveObjectMapOnly
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ThreadPolicy {
OrbCtrl,
SingleThread,
MainThread,
}
impl Default for ThreadPolicy {
fn default() -> Self {
Self::OrbCtrl
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct PolicySet {
pub lifespan: LifespanPolicy,
pub id_assignment: IdAssignmentPolicy,
pub id_uniqueness: IdUniquenessPolicy,
pub implicit_activation: ImplicitActivationPolicy,
pub servant_retention: ServantRetentionPolicy,
pub request_processing: RequestProcessingPolicy,
pub thread: ThreadPolicy,
}
impl PolicySet {
pub fn validate(&self) -> PoaResult<()> {
if self.request_processing == RequestProcessingPolicy::UseDefaultServant
&& self.id_uniqueness != IdUniquenessPolicy::Multiple
{
return Err(PoaError::InvalidPolicy(
"USE_DEFAULT_SERVANT requires MULTIPLE_ID".into(),
));
}
if self.servant_retention == ServantRetentionPolicy::NonRetain
&& self.request_processing == RequestProcessingPolicy::UseActiveObjectMapOnly
{
return Err(PoaError::InvalidPolicy(
"NON_RETAIN requires USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER".into(),
));
}
if self.implicit_activation == ImplicitActivationPolicy::Implicit {
if self.id_assignment != IdAssignmentPolicy::System {
return Err(PoaError::InvalidPolicy(
"IMPLICIT_ACTIVATION requires SYSTEM_ID".into(),
));
}
if self.servant_retention != ServantRetentionPolicy::Retain {
return Err(PoaError::InvalidPolicy(
"IMPLICIT_ACTIVATION requires RETAIN".into(),
));
}
}
Ok(())
}
}
#[cfg(test)]
#[allow(clippy::expect_used, clippy::unwrap_used, clippy::panic)]
mod tests {
use super::*;
#[test]
fn default_policy_set_is_spec_default() {
let p = PolicySet::default();
assert_eq!(p.lifespan, LifespanPolicy::Transient);
assert_eq!(p.id_assignment, IdAssignmentPolicy::System);
assert_eq!(p.id_uniqueness, IdUniquenessPolicy::Unique);
assert_eq!(p.implicit_activation, ImplicitActivationPolicy::NoImplicit);
assert_eq!(p.servant_retention, ServantRetentionPolicy::Retain);
assert_eq!(
p.request_processing,
RequestProcessingPolicy::UseActiveObjectMapOnly
);
assert_eq!(p.thread, ThreadPolicy::OrbCtrl);
}
#[test]
fn default_set_validates() {
assert!(PolicySet::default().validate().is_ok());
}
#[test]
fn use_default_servant_without_multiple_id_is_rejected() {
let p = PolicySet {
request_processing: RequestProcessingPolicy::UseDefaultServant,
id_uniqueness: IdUniquenessPolicy::Unique,
..PolicySet::default()
};
assert!(matches!(p.validate(), Err(PoaError::InvalidPolicy(_))));
}
#[test]
fn use_default_servant_with_multiple_id_is_ok() {
let p = PolicySet {
request_processing: RequestProcessingPolicy::UseDefaultServant,
id_uniqueness: IdUniquenessPolicy::Multiple,
..PolicySet::default()
};
assert!(p.validate().is_ok());
}
#[test]
fn non_retain_with_aom_only_is_rejected() {
let p = PolicySet {
servant_retention: ServantRetentionPolicy::NonRetain,
request_processing: RequestProcessingPolicy::UseActiveObjectMapOnly,
..PolicySet::default()
};
assert!(matches!(p.validate(), Err(PoaError::InvalidPolicy(_))));
}
#[test]
fn non_retain_with_servant_manager_is_ok() {
let p = PolicySet {
servant_retention: ServantRetentionPolicy::NonRetain,
request_processing: RequestProcessingPolicy::UseServantManager,
..PolicySet::default()
};
assert!(p.validate().is_ok());
}
#[test]
fn implicit_activation_requires_system_id_and_retain() {
let p = PolicySet {
implicit_activation: ImplicitActivationPolicy::Implicit,
id_assignment: IdAssignmentPolicy::User,
..PolicySet::default()
};
assert!(matches!(p.validate(), Err(PoaError::InvalidPolicy(_))));
let p2 = PolicySet {
implicit_activation: ImplicitActivationPolicy::Implicit,
servant_retention: ServantRetentionPolicy::NonRetain,
request_processing: RequestProcessingPolicy::UseServantManager,
..PolicySet::default()
};
assert!(matches!(p2.validate(), Err(PoaError::InvalidPolicy(_))));
}
#[test]
fn implicit_activation_with_compatible_policies_is_ok() {
let p = PolicySet {
implicit_activation: ImplicitActivationPolicy::Implicit,
..PolicySet::default()
};
assert!(p.validate().is_ok());
}
}