1use alloy_primitives::U256;
5
6use crate::TopLevelStorage;
7
8pub mod errors;
9
10pub trait CallContext {
13 fn gas(&self) -> u64;
16}
17
18pub trait StaticCallContext: CallContext {}
21
22pub unsafe trait MutatingCallContext: CallContext {
31 fn value(&self) -> U256;
33}
34
35pub trait NonPayableCallContext: MutatingCallContext {}
40
41#[derive(Debug, Clone)]
43pub struct Call<const MUTATING: bool = false, const HAS_VALUE: bool = false> {
44 gas: u64,
45 value: Option<U256>,
46}
47
48impl<const MUTATING: bool, const HAS_VALUE: bool> Call<MUTATING, HAS_VALUE> {
49 pub fn gas(self, gas: u64) -> Self {
52 Self { gas, ..self }
53 }
54
55 pub fn value(self, value: U256) -> Call<true, true> {
58 Call {
59 value: Some(value),
60 gas: self.gas,
61 }
62 }
63}
64
65impl<const MUTATING: bool, const HAS_VALUE: bool> CallContext for Call<MUTATING, HAS_VALUE> {
66 fn gas(&self) -> u64 {
67 self.gas
68 }
69}
70
71impl StaticCallContext for Call<false, false> {}
72
73impl NonPayableCallContext for Call<true, false> {}
74
75unsafe impl<const HAS_VALUE: bool> MutatingCallContext for Call<true, HAS_VALUE> {
76 fn value(&self) -> U256 {
77 self.value.unwrap_or_default()
78 }
79}
80
81impl Default for Call<false, false> {
82 fn default() -> Self {
83 Self::new()
84 }
85}
86
87impl Call<false, false> {
88 pub fn new() -> Self {
89 Self {
90 gas: u64::MAX,
91 value: None,
92 }
93 }
94}
95
96impl Call<true, false> {
97 pub fn new_mutating(_storage: &mut impl TopLevelStorage) -> Self {
98 Self {
99 gas: u64::MAX,
100 value: None,
101 }
102 }
103}
104
105impl Call<true, true> {
106 pub fn new_payable(_storage: &mut impl TopLevelStorage, value: U256) -> Self {
107 Self {
108 gas: u64::MAX,
109 value: Some(value),
110 }
111 }
112}