soroban_tools/circuit_breaker/
impl.rs

1/*
2    Copyright (c) 2023-2024 Frederic Kyung-jin Rezeau (오경진 吳景振)
3
4    This file is part of soroban-kit.
5
6    Licensed under the MIT License, this software is provided "AS IS",
7    no liability assumed. For details, see the LICENSE file in the
8    root directory.
9
10    Author: Fred Kyung-jin Rezeau <fred@litemint.com>
11*/
12
13use soroban_sdk::contracttype;
14
15#[macro_export]
16macro_rules! impl_circuit_breaker_state_machine {
17    ($instance:expr, $env:expr, $trigger:expr, $storage_type:expr, $state_enum:ident, $state_variant:ident) => {
18        let state_key = $state_variant;
19        let region_key = $crate::circuit_breaker::Circuit::Default;
20        $crate::impl_circuit_breaker_state_machine!(@internal $instance, $env, $trigger, $storage_type, state_key,
21            region_key, $state_enum, $crate::circuit_breaker::Circuit);
22    };
23    ($instance:expr, $env:expr, $trigger:expr, $storage_type:expr, $state_enum:ident, $state_variant:ident,
24        $region_enum:ident, $region_variant:ident, ()) => {
25        let state_key = $state_variant;
26        let region_key = $region_enum::$region_variant;
27        $crate::impl_circuit_breaker_state_machine!(@internal $instance, $env, $trigger, $storage_type, state_key,
28            region_key, $state_enum, $region_enum);
29    };
30    ($instance:expr, $env:expr, $trigger:expr, $storage_type:expr, $state_enum:ident, $state_variant:ident,
31        $region_enum:ident, $region_variant:ident, ($($region_tuple_value:expr),+)) => {
32        let state_key = $state_variant;
33        let region_key = $region_enum::$region_variant($($region_tuple_value),*);
34        $crate::impl_circuit_breaker_state_machine!(@internal $instance, $env, $trigger, $storage_type, state_key,
35            region_key, $state_enum, $region_enum);
36    };
37    // @internal
38    (@internal $instance:expr, $env:expr, $trigger:expr, $storage_type:expr, $state_key:expr,
39        $region_key:expr, $state_enum:ty, $region_enum:ty) => {
40            let sm = $crate::fsm::StateMachine::<$region_enum, $state_enum>::new(&$region_key, $storage_type);
41            if $trigger {
42                sm.set_state($env, &$state_key);
43            }
44            else {
45                if sm.get_state($env).is_none() {
46                    sm.set_state($env, &false); // Default circuit state is closed (false).
47                }
48                $instance.on_guard($env, &sm);
49                assert_eq!(sm.get_state(&$env).unwrap(), $state_key);
50                $instance.on_effect($env, &sm);
51            }
52    };
53}
54
55#[contracttype]
56#[derive(Debug, Clone, Eq, PartialEq)]
57pub enum Circuit {
58    Default,
59}