1use serde_json::Value;
2use futures::future::BoxFuture;
3use std::sync::Arc;
4use cloud_task_executor::Context;
5
6pub trait Script: Send + Sync {
8 fn run(&self, context: Context, payload: Value) -> BoxFuture<'static, Result<String, String>>;
9 fn name(&self) -> &str;
10 fn short_name(&self) -> String;
11}
12
13pub type BoxedScript = Arc<dyn Script>;
15
16pub type ScriptFn = Arc<dyn Fn(Context, Value) -> BoxFuture<'static, Result<String, String>> + Send + Sync>;
17
18pub struct MyScript {
20 name: String,
21 func: ScriptFn,
22}
23
24impl MyScript {
25 pub fn new<F, Fut>(name: &str, func: F) -> Self
26 where
27 F: Fn(Context, Value) -> Fut + 'static + Send + Sync,
28 Fut: std::future::Future<Output=Result<String, String>> + 'static + Send,
29 {
30 Self {
31 name: name.to_string(),
32 func: Arc::new(move |ctx, payload| Box::pin(func(ctx, payload))),
33 }
34 }
35
36 pub fn short_name(&self) -> String {
37 let words: Vec<&str> = self.name.split('_').collect();
38 let short: String = words.iter().filter_map(|word| word.chars().next()).collect();
39 short.to_lowercase()
40 }
41}
42
43impl Script for MyScript {
44 fn run(&self, context: Context, payload: Value) -> BoxFuture<'static, Result<String, String>> {
45 (self.func)(context, payload)
46 }
47
48 fn name(&self) -> &str {
49 &self.name
50 }
51
52 fn short_name(&self) -> String {
53 self.short_name()
54 }
55}
56
57pub trait IntoScriptConfigs {
58 fn into_script(self) -> BoxedScript;
59}
60
61impl IntoScriptConfigs for BoxedScript {
62 fn into_script(self) -> BoxedScript {
63 self
64 }
65}
66
67impl IntoScriptConfigs for MyScript {
68 fn into_script(self) -> BoxedScript {
69 Arc::new(self)
70 }
71}