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
//! This module is the user-facing entrypoint for circuit breaker
//! usage. The internal structures are available via other modules if
//! required, but are (for now) mostly undocumented.
//!
//! You should usually stick to this module for documentation and
//! examples.
//!
//! **Note**: The type aliases used by this public API require users
//! to supply [function pointers][] instead of closures. This is
//! because the type of a closure can not currently be named and
//! circuit breakers will often have to be stored in context structs
//! and the like without propagating the closure trait constraints all
//! the way up.
//!
//! If you need to store closures or other types that implement the
//! `Fn`-trait, please take a look at the internal modules.
//!
//! [function pointers]: https://doc.rust-lang.org/book/second-edition/ch19-05-advanced-functions-and-closures.html#function-pointers
pub use Config;
pub use CriusError;
/// Convenience type alias for function pointers matching the
/// input/output and error types of a circuit breaker.
pub type CommandFn<I, O, E> = fn ;
/// Convenience type alias matching the fallback function pointer of a
/// circuit breaker.
pub type FallbackFn<O, E> = fn ;
/// A Command is a runnable circuit breaker. It can be constructed
/// either with or without a fallback method that can provide
/// alternative values if the contained calls fail or if the breaker
/// is open.
///
/// # Type parameters:
///
/// * `I`: *Input* type to the breaker's function.
/// * `O`: *Output* type of the breaker's function.
/// * `E`: *Error* type returned by the breaker's function. This type
/// must implement `From<CriusError>` to propagate internal circuit
/// breaker errors.
pub type Command<I, O, E> = Command;
/// Use this function to construct a circuit breaker *without* a
/// fallback function.
///
/// # Example:
///
/// ```
/// # use crius::{command, Config, CriusError};
/// # #[derive(PartialEq, Debug)]
/// # struct ExampleError;
/// # impl From<CriusError> for ExampleError {
/// # fn from(_: CriusError) -> Self { ExampleError }
/// # }
///
/// // Define a simple circuit breaker command:
/// let mut cmd = command(Config::default(), |n| {
/// if n > 10 {
/// Err(ExampleError)
/// } else {
/// Ok(n * 2)
/// }}).unwrap();
///
/// // and run it with an example input:
/// let result = cmd.run(10);
/// assert_eq!(Ok(20), result)
/// ```
/// Use this function to construct a circuit breaker *with* a fallback
/// function:
/// # Example:
///
/// ```
/// # use crius::{command_with_fallback, Config, CriusError};
/// # #[derive(PartialEq, Debug)]
/// # struct ExampleError;
/// # impl From<CriusError> for ExampleError {
/// # fn from(_: CriusError) -> Self { ExampleError }
/// # }
/// # let double_if_lt_ten = |n| if n > 10 {
/// # Err(ExampleError)
/// # } else {
/// # Ok(n * 2)
/// # };
/// #
/// // Define a simple circuit breaker command:
/// let mut cmd = command_with_fallback(
/// Config::default(),
///
/// // Same function as in the `command`-example
/// double_if_lt_ten,
///
/// // Define a fallback:
/// |_err| 4, // It's always four.
/// ).unwrap();
///
/// // and run it with an example input:
/// let result = cmd.run(11);
/// assert_eq!(Ok(4), result)
/// ```