use std::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum ActionType {
Produce,
Consume,
Use,
Cite,
Work,
Pickup,
Dropoff,
Accept,
Modify,
Combine,
Separate,
DeliverService,
TransferAllRights,
TransferCustody,
Transfer,
Move,
Copy,
Raise,
Lower,
}
impl ActionType {
pub fn as_str(&self) -> &'static str {
match self {
ActionType::Produce => "produce",
ActionType::Consume => "consume",
ActionType::Use => "use",
ActionType::Cite => "cite",
ActionType::Work => "work",
ActionType::Pickup => "pickup",
ActionType::Dropoff => "dropoff",
ActionType::Accept => "accept",
ActionType::Modify => "modify",
ActionType::Combine => "combine",
ActionType::Separate => "separate",
ActionType::DeliverService => "deliverService",
ActionType::TransferAllRights => "transferAllRights",
ActionType::TransferCustody => "transferCustody",
ActionType::Transfer => "transfer",
ActionType::Move => "move",
ActionType::Copy => "copy",
ActionType::Raise => "raise",
ActionType::Lower => "lower",
}
}
pub fn from_str(s: &str) -> Option<Self> {
match s.to_lowercase().as_str() {
"produce" => Some(ActionType::Produce),
"consume" => Some(ActionType::Consume),
"use" => Some(ActionType::Use),
"cite" => Some(ActionType::Cite),
"work" => Some(ActionType::Work),
"pickup" => Some(ActionType::Pickup),
"dropoff" => Some(ActionType::Dropoff),
"accept" => Some(ActionType::Accept),
"modify" => Some(ActionType::Modify),
"combine" => Some(ActionType::Combine),
"separate" => Some(ActionType::Separate),
"deliverservice" | "deliver_service" => Some(ActionType::DeliverService),
"transferallrights" | "transfer_all_rights" => Some(ActionType::TransferAllRights),
"transfercustody" | "transfer_custody" => Some(ActionType::TransferCustody),
"transfer" => Some(ActionType::Transfer),
"move" => Some(ActionType::Move),
"copy" => Some(ActionType::Copy),
"raise" => Some(ActionType::Raise),
"lower" => Some(ActionType::Lower),
_ => None,
}
}
pub fn is_transfer(&self) -> bool {
matches!(
self,
ActionType::Transfer | ActionType::TransferAllRights | ActionType::TransferCustody
)
}
pub fn is_production(&self) -> bool {
matches!(
self,
ActionType::Produce | ActionType::Consume | ActionType::Use
)
}
pub fn is_transportation(&self) -> bool {
matches!(self, ActionType::Pickup | ActionType::Dropoff)
}
pub fn pairs_with(&self) -> Option<ActionType> {
match self {
ActionType::Pickup => Some(ActionType::Dropoff),
ActionType::Dropoff => Some(ActionType::Pickup),
ActionType::Accept => Some(ActionType::Modify),
ActionType::Modify => Some(ActionType::Accept),
ActionType::Combine => Some(ActionType::Separate),
ActionType::Separate => Some(ActionType::Combine),
_ => None,
}
}
}
impl fmt::Display for ActionType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl Default for ActionType {
fn default() -> Self {
ActionType::Transfer
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum ActionEffect {
Increment,
Decrement,
NoEffect,
DecrementIncrement,
IncrementTo,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum InputOutput {
Input,
Output,
OutputInput,
NotApplicable,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Action {
pub action_type: ActionType,
pub label: String,
pub event_quantity: EventQuantityType,
pub input_output: InputOutput,
pub pairs_with: Option<ActionType>,
pub create_resource: CreateResource,
pub accounting_effect: ActionEffect,
pub onhand_effect: ActionEffect,
pub location_effect: LocationEffect,
pub contained_effect: ContainedEffect,
pub accountable_effect: AccountableEffect,
pub stage_effect: StageEffect,
pub state_effect: StateEffect,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum EventQuantityType {
ResourceQuantity,
EffortQuantity,
Both,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum CreateResource {
No,
Optional,
OptionalTo,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum LocationEffect {
NoEffect,
New,
Update,
UpdateTo,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum ContainedEffect {
NoEffect,
Update,
Remove,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum AccountableEffect {
NoEffect,
New,
UpdateTo,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum StageEffect {
NoEffect,
Stage,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum StateEffect {
NoEffect,
Update,
UpdateTo,
}
impl Action {
pub fn from_type(action_type: ActionType) -> Self {
match action_type {
ActionType::Produce => Action {
action_type,
label: "Produce".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Output,
pairs_with: None,
create_resource: CreateResource::Optional,
accounting_effect: ActionEffect::Increment,
onhand_effect: ActionEffect::Increment,
location_effect: LocationEffect::New,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::New,
stage_effect: StageEffect::Stage,
state_effect: StateEffect::Update,
},
ActionType::Consume => Action {
action_type,
label: "Consume".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Input,
pairs_with: None,
create_resource: CreateResource::No,
accounting_effect: ActionEffect::Decrement,
onhand_effect: ActionEffect::Decrement,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Use => Action {
action_type,
label: "Use".to_string(),
event_quantity: EventQuantityType::Both,
input_output: InputOutput::Input,
pairs_with: None,
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Work => Action {
action_type,
label: "Work".to_string(),
event_quantity: EventQuantityType::Both,
input_output: InputOutput::Input,
pairs_with: None,
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Cite => Action {
action_type,
label: "Cite".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Input,
pairs_with: None,
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Transfer => Action {
action_type,
label: "Transfer".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::NotApplicable,
pairs_with: None,
create_resource: CreateResource::OptionalTo,
accounting_effect: ActionEffect::DecrementIncrement,
onhand_effect: ActionEffect::DecrementIncrement,
location_effect: LocationEffect::UpdateTo,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::UpdateTo,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::TransferAllRights => Action {
action_type,
label: "Transfer All Rights".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::NotApplicable,
pairs_with: None,
create_resource: CreateResource::OptionalTo,
accounting_effect: ActionEffect::DecrementIncrement,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::UpdateTo,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::TransferCustody => Action {
action_type,
label: "Transfer Custody".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::NotApplicable,
pairs_with: None,
create_resource: CreateResource::OptionalTo,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::DecrementIncrement,
location_effect: LocationEffect::UpdateTo,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Move => Action {
action_type,
label: "Move".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::NotApplicable,
pairs_with: None,
create_resource: CreateResource::OptionalTo,
accounting_effect: ActionEffect::DecrementIncrement,
onhand_effect: ActionEffect::DecrementIncrement,
location_effect: LocationEffect::UpdateTo,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Pickup => Action {
action_type,
label: "Pickup".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Input,
pairs_with: Some(ActionType::Dropoff),
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Dropoff => Action {
action_type,
label: "Dropoff".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Output,
pairs_with: Some(ActionType::Pickup),
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::Update,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Accept => Action {
action_type,
label: "Accept".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Input,
pairs_with: Some(ActionType::Modify),
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Modify => Action {
action_type,
label: "Modify".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Output,
pairs_with: Some(ActionType::Accept),
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::Stage,
state_effect: StateEffect::Update,
},
ActionType::Combine => Action {
action_type,
label: "Combine".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Input,
pairs_with: Some(ActionType::Separate),
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::Update,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Separate => Action {
action_type,
label: "Separate".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::Output,
pairs_with: Some(ActionType::Combine),
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::Remove,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::DeliverService => Action {
action_type,
label: "Deliver Service".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::OutputInput,
pairs_with: None,
create_resource: CreateResource::No,
accounting_effect: ActionEffect::NoEffect,
onhand_effect: ActionEffect::NoEffect,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Copy => Action {
action_type,
label: "Copy".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::NotApplicable,
pairs_with: None,
create_resource: CreateResource::OptionalTo,
accounting_effect: ActionEffect::IncrementTo,
onhand_effect: ActionEffect::IncrementTo,
location_effect: LocationEffect::New,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::UpdateTo,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Raise => Action {
action_type,
label: "Raise".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::NotApplicable,
pairs_with: None,
create_resource: CreateResource::Optional,
accounting_effect: ActionEffect::Increment,
onhand_effect: ActionEffect::Increment,
location_effect: LocationEffect::New,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::New,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
ActionType::Lower => Action {
action_type,
label: "Lower".to_string(),
event_quantity: EventQuantityType::ResourceQuantity,
input_output: InputOutput::NotApplicable,
pairs_with: None,
create_resource: CreateResource::No,
accounting_effect: ActionEffect::Decrement,
onhand_effect: ActionEffect::Decrement,
location_effect: LocationEffect::NoEffect,
contained_effect: ContainedEffect::NoEffect,
accountable_effect: AccountableEffect::NoEffect,
stage_effect: StageEffect::NoEffect,
state_effect: StateEffect::NoEffect,
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_action_type_string_conversion() {
assert_eq!(ActionType::Produce.as_str(), "produce");
assert_eq!(ActionType::from_str("produce"), Some(ActionType::Produce));
assert_eq!(ActionType::from_str("PRODUCE"), Some(ActionType::Produce));
}
#[test]
fn test_action_pairs() {
assert_eq!(ActionType::Pickup.pairs_with(), Some(ActionType::Dropoff));
assert_eq!(ActionType::Accept.pairs_with(), Some(ActionType::Modify));
assert_eq!(ActionType::Produce.pairs_with(), None);
}
#[test]
fn test_action_classification() {
assert!(ActionType::Transfer.is_transfer());
assert!(ActionType::TransferAllRights.is_transfer());
assert!(!ActionType::Produce.is_transfer());
assert!(ActionType::Produce.is_production());
assert!(!ActionType::Transfer.is_production());
assert!(ActionType::Pickup.is_transportation());
assert!(!ActionType::Produce.is_transportation());
}
}