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
use std::fmt::{self, Debug};
use serde::Deserialize;
use crate::{MappingFnImpl, ValueSpec};
type FnPlaceholder<T> = fn(&()) -> Option<T>;
/// Exists to deserialize `MappingFn` with a non-type-erased `MappingFnImpl`
#[derive(Clone, Deserialize)]
pub enum ValueSpecDe<T> {
/// Loads a stored value spec.
///
/// The value used is determined by the value spec that was
/// last stored in the `params_specs_file`. This means it
/// could be loaded as a `Value(T)` during context `build()`.
///
/// This variant may be provided when defining a command context
/// builder. However, this variant is never serialized, but
/// whichever value was *first* stored is re-loaded then
/// re-serialized.
///
/// If no value spec was previously serialized, then the command
/// context build will return an error.
Stored,
/// Uses the provided value.
///
/// The value used is whatever is passed in to the command context
/// builder.
Value {
/// The value to use.
value: T,
},
/// Uses a value loaded from `resources` at runtime.
///
/// The value may have been provided by workspace params, or
/// inserted by a predecessor at runtime.
InMemory,
/// Look up some data populated by a predecessor, and compute the value
/// from that data.
MappingFn(MappingFnImpl<T, FnPlaceholder<T>, ((),)>),
}
impl<T> Debug for ValueSpecDe<T>
where
T: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Stored => f.write_str("Stored"),
Self::Value { value } => f.debug_tuple("Value").field(value).finish(),
Self::InMemory => f.write_str("InMemory"),
Self::MappingFn(mapping_fn_impl) => {
f.debug_tuple("MappingFn").field(&mapping_fn_impl).finish()
}
}
}
}
impl<T> From<ValueSpecDe<T>> for ValueSpec<T>
where
T: Clone + Debug + Send + Sync + 'static,
{
fn from(value_spec_de: ValueSpecDe<T>) -> Self {
match value_spec_de {
ValueSpecDe::Stored => ValueSpec::Stored,
ValueSpecDe::Value { value } => ValueSpec::Value { value },
ValueSpecDe::InMemory => ValueSpec::InMemory,
ValueSpecDe::MappingFn(mapping_fn_impl) => {
ValueSpec::MappingFn(Box::new(mapping_fn_impl))
}
}
}
}