1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! `flowcore` defines core structs and traits used by other flow libraries and implementations
use Value;
use crateResult;
/// Return a flow function result with `Ok((Some(value), RUN_AGAIN))`.
///
/// Single value: `flow_output!(json!(42))`
/// Named outputs: `flow_output!("result" => json!(42), "remainder" => json!(0))`
///
/// # Examples
/// ```
/// use flowcore::flow_output;
/// use serde_json::json;
///
/// // Single value output
/// let result: flowcore::errors::Result<(Option<serde_json::Value>, bool)> =
/// flow_output!(json!(42));
/// assert_eq!(result.unwrap().0, Some(json!(42)));
///
/// // Named output map
/// let result: flowcore::errors::Result<(Option<serde_json::Value>, bool)> =
/// flow_output!("result" => json!(42), "remainder" => json!(0));
/// assert_eq!(result.unwrap().0.unwrap().pointer("/result").unwrap(), &json!(42));
/// ```
/// serializers to read definition files from various text formats based on file extension
/// Serializers for writing flow model types to disk (TOML format)
/// contains [Error] that other modules in this crate will `use errors::*;`
/// to get access to everything `error_chain` creates.
/// `meta_provider` resolves library references of the type "lib://" and "context://"
/// defines many of the core data structures used across libraries and binaries
/// is a trait definition that providers of content must implement
/// Utility functions related to [Urls][url::Url]
/// Use `DONT_RUN_AGAIN` to indicate that a function should not be executed more times
pub const DONT_RUN_AGAIN: RunAgain = false;
/// Use `RUN_AGAIN` to indicate that a function can be executed more times
pub const RUN_AGAIN: RunAgain = true;
/// Implementations should return a value of type `RunAgain` to indicate if it should be
/// executed more times in the future.
pub type RunAgain = bool;
/// contains the file and http content provider implementations
/// The `Implementation` trait used by functions to provide the code that runs on inputs
///
/// A function's implementation must implement this trait with a single `run()` method that takes
/// as input an array of values, and it returns a `Result` tuple with an Optional output `Value`
/// plus a `RunAgain` indicating if it should be run again.
/// i.e. it has not "completed", in which case it should not be called again.
///
/// # Examples
///
/// Here is an example implementation of this trait:
///
/// ```
/// use flowcore::{Implementation, RUN_AGAIN, RunAgain};
/// use flowcore::errors::Result;
/// use serde_json::Value;
/// use serde_json::json;
///
/// #[derive(Debug)]
/// pub struct Compare;
///
/// /*
/// A compare implementation that takes two numbers and outputs the comparisons between them
/// */
/// impl Implementation for Compare {
/// fn run(&self, mut inputs: &[Value]) -> Result<(Option<Value>, RunAgain)> {
/// let left = inputs[0].as_i64().unwrap();
/// let right = inputs[1].as_i64().unwrap();
///
/// let output = json!({
/// "equal" : left == right,
/// "lt" : left < right,
/// "gt" : left > right,
/// "lte" : left <= right,
/// "gte" : left >= right
/// });
///
/// Ok((None, RUN_AGAIN))
/// }
/// }
/// ```
///
/// **Note**: It is recommended to implement this trait by using the `flow_function` macro from the
/// `flowmacro` crate to simplify input gathering and to hide the boilerplate code around the
/// function implementing the logic.