datafusion-ethers 55.1.0

Ethereum RPC bridge for Apache Datafusion
Documentation
use alloy_rpc_types_eth::{BlockNumberOrTag, Filter, FilterBlockOption};

///////////////////////////////////////////////////////////////////////////////////////////////////

pub(crate) trait FilterExt {
    fn union(self, from: BlockNumberOrTag, to: BlockNumberOrTag) -> Self;
}

impl FilterExt for Filter {
    fn union(mut self, from: BlockNumberOrTag, to: BlockNumberOrTag) -> Self {
        self.block_option = self.block_option.union(FilterBlockOption::Range {
            from_block: Some(from),
            to_block: Some(to),
        });
        self
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
pub(crate) trait FilterBlockOptionExt {
    fn union(self, other: Self) -> Self;
}

impl FilterBlockOptionExt for FilterBlockOption {
    fn union(self: FilterBlockOption, other: FilterBlockOption) -> FilterBlockOption {
        let a = self;
        let b = other;

        match (a, b) {
            (FilterBlockOption::AtBlockHash(h_a), FilterBlockOption::AtBlockHash(h_b))
                if h_a == h_b =>
            {
                a
            }
            (
                FilterBlockOption::Range {
                    from_block: Some(from_a),
                    to_block: Some(to_a),
                },
                FilterBlockOption::Range {
                    from_block: Some(from_b),
                    to_block: Some(to_b),
                },
            ) => FilterBlockOption::Range {
                from_block: Some(from_a.max(from_b)),
                to_block: Some(to_a.min(to_b)),
            },
            _ => panic!("Can't create a union of block ranges {a:?} and {b:?}"),
        }
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

pub(crate) trait BlockNumberOrTagExt {
    fn min(self, other: Self) -> Self;
    fn max(self, other: Self) -> Self;
}

impl BlockNumberOrTagExt for BlockNumberOrTag {
    fn min(self: BlockNumberOrTag, other: BlockNumberOrTag) -> BlockNumberOrTag {
        let a = self;
        let b = other;

        match (a, b) {
            (BlockNumberOrTag::Number(a), BlockNumberOrTag::Number(b)) => {
                BlockNumberOrTag::Number(u64::min(a, b))
            }
            (BlockNumberOrTag::Number(_), _) => a,
            (BlockNumberOrTag::Latest, _) => b,
            (BlockNumberOrTag::Safe, BlockNumberOrTag::Latest) => BlockNumberOrTag::Safe,
            (BlockNumberOrTag::Safe, _) => b,
            (BlockNumberOrTag::Finalized, BlockNumberOrTag::Latest | BlockNumberOrTag::Safe) => {
                BlockNumberOrTag::Finalized
            }
            (BlockNumberOrTag::Finalized, _) => b,

            _ => unreachable!(),
        }
    }

    fn max(self: BlockNumberOrTag, other: BlockNumberOrTag) -> BlockNumberOrTag {
        let a = self;
        let b = other;

        match (a, b) {
            (BlockNumberOrTag::Earliest, _) => b,
            (_, BlockNumberOrTag::Earliest) => a,
            (BlockNumberOrTag::Number(a), BlockNumberOrTag::Number(b)) => {
                BlockNumberOrTag::Number(u64::max(a, b))
            }
            _ => unreachable!(),
        }
    }
}