Skip to content

Commit d4ef65f

Browse files
committed
Add associated type bounds where viable.
Move info from argument to returned value using this.
1 parent 404645e commit d4ef65f

File tree

7 files changed

+432
-306
lines changed

7 files changed

+432
-306
lines changed

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ async-std = { version = "1.4.0", optional = true }
2929
libc = { version = "0.2.71", optional = true }
3030
byteorder = { version = "1.3.4", optional = true }
3131
rolling-stats = { version = "0.3.0", optional = true }
32-
32+
thiserror = { version = "1.0.30", optional = true }
3333

3434
[dependencies.chrono]
3535
version = "0.4.19"
@@ -39,3 +39,5 @@ default_features = false
3939
version = "0.7.1"
4040
optional = true
4141

42+
[dev-dependencies]
43+
anyhow = "1.0.44"

src/blocking.rs

Lines changed: 81 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
//! Blocking APIs on top of the base radio traits
2-
//!
3-
//! These implementations use the radio's DelayUs implementation to
2+
//!
3+
//! These implementations use the radio's DelayUs implementation to
44
//! poll on completion of operations.
5-
//!
5+
//!
66
//! ## https://github.com/ryankurte/rust-radio
77
//! ## Copyright 2020 Ryan Kurte
88
9+
use core::fmt::Debug;
910
use core::time::Duration;
1011

1112
use embedded_hal::delay::blocking::DelayUs;
1213

13-
#[cfg(feature="structopt")]
14+
#[cfg(feature = "structopt")]
1415
use structopt::StructOpt;
1516

16-
#[cfg(feature="std")]
17+
#[cfg(feature = "std")]
1718
use crate::std::string::ToString;
1819

19-
use crate::{Transmit, Receive, State};
20+
use crate::{Receive, State, Transmit};
2021

2122
/// BlockingOptions for blocking radio functions
2223
#[derive(Clone, PartialEq, Debug)]
23-
#[cfg_attr(feature="structopt", derive(StructOpt))]
24+
#[cfg_attr(feature = "structopt", derive(StructOpt))]
2425
pub struct BlockingOptions {
2526
/// Interval for polling for device state
2627
#[cfg_attr(feature="structopt", structopt(long, default_value="100us", parse(try_from_str=crate::duration_from_str)))]
@@ -42,20 +43,25 @@ impl Default for BlockingOptions {
4243

4344
/// BlockingError wraps radio error type to provie a `Timeout` variant
4445
#[derive(Clone, Debug, PartialEq)]
46+
#[cfg_attr(feature = "thiserror", derive(thiserror::Error))]
4547
pub enum BlockingError<E> {
48+
#[cfg_attr(feature = "thiserror", error("Inner: {0}"))]
4649
Inner(E),
50+
#[cfg_attr(feature = "thiserror", error("Timeout"))]
4751
Timeout,
4852
}
4953

50-
impl <E> From<E> for BlockingError<E> {
54+
impl<E> From<E> for BlockingError<E> {
5155
fn from(e: E) -> Self {
5256
BlockingError::Inner(e)
5357
}
5458
}
5559

56-
/// Blocking transmit function implemented over `radio::Transmit` and `radio::Power` using the provided
60+
/// Blocking transmit function implemented over `radio::Transmit` and `radio::Power` using the provided
5761
/// `BlockingOptions` and radio-internal `DelayUs` impl to poll for completion
58-
#[cfg_attr(feature = "mock", doc = r##"
62+
#[cfg_attr(
63+
feature = "mock",
64+
doc = r##"
5965
```
6066
# use radio::*;
6167
# use radio::mock::*;
@@ -75,18 +81,27 @@ assert_eq!(res, Ok(()));
7581
7682
# radio.done();
7783
```
78-
"##)]
84+
"##
85+
)]
7986
///
80-
pub trait BlockingTransmit<E> {
81-
fn do_transmit(&mut self, data: &[u8], tx_options: BlockingOptions) -> Result<(), BlockingError<E>>;
87+
pub trait BlockingTransmit<E: Debug> {
88+
fn do_transmit(
89+
&mut self,
90+
data: &[u8],
91+
tx_options: BlockingOptions,
92+
) -> Result<(), BlockingError<E>>;
8293
}
8394

84-
impl <T, E> BlockingTransmit<E> for T
85-
where
95+
impl<T, E> BlockingTransmit<E> for T
96+
where
8697
T: Transmit<Error = E> + DelayUs<u32>,
87-
E: core::fmt::Debug,
98+
E: Debug,
8899
{
89-
fn do_transmit(&mut self, data: &[u8], tx_options: BlockingOptions) -> Result<(), BlockingError<E>> {
100+
fn do_transmit(
101+
&mut self,
102+
data: &[u8],
103+
tx_options: BlockingOptions,
104+
) -> Result<(), BlockingError<E>> {
90105
// Enter transmit mode
91106
self.start_transmit(data)?;
92107

@@ -98,12 +113,12 @@ where
98113
debug!("Blocking send complete");
99114
break;
100115
}
101-
116+
102117
// Update poll time and timeout if overrun
103118
c += tx_options.poll_interval.as_micros();
104119
if c > t {
105120
debug!("Blocking send timeout");
106-
return Err(BlockingError::Timeout)
121+
return Err(BlockingError::Timeout);
107122
}
108123

109124
// Wait for next poll
@@ -114,9 +129,11 @@ where
114129
}
115130
}
116131

117-
/// Blocking receive function implemented over `radio::Receive` using the provided `BlockingOptions`
132+
/// Blocking receive function implemented over `radio::Receive` using the provided `BlockingOptions`
118133
/// and radio-internal `DelayUs` impl to poll for completion
119-
#[cfg_attr(feature = "mock", doc = r##"
134+
#[cfg_attr(
135+
feature = "mock",
136+
doc = r##"
120137
```
121138
# use radio::*;
122139
# use radio::mock::*;
@@ -125,7 +142,6 @@ use radio::blocking::{BlockingReceive, BlockingOptions};
125142
let data = [0xaa, 0xbb];
126143
let info = BasicInfo::new(-81, 0);
127144
128-
129145
# let mut radio = MockRadio::new(&[
130146
# Transaction::start_receive(None),
131147
# Transaction::check_receive(true, Ok(false)),
@@ -135,45 +151,57 @@ let info = BasicInfo::new(-81, 0);
135151
# ]);
136152
#
137153
154+
// Setup buffer to read into
138155
let mut buff = [0u8; 128];
139-
let mut i = BasicInfo::new(0, 0);
140156
141157
// Receive using a blocking call
142-
let res = radio.do_receive(&mut buff, &mut i, BlockingOptions::default());
158+
let (n, info) = radio.do_receive(&mut buff, BlockingOptions::default())?;
143159
144-
assert_eq!(res, Ok(data.len()));
160+
assert_eq!(n, data.len());
145161
assert_eq!(&buff[..data.len()], &data);
146162
147163
# radio.done();
164+
165+
# Ok::<(), anyhow::Error>(())
148166
```
149-
"##)]
150-
///
167+
"##
168+
)]
169+
///
151170
pub trait BlockingReceive<I, E> {
152-
fn do_receive(&mut self, buff: &mut [u8], info: &mut I, rx_options: BlockingOptions) -> Result<usize, BlockingError<E>>;
171+
fn do_receive(
172+
&mut self,
173+
buff: &mut [u8],
174+
rx_options: BlockingOptions,
175+
) -> Result<(usize, I), BlockingError<E>>;
153176
}
154177

155-
impl <T, I, E> BlockingReceive<I, E> for T
178+
impl<T, I, E> BlockingReceive<I, E> for T
156179
where
157-
T: Receive<Info=I, Error=E> + DelayUs<u32>,
158-
I: core::fmt::Debug,
159-
E: core::fmt::Debug,
180+
T: Receive<Info = I, Error = E> + DelayUs<u32>,
181+
<T as Receive>::Info: Debug,
182+
I: Debug,
183+
E: Debug,
160184
{
161-
fn do_receive(&mut self, buff: &mut [u8], info: &mut I, rx_options: BlockingOptions) -> Result<usize, BlockingError<E>> {
185+
fn do_receive(
186+
&mut self,
187+
buff: &mut [u8],
188+
rx_options: BlockingOptions,
189+
) -> Result<(usize, I), BlockingError<E>> {
162190
// Start receive mode
163191
self.start_receive()?;
164192

165193
let t = rx_options.timeout.as_micros();
166194
let mut c = 0;
167195
loop {
168196
if self.check_receive(true)? {
169-
let n = self.get_received(info, buff)?;
170-
return Ok(n)
197+
let (n, i) = self.get_received(buff)?;
198+
return Ok((n, i));
171199
}
172200

173201
c += rx_options.poll_interval.as_micros();
174202
if c > t {
175203
debug!("Blocking receive timeout");
176-
return Err(BlockingError::Timeout)
204+
return Err(BlockingError::Timeout);
177205
}
178206

179207
let _ = self.delay_us(rx_options.poll_interval.as_micros() as u32);
@@ -183,16 +211,24 @@ where
183211

184212
/// BlockingSetState sets the radio state and polls until command completion
185213
pub trait BlockingSetState<S, E> {
186-
fn set_state_checked(&mut self, state: S, options: BlockingOptions) -> Result<(), BlockingError<E>>;
214+
fn set_state_checked(
215+
&mut self,
216+
state: S,
217+
options: BlockingOptions,
218+
) -> Result<(), BlockingError<E>>;
187219
}
188220

189-
impl <T, S, E>BlockingSetState<S, E> for T
190-
where
191-
T: State<State=S, Error=E> + DelayUs<u32>,
192-
S: core::fmt::Debug + core::cmp::PartialEq + Copy,
193-
E: core::fmt::Debug,
221+
impl<T, S, E> BlockingSetState<S, E> for T
222+
where
223+
T: State<State = S, Error = E> + DelayUs<u32>,
224+
S: Debug + core::cmp::PartialEq + Copy,
225+
E: Debug,
194226
{
195-
fn set_state_checked(&mut self, state: S, options: BlockingOptions) -> Result<(), BlockingError<E>> {
227+
fn set_state_checked(
228+
&mut self,
229+
state: S,
230+
options: BlockingOptions,
231+
) -> Result<(), BlockingError<E>> {
196232
// Send set state command
197233
self.set_state(state)?;
198234

@@ -205,20 +241,18 @@ where
205241

206242
// Check for expected state
207243
if state == s {
208-
return Ok(())
244+
return Ok(());
209245
}
210246

211247
// Timeout eventually
212248
c += options.poll_interval.as_micros();
213249
if c > t {
214250
debug!("Blocking receive timeout");
215-
return Err(BlockingError::Timeout)
251+
return Err(BlockingError::Timeout);
216252
}
217253

218254
// Delay before next loop
219255
let _ = self.delay_us(options.poll_interval.as_micros() as u32);
220256
}
221-
222257
}
223258
}
224-

src/config.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ pub enum ConfigOption {
2424
/// Transmit power (dBm)
2525
TXPower(i16),
2626

27-
2827
/// Await Clear Channel before TX (if supported)
2928
AwaitCCA(bool),
3029
/// CCA threshold in dBm (used if AwaitCCA is set)
@@ -45,7 +44,7 @@ pub enum ConfigError<E> {
4544
NotSupported,
4645

4746
/// Other (device, non-configuration errors)
48-
Other(E)
47+
Other(E),
4948
}
5049

5150
/// Configure trait implemented by configurable radios
@@ -62,4 +61,3 @@ pub trait Configure {
6261
/// Returns Ok(true) on successful get, Ok(false) for unsupported options, Err(Self::Error) for errors
6362
fn get_option(&mut self, o: &mut ConfigOption) -> Result<(), ConfigError<Self::Error>>;
6463
}
65-

0 commit comments

Comments
 (0)