1use std::time::Duration;
2use uuid::Uuid;
3
4#[derive(Debug, Clone, Hash, Eq, PartialEq)]
5pub enum Filter {
6 Address(String),
7 Characteristic(Uuid),
8 Name(String),
9 Rssi(i16),
10 Service(Uuid),
11}
12
13#[derive(Default)]
14pub struct ScanConfig {
15 pub(crate) adapter_index: usize,
17 pub(crate) filters: Vec<Filter>,
19 pub(crate) address_filter: Option<Box<dyn Fn(&str) -> bool + Send + Sync>>,
21 pub(crate) name_filter: Option<Box<dyn Fn(&str) -> bool + Send + Sync>>,
23 pub(crate) rssi_filter: Option<Box<dyn Fn(i16) -> bool + Send + Sync>>,
25 pub(crate) service_filter: Option<Box<dyn Fn(&Vec<Uuid>, &Uuid) -> bool + Send + Sync>>,
27 pub(crate) characteristics_filter: Option<Box<dyn Fn(&Vec<Uuid>) -> bool + Send + Sync>>,
29 pub(crate) max_results: Option<usize>,
31 pub(crate) timeout: Option<Duration>,
33 pub(crate) force_disconnect: bool,
35}
36
37impl ScanConfig {
38 #[inline]
40 pub fn adapter_index(mut self, index: usize) -> Self {
41 self.adapter_index = index;
42 self
43 }
44
45 #[inline]
46 pub fn with_filters(mut self, filters: &[Filter]) -> Self {
47 self.filters.extend_from_slice(filters);
48 self
49 }
50
51 #[inline]
53 pub fn filter_by_address(
54 mut self,
55 func: impl Fn(&str) -> bool + Send + Sync + 'static,
56 ) -> Self {
57 self.address_filter = Some(Box::new(func));
58 self
59 }
60
61 #[inline]
63 pub fn filter_by_name(mut self, func: impl Fn(&str) -> bool + Send + Sync + 'static) -> Self {
64 self.name_filter = Some(Box::new(func));
65 self
66 }
67
68 #[inline]
69 pub fn filter_by_rssi(mut self, func: impl Fn(i16) -> bool + Send + Sync + 'static) -> Self {
70 self.rssi_filter = Some(Box::new(func));
71 self
72 }
73
74 #[inline]
75 pub fn filter_by_service(
76 mut self,
77 func: impl Fn(&Vec<Uuid>, &Uuid) -> bool + Send + Sync + 'static,
78 ) -> Self {
79 self.service_filter = Some(Box::new(func));
80 self
81 }
82
83 #[inline]
85 pub fn filter_by_characteristics(
86 mut self,
87 func: impl Fn(&Vec<Uuid>) -> bool + Send + Sync + 'static,
88 ) -> Self {
89 self.characteristics_filter = Some(Box::new(func));
90 self
91 }
92
93 #[inline]
95 pub fn stop_after_matches(mut self, max_results: usize) -> Self {
96 self.max_results = Some(max_results);
97 self
98 }
99
100 #[inline]
102 pub fn stop_after_first_match(self) -> Self {
103 self.stop_after_matches(1)
104 }
105
106 #[inline]
108 pub fn stop_after_timeout(mut self, timeout: Duration) -> Self {
109 self.timeout = Some(timeout);
110 self
111 }
112
113 #[inline]
114 pub fn force_disconnect(mut self, force_disconnect: bool) -> Self {
115 self.force_disconnect = force_disconnect;
116 self
117 }
118
119 #[inline]
121 pub fn require_name(self) -> Self {
122 if self.name_filter.is_none() {
123 self.filter_by_name(|src| !src.is_empty())
124 } else {
125 self
126 }
127 }
128}