datafusion_ethers/
utils.rs

1use alloy::rpc::types::eth::{BlockNumberOrTag, Filter, FilterBlockOption};
2
3///////////////////////////////////////////////////////////////////////////////////////////////////
4
5pub(crate) trait FilterExt {
6    fn union(self, from: BlockNumberOrTag, to: BlockNumberOrTag) -> Self;
7}
8
9impl FilterExt for Filter {
10    fn union(mut self, from: BlockNumberOrTag, to: BlockNumberOrTag) -> Self {
11        self.block_option = self.block_option.union(FilterBlockOption::Range {
12            from_block: Some(from),
13            to_block: Some(to),
14        });
15        self
16    }
17}
18
19///////////////////////////////////////////////////////////////////////////////////////////////////
20pub(crate) trait FilterBlockOptionExt {
21    fn union(self, other: Self) -> Self;
22}
23
24impl FilterBlockOptionExt for FilterBlockOption {
25    fn union(self: FilterBlockOption, other: FilterBlockOption) -> FilterBlockOption {
26        let a = self;
27        let b = other;
28
29        match (a, b) {
30            (FilterBlockOption::AtBlockHash(h_a), FilterBlockOption::AtBlockHash(h_b))
31                if h_a == h_b =>
32            {
33                a
34            }
35            (
36                FilterBlockOption::Range {
37                    from_block: Some(from_a),
38                    to_block: Some(to_a),
39                },
40                FilterBlockOption::Range {
41                    from_block: Some(from_b),
42                    to_block: Some(to_b),
43                },
44            ) => FilterBlockOption::Range {
45                from_block: Some(from_a.max(from_b)),
46                to_block: Some(to_a.min(to_b)),
47            },
48            _ => panic!("Can't create a union of block ranges {a:?} and {b:?}"),
49        }
50    }
51}
52
53///////////////////////////////////////////////////////////////////////////////////////////////////
54
55pub(crate) trait BlockNumberOrTagExt {
56    fn min(self, other: Self) -> Self;
57    fn max(self, other: Self) -> Self;
58}
59
60impl BlockNumberOrTagExt for BlockNumberOrTag {
61    fn min(self: BlockNumberOrTag, other: BlockNumberOrTag) -> BlockNumberOrTag {
62        let a = self;
63        let b = other;
64
65        match (a, b) {
66            (BlockNumberOrTag::Number(a), BlockNumberOrTag::Number(b)) => {
67                BlockNumberOrTag::Number(u64::min(a, b))
68            }
69            (BlockNumberOrTag::Number(_), _) => a,
70            (BlockNumberOrTag::Latest, _) => b,
71            (BlockNumberOrTag::Safe, BlockNumberOrTag::Latest) => BlockNumberOrTag::Safe,
72            (BlockNumberOrTag::Safe, _) => b,
73            (BlockNumberOrTag::Finalized, BlockNumberOrTag::Latest | BlockNumberOrTag::Safe) => {
74                BlockNumberOrTag::Finalized
75            }
76            (BlockNumberOrTag::Finalized, _) => b,
77
78            _ => unreachable!(),
79        }
80    }
81
82    fn max(self: BlockNumberOrTag, other: BlockNumberOrTag) -> BlockNumberOrTag {
83        let a = self;
84        let b = other;
85
86        match (a, b) {
87            (BlockNumberOrTag::Earliest, _) => b,
88            (_, BlockNumberOrTag::Earliest) => a,
89            (BlockNumberOrTag::Number(a), BlockNumberOrTag::Number(b)) => {
90                BlockNumberOrTag::Number(u64::max(a, b))
91            }
92            _ => unreachable!(),
93        }
94    }
95}