You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: filter.rs
    path of file: ./repos/parity-ethereum/ethcore/trace/src/types
    
    the code of the file until where you have to start completion: // Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.

// Parity Ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity Ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity Ethereum.  If not, see <http://www.gnu.org/licenses/>.

//! Trace filters type definitions

use std::ops::Range;
use ethereum_types::{Address, Bloom, BloomInput};
use crate::{flat::FlatTrace, trace::{Action, Res}};

/// Addresses filter.
///
/// Used to create bloom possibilities and match filters.
#[derive(Debug)]
pub struct AddressesFilter {
	list: Vec<Address>
}

impl From<Vec<Address>> for AddressesFilter {
	fn from(addresses: Vec<Address>) -> Self {
		AddressesFilter { list: addresses }
	}
}

impl AddressesFilter {
	/// Returns true if address matches one of the searched addresses.
	pub fn matches(&self, address: &Address) -> bool {
		self.matches_all() || self.list.contains(address)
	}

	/// Returns true if this address filter matches everything.
	pub fn matches_all(&self) -> bool {
		self.list.is_empty()
	}

	/// Returns blooms of this addresses filter.
	pub fn blooms(&self) -> Vec<Bloom> {
		match self.list.is_empty() {
			true => vec![Bloom::default()],
			false => self.list.iter()
				.map(|address| Bloom::from(BloomInput::Raw(address.as_bytes())))
				.collect(),
		}
	}

	/// Returns vector of blooms zipped with blooms of this addresses filter.
	pub fn with_blooms(&self, blooms: Vec<Bloom>) -> Vec<Bloom> {
		match self.list.is_empty() {
			true => blooms,
			false => blooms
				.into_iter()
				.flat_map(|bloom| self.list.iter()
					.map(|address| {
						let mut bloom = bloom.clone();
						bloom.accrue(BloomInput::Raw(address.as_bytes()));
						bloom
					})
					.collect::<Vec<_>>())
				.collect(),
		}
	}
}

#[derive(Debug)]
/// Traces filter.
pub struct Filter {
	/// Block range.
	pub range: Range<usize>,

	/// From address filter.
	pub from_address: AddressesFilter,

	/// To address filter.
	pub to_address: AddressesFilter,
}

impl Filter {
	/// Returns combinations of each address.
	pub fn bloom_possibilities(&self) -> Vec<Bloom> {
		self.to_address.with_blooms(self.from_address.blooms())
	}

	/// Returns true if given trace matches the filter.
	pub fn matches(&self, trace: &FlatTrace) -> bool {
		match trace.action {
			Action::Call(ref call) => {
				let from_matches = self.from_address.matches(&call.from);
				let to_matches = self.to_address.matches(&call.to);
				f
    
	fn filter_matches() {
		let f0 = Filter {
			range: (0..0),
			from_address: AddressesFilter::from(vec![Address::from_low_u64_be(1)]),
			to_address: AddressesFilter::from(vec![]),
		};

		let f1 = Filter {
			range: (0..0),
			from_address: AddressesFilter::from(vec![Address::from_low_u64_be(3), Address::from_low_u64_be(1)]),
			to_address: AddressesFilter::from(vec![]),
		};

		let f2 = Filter {
			range: (0..0),
			from_address: AddressesFilter::from(vec![]),
			to_address: AddressesFilter::from(vec![]),
		};

		let f3 = Filter {
			range: (0..0),
			from_address: AddressesFilter::from(vec![]),
			to_address: AddressesFilter::from(vec![Address::from_low_u64_be(2)]),
		};

		let f4 = Filter {
			range: (0..0),
			from_address: AddressesFilter::from(vec![]),
			to_address: AddressesFilter::from(vec![Address::from_low_u64_be(2), Address::from_low_u64_be(3)]),
		};

		let f5 = Filter {
			range: (0..0),
			from_address: AddressesFilter::from(vec![Address::from_low_u64_be(1)]),
			to_address: AddressesFilter::from(vec![Address::from_low_u64_be(2), Address::from_low_u64_be(3)]),
		};

		let f6 = Filter {
			range: (0..0),
			from_address: AddressesFilter::from(vec![Address::from_low_u64_be(1)]),
			to_address: AddressesFilter::from(vec![Address::from_low_u64_be(4)]),
		};

		let trace = FlatTrace {
			action: Action::Call(Call {
				from: Address::from_low_u64_be(1),
				to: Address::from_low_u64_be(2),
				value: 3.into(),
				gas: 4.into(),
				input: vec![0x5],
				call_type: Some(CallType::Call).into(),
			}),
			result: Res::FailedCall(TraceError::OutOfGas),
			trace_address: vec![0].into_iter().collect(),
			subtraces: 0,
		};

		assert!(f0.matches(&trace));
		assert!(f1.matches(&trace));
		assert!(f2.matches(&trace));
		assert!(f3.matches(&trace));
		assert!(f4.matches(&trace));
		assert!(f5.matches(&trace));
		assert!(!f6.matches(&trace));

		let trace = FlatTrace {
			action: Action::Create(Create {
				from: Address::from_low_u64_be(1),
				value: 3.into(),
				gas: 4.into(),
				init: vec![0x5],
				creation_method: Some(CreationMethod::Create),
			}),
			result: Res::Create(CreateResult {
				gas_used: 10.into(),
				code: vec![],
				address: Address::from_low_u64_be(2),
			}),
			trace_address: vec![0].into_iter().collect(),
			subtraces: 0,
		};

		assert!(f0.matches(&trace));
		assert!(f1.matches(&trace));
		assert!(f2.matches(&trace));
		assert!(f3.matches(&trace));
		assert!(f4.matches(&trace));
		assert!(f5.matches(&trace));
		assert!(!f6.matches(&trace));

		let trace = FlatTrace {
			action: Action::Suicide(Suicide {
				address: Address::from_low_u64_be(1),
				refund_address: Address::from_low_u64_be(2),
				balance: 3.into(),
			}),
			result: Res::None,
			trace_address: vec![].into_iter().collect(),
			subtraces: 0
		};

		assert!(f0.matches(&trace));
		assert!(f1.matches(&trace));
		assert!(f2.matches(&trace));
		assert!(f3.matches(&trace));
		assert!(f4.matches(&trace));
		assert!(f5.matches(&trace));
		assert!(!f6.matches(&trace));

		let trace = FlatTrace {
			action: Action::Reward(Reward {
				author: Address::from_low_u64_be(2),
				value: 100.into(),
				reward_type: RewardType::Block,
			}),
			result: Res::None,
			trace_address: vec![].into_iter().collect(),
			subtraces: 0
		};

		assert!(!f0.matches(&trace));
		assert!(!f1.matches(&trace));
		assert!(f2.matches(&trace));
		assert!(f3.matches(&trace));
		assert!(f4.matches(&trace));
		assert!(!f5.matches(&trace));
		assert!(!f6.matches(&trace));
	}