use serde_json;
use serde_json::json;
use std::marker::{Send, Sync};
use std::sync::{Arc, RwLock, Weak};
use super::thing::Thing;
use super::utils::timestamp;
pub trait Action: Send + Sync {
fn as_action_description(&self) -> serde_json::Map<String, serde_json::Value> {
let mut description = serde_json::Map::new();
let mut inner = serde_json::Map::new();
inner.insert("href".to_owned(), json!(self.get_href()));
inner.insert("timeRequested".to_owned(), json!(self.get_time_requested()));
inner.insert("status".to_owned(), json!(self.get_status()));
if let Some(input) = self.get_input() {
inner.insert("input".to_owned(), json!(input));
}
if let Some(time_completed) = self.get_time_completed() {
inner.insert("timeCompleted".to_owned(), json!(time_completed));
}
description.insert(self.get_name(), json!(inner));
description
}
fn set_href_prefix(&mut self, prefix: String);
fn get_id(&self) -> String;
fn get_name(&self) -> String;
fn get_href(&self) -> String;
fn get_status(&self) -> String;
fn get_thing(&self) -> Option<Arc<RwLock<Box<dyn Thing>>>>;
fn get_time_requested(&self) -> String;
fn get_time_completed(&self) -> Option<String>;
fn get_input(&self) -> Option<serde_json::Map<String, serde_json::Value>>;
fn set_status(&mut self, status: String);
fn start(&mut self);
fn perform_action(&mut self);
fn cancel(&mut self);
fn finish(&mut self);
}
pub struct BaseAction {
id: String,
name: String,
input: Option<serde_json::Map<String, serde_json::Value>>,
href_prefix: String,
href: String,
status: String,
time_requested: String,
time_completed: Option<String>,
thing: Weak<RwLock<Box<dyn Thing>>>,
}
impl BaseAction {
pub fn new(
id: String,
name: String,
input: Option<serde_json::Map<String, serde_json::Value>>,
thing: Weak<RwLock<Box<dyn Thing>>>,
) -> Self {
let href = format!("/actions/{}/{}", name, id);
Self {
id,
name,
input,
href_prefix: "".to_owned(),
href,
status: "created".to_owned(),
time_requested: timestamp(),
time_completed: None,
thing,
}
}
}
impl Action for BaseAction {
fn set_href_prefix(&mut self, prefix: String) {
self.href_prefix = prefix;
}
fn get_id(&self) -> String {
self.id.clone()
}
fn get_name(&self) -> String {
self.name.clone()
}
fn get_href(&self) -> String {
format!("{}{}", self.href_prefix, self.href)
}
fn get_status(&self) -> String {
self.status.clone()
}
fn get_thing(&self) -> Option<Arc<RwLock<Box<dyn Thing>>>> {
self.thing.upgrade()
}
fn get_time_requested(&self) -> String {
self.time_requested.clone()
}
fn get_time_completed(&self) -> Option<String> {
self.time_completed.clone()
}
fn get_input(&self) -> Option<serde_json::Map<String, serde_json::Value>> {
self.input.clone()
}
fn set_status(&mut self, status: String) {
self.status = status;
}
fn start(&mut self) {
self.set_status("pending".to_owned());
}
fn perform_action(&mut self) {}
fn cancel(&mut self) {}
fn finish(&mut self) {
self.set_status("completed".to_owned());
self.time_completed = Some(timestamp());
}
}