1use crate::environment::Environment;
4use crate::error::BindError;
5
6pub trait Binding<T> {
8 fn bind<E: Environment>(&self, environment: &E) -> Result<T, BindError>;
10}
11
12pub trait BindingExt: Sized {
14 #[must_use]
18 fn optional(self) -> OptionalVar<Self> {
19 OptionalVar { binding: self }
20 }
21}
22
23impl<B> BindingExt for B {}
24
25pub struct OptionalVar<B> {
27 binding: B,
28}
29
30impl<T, B> Binding<Option<T>> for OptionalVar<B>
31where
32 B: Binding<T>,
33{
34 fn bind<E: Environment>(&self, environment: &E) -> Result<Option<T>, BindError> {
35 match self.binding.bind(environment) {
36 Ok(value) => Ok(Some(value)),
37 Err(BindError::MissingVariable { .. } | BindError::EmptyVariable { .. }) => Ok(None),
38 Err(error) => Err(error),
39 }
40 }
41}
42
43pub struct Binder<E>
45where
46 E: Environment,
47{
48 environment: E,
49}
50
51impl<E> Binder<E>
52where
53 E: Environment,
54{
55 #[must_use]
57 pub fn new(environment: E) -> Self {
58 Self { environment }
59 }
60
61 pub fn bind<T, B>(&self, binding: &B) -> Result<T, BindError>
63 where
64 B: Binding<T>,
65 {
66 binding.bind(&self.environment)
67 }
68
69 #[must_use]
71 pub fn environment(&self) -> &E {
72 &self.environment
73 }
74}