use serde_json::Value;
use futures::future::BoxFuture;
use std::sync::Arc;
use cloud_task_executor::Context;
pub trait Script: Send + Sync {
fn run(&self, context: Context, payload: Value) -> BoxFuture<'static, Result<String, String>>;
fn name(&self) -> &str;
fn short_name(&self) -> String;
}
pub type BoxedScript = Arc<dyn Script>;
pub type ScriptFn = Arc<dyn Fn(Context, Value) -> BoxFuture<'static, Result<String, String>> + Send + Sync>;
pub struct MyScript {
name: String,
func: ScriptFn,
}
impl MyScript {
pub fn new<F, Fut>(name: &str, func: F) -> Self
where
F: Fn(Context, Value) -> Fut + 'static + Send + Sync,
Fut: std::future::Future<Output=Result<String, String>> + 'static + Send,
{
Self {
name: name.to_string(),
func: Arc::new(move |ctx, payload| Box::pin(func(ctx, payload))),
}
}
pub fn short_name(&self) -> String {
let words: Vec<&str> = self.name.split('_').collect();
let short: String = words.iter().filter_map(|word| word.chars().next()).collect();
short.to_lowercase()
}
}
impl Script for MyScript {
fn run(&self, context: Context, payload: Value) -> BoxFuture<'static, Result<String, String>> {
(self.func)(context, payload)
}
fn name(&self) -> &str {
&self.name
}
fn short_name(&self) -> String {
self.short_name()
}
}
pub trait IntoScriptConfigs {
fn into_script(self) -> BoxedScript;
}
impl IntoScriptConfigs for BoxedScript {
fn into_script(self) -> BoxedScript {
self
}
}
impl IntoScriptConfigs for MyScript {
fn into_script(self) -> BoxedScript {
Arc::new(self)
}
}