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
//! Ready-made [`CallLayer`]s.
use ;
use crateResult;
use OwnedDataValue;
use fmt;
/// What an [`Answer`] asks of each call.
type Answering = dyn Fn + Send + Sync;
/// Answers calls from a closure, for a dry run.
///
/// The closure is asked about each call it wraps, and sees the call's
/// [`Ctx`]: its [`info`](Ctx::info), its [`input`](Ctx::input), resolved with
/// every secret-reading field `null`, and the
/// [`primary_output`](Ctx::primary_output) an answer is written through.
/// `Some(value)` is written with [`Ctx::emit_default`], through the callee's
/// primary output, and the call returns [`Outcome::Ok`] without reaching the
/// layers inside this one or the function. `None` passes the call on. A
/// callee with no primary output fails the call with a `Config` error.
///
/// ```
/// use dataflow_rs::datavalue::OwnedDataValue;
/// use dataflow_rs::function::{CallLayer, layers::Answer};
/// use dataflow_rs::RunOptions;
/// use std::sync::Arc;
///
/// // Every `http_call` that has somewhere to write answers with the input
/// // it was given; the rest run.
/// let dry_run: Vec<Arc<dyn CallLayer>> = vec![Arc::new(Answer::new(|ctx| {
/// if ctx.info().function != "http_call" || ctx.primary_output().is_none() {
/// return None;
/// }
/// let input = ctx.input().ok()?;
/// Some(OwnedDataValue::Object(vec![
/// ("status".into(), "dry run".into()),
/// ("request".into(), input),
/// ]))
/// }))];
/// let opts = RunOptions::default().layers(&dry_run);
/// ```