Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// override the default setting (`cargo check --all-targets`) which produces the following error
// "can't find crate for `test`" when the default compilation target is a no_std target
// with these changes RA will call `cargo check --bins` on save
"rust-analyzer.checkOnSave.allTargets": false,
"rust-analyzer.cargo.target": "thumbv6m-none-eabi",
"rust-analyzer.diagnostics.disabled": [
"unresolved-import"
Expand Down
10 changes: 5 additions & 5 deletions atat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ name = "atat"
embedded-io = "0.6"
embedded-io-async = "0.6"
futures = { version = "0.3", default-features = false }
embassy-sync = "0.6"
embassy-time = "0.4"
embassy-sync = "0.7.2"
embassy-time = "0.5.0"
embassy-futures = "0.1"
heapless = { version = "^0.8", features = ["serde"] }
heapless = { version = "^0.9", features = ["serde"] }
thiserror = { version = "2", default-features = false }
serde_at = { path = "../serde_at", version = "^0.24.1", optional = true }
atat_derive = { path = "../atat_derive", version = "^0.24.1", optional = true }
Expand All @@ -38,7 +38,7 @@ log = { version = "^0.4", default-features = false, optional = true }
defmt = { version = "^0.3", optional = true }

[dev-dependencies]
embassy-time = { version = "0.4", features = ["std"] }
embassy-time = { version = "0.5", features = ["std", "generic-queue-8"] }
critical-section = { version = "1.1", features = ["std"] }
serde_at = { path = "../serde_at", version = "^0.24.1", features = [
"heapless",
Expand All @@ -48,7 +48,7 @@ static_cell = { version = "2.0.0" }

[features]
default = ["derive", "bytes"]
defmt = ["dep:defmt", "embedded-io-async/defmt-03", "heapless/defmt-03"]
defmt = ["dep:defmt", "embedded-io-async/defmt-03", "heapless/defmt"]
derive = ["atat_derive", "serde_at"]
bytes = ["heapless-bytes", "serde_bytes"]
custom-error-messages = []
Expand Down
11 changes: 8 additions & 3 deletions atat/src/asynch/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@
}

impl<'a, W: Write, const INGRESS_BUF_SIZE: usize> Client<'a, W, INGRESS_BUF_SIZE> {
pub fn new(
writer: W,
res_slot: &'a ResponseSlot<INGRESS_BUF_SIZE>,
buf: &'a mut [u8],
config: Config,
) -> Self {
Self {
writer,
res_slot,
buf,
config,
cooldown_timer: None,
}
}

Check warning on line 36 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

this could be a `const fn`

warning: this could be a `const fn` --> atat/src/asynch/client.rs:23:5 | 23 | / pub fn new( 24 | | writer: W, 25 | | res_slot: &'a ResponseSlot<INGRESS_BUF_SIZE>, 26 | | buf: &'a mut [u8], ... | 36 | | } | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#missing_const_for_fn = note: `-W clippy::missing-const-for-fn` implied by `-W clippy::nursery` = help: to override `-W clippy::nursery` add `#[allow(clippy::missing_const_for_fn)]` help: make the function `const` | 23 | pub const fn new( | +++++

async fn send_request(&mut self, len: usize) -> Result<(), Error> {
if len < 50 {
Expand Down Expand Up @@ -65,8 +65,8 @@
Ok(())
}

async fn wait_response<'guard>(

Check warning on line 68 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'guard

warning: the following explicit lifetimes could be elided: 'guard --> atat/src/asynch/client.rs:68:28 | 68 | async fn wait_response<'guard>( | ^^^^^^ 69 | &'guard mut self, | ^^^^^^ 70 | timeout: Duration, 71 | ) -> Result<ResponseSlotGuard<'guard, INGRESS_BUF_SIZE>, Error> { | ^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#elidable_lifetime_names
&'guard mut self,

Check warning on line 69 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

this argument is a mutable reference, but not used mutably

warning: this argument is a mutable reference, but not used mutably --> atat/src/asynch/client.rs:69:9 | 69 | &'guard mut self, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&self` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#needless_pass_by_ref_mut = note: `-W clippy::needless-pass-by-ref-mut` implied by `-W clippy::nursery` = help: to override `-W clippy::nursery` add `#[allow(clippy::needless_pass_by_ref_mut)]`
timeout: Duration,
) -> Result<ResponseSlotGuard<'guard, INGRESS_BUF_SIZE>, Error> {

Check warning on line 71 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

future cannot be sent between threads safely

warning: future cannot be sent between threads safely --> atat/src/asynch/client.rs:68:5 | 68 | / async fn wait_response<'guard>( 69 | | &'guard mut self, 70 | | timeout: Duration, 71 | | ) -> Result<ResponseSlotGuard<'guard, INGRESS_BUF_SIZE>, Error> { | |___________________________________________________________________^ future returned by `wait_response` is not `Send` | note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send` --> atat/src/asynch/client.rs:69:9 | 69 | &'guard mut self, | ^^^^^^^^^^^^^^^^ has type `&mut asynch::client::Client<'a, W, INGRESS_BUF_SIZE>` which is not `Send`, because `asynch::client::Client<'a, W, INGRESS_BUF_SIZE>` is not `Send` = note: `W` doesn't implement `core::marker::Send` note: future is not `Send` as this value is used across an await --> atat/src/asynch/client.rs:88:57 | 78 | &self, | ----- has type `&asynch::client::Client<'_, W, INGRESS_BUF_SIZE>` which is not `Send` ... 88 | fut = match select(fut, Timer::at(expires)).await { | ^^^^^ await occurs here, with `&self` maybe used later = note: `W` doesn't implement `core::marker::Sync` = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#future_not_send
self.with_timeout(timeout, self.res_slot.get())
Expand All @@ -74,11 +74,11 @@
.map_err(|_| Error::Timeout)
}

async fn with_timeout<F: Future>(
&self,
timeout: Duration,
fut: F,
) -> Result<F::Output, TimeoutError> {

Check warning on line 81 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

future cannot be sent between threads safely

warning: future cannot be sent between threads safely --> atat/src/asynch/client.rs:77:5 | 77 | / async fn with_timeout<F: Future>( 78 | | &self, 79 | | timeout: Duration, 80 | | fut: F, 81 | | ) -> Result<F::Output, TimeoutError> { | |________________________________________^ future returned by `with_timeout` is not `Send` | note: future is not `Send` as this value is used across an await --> atat/src/asynch/client.rs:88:57 | 85 | pin_mut!(fut); | ------------- has type `F` which is not `Send` ... 88 | fut = match select(fut, Timer::at(expires)).await { | ^^^^^ await occurs here, with `mut $x` maybe used later = note: `F` doesn't implement `core::marker::Send` note: future is not `Send` as this value is used across an await --> atat/src/asynch/client.rs:88:57 | 78 | &self, | ----- has type `&asynch::client::Client<'_, W, INGRESS_BUF_SIZE>` which is not `Send` ... 88 | fut = match select(fut, Timer::at(expires)).await { | ^^^^^ await occurs here, with `&self` maybe used later = note: `W` doesn't implement `core::marker::Sync` = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#future_not_send
let start = Instant::now();
let mut expires = (self.config.get_response_timeout)(start, timeout);

Expand All @@ -87,7 +87,7 @@
loop {
fut = match select(fut, Timer::at(expires)).await {
Either::Left((r, _)) => return Ok(r),
Either::Right((_, fut)) => {

Check warning on line 90 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

matching over `()` is more explicit

warning: matching over `()` is more explicit --> atat/src/asynch/client.rs:90:32 | 90 | Either::Right((_, fut)) => { | ^ help: use `()` instead of `_`: `()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#ignored_unit_patterns = note: `-W clippy::ignored-unit-patterns` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::ignored_unit_patterns)]`
let new_expires = (self.config.get_response_timeout)(start, timeout);
if new_expires <= expires {
return Err(TimeoutError);
Expand All @@ -105,24 +105,24 @@

async fn wait_cooldown_timer(&mut self) {
if let Some(cooldown) = self.cooldown_timer.take() {
cooldown.await

Check warning on line 108 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

consider adding a `;` to the last statement for consistent formatting

warning: consider adding a `;` to the last statement for consistent formatting --> atat/src/asynch/client.rs:108:13 | 108 | cooldown.await | ^^^^^^^^^^^^^^ help: add a `;` here: `cooldown.await;` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#semicolon_if_nothing_returned
}
}
}

impl<W: Write, const INGRESS_BUF_SIZE: usize> AtatClient for Client<'_, W, INGRESS_BUF_SIZE> {
async fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> {
let len = cmd.write(&mut self.buf);
let len = cmd.write(self.buf);
self.send_request(len).await?;
if !Cmd::EXPECTS_RESPONSE_CODE {
cmd.parse(Ok(&[]))
} else {
let response = self
.wait_response(Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))
.await?;
let response: &Response<INGRESS_BUF_SIZE> = &response.borrow();
cmd.parse(response.into())
}

Check warning on line 125 in atat/src/asynch/client.rs

View workflow job for this annotation

GitHub Actions / clippy

unnecessary boolean `not` operation

warning: unnecessary boolean `not` operation --> atat/src/asynch/client.rs:117:9 | 117 | / if !Cmd::EXPECTS_RESPONSE_CODE { 118 | | cmd.parse(Ok(&[])) 119 | | } else { 120 | | let response = self ... | 124 | | cmd.parse(response.into()) 125 | | } | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#if_not_else = note: `-W clippy::if-not-else` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::if_not_else)]` help: try | 117 ~ if Cmd::EXPECTS_RESPONSE_CODE { 118 + let response = self 119 + .wait_response(Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into())) 120 + .await?; 121 + let response: &Response<INGRESS_BUF_SIZE> = &response.borrow(); 122 + cmd.parse(response.into()) 123 + } else { 124 + cmd.parse(Ok(&[])) 125 + } |
}
}

Expand Down Expand Up @@ -152,6 +152,7 @@

#[derive(Clone, PartialEq, AtatEnum)]
#[at_enum(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum Functionality {
#[at_arg(value = 0)]
Min,
Expand Down Expand Up @@ -183,8 +184,12 @@
static mut BUF: [u8; 1000] = [0; 1000];

let tx_mock = crate::tx_mock::TxMock::new(TX_CHANNEL.publisher().unwrap());
let client: Client<crate::tx_mock::TxMock, TEST_RX_BUF_LEN> =
Client::new(tx_mock, &RES_SLOT, unsafe { BUF.as_mut() }, $config);
let client: Client<crate::tx_mock::TxMock, TEST_RX_BUF_LEN> = Client::new(
tx_mock,
&RES_SLOT,
unsafe { &mut *core::ptr::addr_of_mut!(BUF) },
$config,
);
(client, TX_CHANNEL.subscriber().unwrap(), &RES_SLOT)
}};
}
Expand Down
4 changes: 2 additions & 2 deletions atat/src/asynch/simple_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
}

impl<'a, RW: Read + Write, D: Digester> SimpleClient<'a, RW, D> {
pub fn new(rw: RW, digester: D, buf: &'a mut [u8], config: Config) -> Self {
Self {
rw,
digester,
buf,
config,
pos: 0,
cooldown_timer: None,
}
}

Check warning on line 25 in atat/src/asynch/simple_client.rs

View workflow job for this annotation

GitHub Actions / clippy

this could be a `const fn`

warning: this could be a `const fn` --> atat/src/asynch/simple_client.rs:16:5 | 16 | / pub fn new(rw: RW, digester: D, buf: &'a mut [u8], config: Config) -> Self { 17 | | Self { 18 | | rw, 19 | | digester, ... | 25 | | } | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#missing_const_for_fn help: make the function `const` | 16 | pub const fn new(rw: RW, digester: D, buf: &'a mut [u8], config: Config) -> Self { | +++++

async fn send_request(&mut self, len: usize) -> Result<(), Error> {
if len < 50 {
Expand All @@ -48,14 +48,14 @@
Ok(())
}

async fn wait_response<'guard>(&'guard mut self) -> Result<Response<256>, Error> {
async fn wait_response(&mut self) -> Result<Response<256>, Error> {
loop {
match self.rw.read(&mut self.buf[self.pos..]).await {
Ok(n) => {
self.pos += n;
}
_ => return Err(Error::Read),
};

Check warning on line 58 in atat/src/asynch/simple_client.rs

View workflow job for this annotation

GitHub Actions / clippy

unnecessary semicolon

warning: unnecessary semicolon --> atat/src/asynch/simple_client.rs:58:14 | 58 | }; | ^ help: remove | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#unnecessary_semicolon = note: `-W clippy::unnecessary-semicolon` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::unnecessary_semicolon)]`

trace!(
"Buffer contents: ({:?} bytes) '{:?}'",
Expand Down Expand Up @@ -89,7 +89,7 @@
match &resp {
Ok(r) => {
if r.is_empty() {
debug!("Received OK ({}/{})", swallowed, self.pos)

Check warning on line 92 in atat/src/asynch/simple_client.rs

View workflow job for this annotation

GitHub Actions / clippy

consider adding a `;` to the last statement for consistent formatting

warning: consider adding a `;` to the last statement for consistent formatting --> atat/src/asynch/simple_client.rs:92:37 | 92 | ... debug!("Received OK ({}/{})", swallowed, self.pos) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `debug!("Received OK ({}/{})", swallowed, self.pos);` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#semicolon_if_nothing_returned
} else {
debug!(
"Received response ({}/{}): {:?}",
Expand Down Expand Up @@ -136,27 +136,27 @@

async fn wait_cooldown_timer(&mut self) {
if let Some(cooldown) = self.cooldown_timer.take() {
cooldown.await

Check warning on line 139 in atat/src/asynch/simple_client.rs

View workflow job for this annotation

GitHub Actions / clippy

consider adding a `;` to the last statement for consistent formatting

warning: consider adding a `;` to the last statement for consistent formatting --> atat/src/asynch/simple_client.rs:139:13 | 139 | cooldown.await | ^^^^^^^^^^^^^^ help: add a `;` here: `cooldown.await;` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#semicolon_if_nothing_returned
}
}
}

impl<RW: Read + Write, D: Digester> AtatClient for SimpleClient<'_, RW, D> {
async fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> {

Check warning on line 145 in atat/src/asynch/simple_client.rs

View workflow job for this annotation

GitHub Actions / clippy

future cannot be sent between threads safely

warning: future cannot be sent between threads safely --> atat/src/asynch/simple_client.rs:145:5 | 145 | async fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `send` is not `Send` | note: future is not `Send` as this value is used across an await --> atat/src/asynch/simple_client.rs:148:32 | 145 | async fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> { | --- has type `&Cmd` which is not `Send` ... 148 | self.send_request(len).await?; | ^^^^^ await occurs here, with `cmd` maybe used later = note: `Cmd` doesn't implement `core::marker::Sync` note: future is not `Send` as this value is used across an await --> atat/src/asynch/simple_client.rs:148:32 | 145 | async fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> { | --------- has type `&mut asynch::simple_client::SimpleClient<'_, RW, D>` which is not `Send` ... 148 | self.send_request(len).await?; | ^^^^^ await occurs here, with `&mut self` maybe used later = note: `RW` doesn't implement `core::marker::Send` note: future is not `Send` as this value is used across an await --> atat/src/asynch/simple_client.rs:148:32 | 145 | async fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> { | --------- has type `&mut asynch::simple_client::SimpleClient<'_, RW, D>` which is not `Send` ... 148 | self.send_request(len).await?; | ^^^^^ await occurs here, with `&mut self` maybe used later = note: `D` doesn't implement `core::marker::Send` note: future is not `Send` as it awaits another future which is not `Send` --> atat/src/asynch/simple_client.rs:37:9 | 37 | with_timeout(self.config.tx_timeout, self.rw.write_all(&self.buf[..len])) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `embassy_time::timer::TimeoutFuture<impl futures::Future<Output = core::result::Result<(), <RW as embedded_io::ErrorType>::Error>>>`, which is not `Send` = note: `impl futures::Future<Output = core::result::Result<(), <RW as embedded_io::ErrorType>::Error>>` doesn't implement `core::marker::Send` note: future is not `Send` as it awaits another future which is not `Send` --> atat/src/asynch/simple_client.rs:42:9 | 42 | with_timeout(self.config.flush_timeout, self.rw.flush()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `embassy_time::timer::TimeoutFuture<impl futures::Future<Output = core::result::Result<(), <RW as embedded_io::ErrorType>::Error>>>`, which is not `Send` = note: `impl futures::Future<Output = core::result::Result<(), <RW as embedded_io::ErrorType>::Error>>` doesn't implement `core::marker::Send` note: future is not `Send` as it awaits another future which is not `Send` --> atat/src/asynch/simple_client.rs:53:19 | 53 | match self.rw.read(&mut self.buf[self.pos..]).await { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl futures::Future<Output = core::result::Result<usize, <RW as embedded_io::ErrorType>::Error>>`, which is not `Send` = note: `impl futures::Future<Output = core::result::Result<usize, <RW as embedded_io::ErrorType>::Error>>` doesn't implement `core::marker::Send` = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#future_not_send
let len = cmd.write(&mut self.buf);
let len = cmd.write(self.buf);

self.send_request(len).await?;
if !Cmd::EXPECTS_RESPONSE_CODE {
cmd.parse(Ok(&[]))
} else {
let response = embassy_time::with_timeout(
Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()),
self.wait_response(),
)
.await
.map_err(|_| Error::Timeout)??;

cmd.parse((&response).into())
}

Check warning on line 160 in atat/src/asynch/simple_client.rs

View workflow job for this annotation

GitHub Actions / clippy

unnecessary boolean `not` operation

warning: unnecessary boolean `not` operation --> atat/src/asynch/simple_client.rs:149:9 | 149 | / if !Cmd::EXPECTS_RESPONSE_CODE { 150 | | cmd.parse(Ok(&[])) 151 | | } else { 152 | | let response = embassy_time::with_timeout( ... | 159 | | cmd.parse((&response).into()) 160 | | } | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#if_not_else help: try | 149 ~ if Cmd::EXPECTS_RESPONSE_CODE { 150 + let response = embassy_time::with_timeout( 151 + Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()), 152 + self.wait_response(), 153 + ) 154 + .await 155 + .map_err(|_| Error::Timeout)??; 156 + 157 + cmd.parse((&response).into()) 158 + } else { 159 + cmd.parse(Ok(&[])) 160 + } |
}
}
20 changes: 13 additions & 7 deletions atat/src/blocking/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
AtatCmd, Config, Error, Response,
};

/// Client responsible for handling send, receive and timeout from the
/// userfacing side. The client is decoupled from the ingress-manager through
/// some spsc queue consumers, where any received responses can be dequeued. The
/// Client also has an spsc producer, to allow signaling commands like
/// `reset` to the ingress-manager.

Check warning on line 15 in atat/src/blocking/client.rs

View workflow job for this annotation

GitHub Actions / clippy

first doc comment paragraph is too long

warning: first doc comment paragraph is too long --> atat/src/blocking/client.rs:11:1 | 11 | / /// Client responsible for handling send, receive and timeout from the 12 | | /// userfacing side. The client is decoupled from the ingress-manager through 13 | | /// some spsc queue consumers, where any received responses can be dequeued. The 14 | | /// Client also has an spsc producer, to allow signaling commands like 15 | | /// `reset` to the ingress-manager. | |_^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#too_long_first_doc_paragraph = note: `-W clippy::too-long-first-doc-paragraph` implied by `-W clippy::nursery` = help: to override `-W clippy::nursery` add `#[allow(clippy::too_long_first_doc_paragraph)]`
pub struct Client<'a, W, const INGRESS_BUF_SIZE: usize>
where
W: Write,
Expand All @@ -28,20 +28,20 @@
where
W: Write,
{
pub fn new(
writer: W,
res_slot: &'a ResponseSlot<INGRESS_BUF_SIZE>,
buf: &'a mut [u8],
config: Config,
) -> Self {
Self {
writer,
res_slot,
buf,
cooldown_timer: None,
config,
}
}

Check warning on line 44 in atat/src/blocking/client.rs

View workflow job for this annotation

GitHub Actions / clippy

this could be a `const fn`

warning: this could be a `const fn` --> atat/src/blocking/client.rs:31:5 | 31 | / pub fn new( 32 | | writer: W, 33 | | res_slot: &'a ResponseSlot<INGRESS_BUF_SIZE>, 34 | | buf: &'a mut [u8], ... | 44 | | } | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#missing_const_for_fn help: make the function `const` | 31 | pub const fn new( | +++++

fn send_request(&mut self, len: usize) -> Result<(), Error> {
if len < 50 {
Expand All @@ -65,8 +65,8 @@
Ok(())
}

fn wait_response<'guard>(

Check warning on line 68 in atat/src/blocking/client.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'guard

warning: the following explicit lifetimes could be elided: 'guard --> atat/src/blocking/client.rs:68:22 | 68 | fn wait_response<'guard>( | ^^^^^^ 69 | &'guard mut self, | ^^^^^^ 70 | timeout: Duration, 71 | ) -> Result<ResponseSlotGuard<'guard, INGRESS_BUF_SIZE>, Error> { | ^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#elidable_lifetime_names help: elide the lifetimes | 68 ~ fn wait_response( 69 ~ &mut self, 70 | timeout: Duration, 71 ~ ) -> Result<ResponseSlotGuard<'_, INGRESS_BUF_SIZE>, Error> { |
&'guard mut self,

Check warning on line 69 in atat/src/blocking/client.rs

View workflow job for this annotation

GitHub Actions / clippy

this argument is a mutable reference, but not used mutably

warning: this argument is a mutable reference, but not used mutably --> atat/src/blocking/client.rs:69:9 | 69 | &'guard mut self, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&self` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#needless_pass_by_ref_mut
timeout: Duration,
) -> Result<ResponseSlotGuard<'guard, INGRESS_BUF_SIZE>, Error> {
self.with_timeout(timeout, || self.res_slot.try_get())
Expand Down Expand Up @@ -106,12 +106,12 @@
W: Write,
{
fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> {
let len = cmd.write(&mut self.buf);
let len = cmd.write(self.buf);
self.send_request(len)?;
if !Cmd::EXPECTS_RESPONSE_CODE {
cmd.parse(Ok(&[]))
} else {
let response = self.wait_response(Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))?;

Check warning on line 114 in atat/src/blocking/client.rs

View workflow job for this annotation

GitHub Actions / clippy

temporary with significant `Drop` can be early dropped

warning: temporary with significant `Drop` can be early dropped --> atat/src/blocking/client.rs:114:17 | 113 | } else { | ________________- 114 | | let response = self.wait_response(Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))?; | | ^^^^^^^^ 115 | | let response: &Response<INGRESS_BUF_SIZE> = &response.borrow(); 116 | | cmd.parse(response.into()) 117 | | } | |_________- temporary `response` is currently being dropped at the end of its contained scope | = note: this might lead to unnecessary resource contention = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#significant_drop_tightening help: merge the temporary construction with its single usage | 114 ~ 115 + let response = self.wait_response(Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))?.; 116 ~ |
let response: &Response<INGRESS_BUF_SIZE> = &response.borrow();
cmd.parse(response.into())
}

Check warning on line 117 in atat/src/blocking/client.rs

View workflow job for this annotation

GitHub Actions / clippy

unnecessary boolean `not` operation

warning: unnecessary boolean `not` operation --> atat/src/blocking/client.rs:111:9 | 111 | / if !Cmd::EXPECTS_RESPONSE_CODE { 112 | | cmd.parse(Ok(&[])) 113 | | } else { 114 | | let response = self.wait_response(Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))?; 115 | | let response: &Response<INGRESS_BUF_SIZE> = &response.borrow(); 116 | | cmd.parse(response.into()) 117 | | } | |_________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#if_not_else help: try | 111 ~ if Cmd::EXPECTS_RESPONSE_CODE { 112 + let response = self.wait_response(Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))?; 113 + let response: &Response<INGRESS_BUF_SIZE> = &response.borrow(); 114 + cmd.parse(response.into()) 115 + } else { 116 + cmd.parse(Ok(&[])) 117 + } |
Expand All @@ -132,6 +132,7 @@
const TEST_RX_BUF_LEN: usize = 256;

#[derive(Debug, PartialEq, Eq)]
#[allow(dead_code)]
pub enum InnerError {
Test,
}
Expand Down Expand Up @@ -192,6 +193,7 @@

#[derive(Clone, PartialEq, AtatEnum)]
#[at_enum(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum Functionality {
#[at_arg(value = 0)]
Min,
Expand Down Expand Up @@ -235,6 +237,7 @@
}

#[derive(Debug, Clone, AtatResp, PartialEq)]
#[allow(dead_code)]
pub struct MessageWaitingIndication {
#[at_arg(position = 0)]
pub status: u8,
Expand All @@ -243,6 +246,7 @@
}

#[derive(Debug, Clone, AtatUrc, PartialEq)]
#[allow(dead_code)]
pub enum Urc {
#[at_urc(b"+UMWI")]
MessageWaitingIndication(MessageWaitingIndication),
Expand All @@ -258,8 +262,12 @@
static mut BUF: [u8; 1000] = [0; 1000];

let tx_mock = crate::tx_mock::TxMock::new(TX_CHANNEL.publisher().unwrap());
let client: Client<crate::tx_mock::TxMock, TEST_RX_BUF_LEN> =
Client::new(tx_mock, &RES_SLOT, unsafe { BUF.as_mut() }, $config);
let client: Client<crate::tx_mock::TxMock, TEST_RX_BUF_LEN> = Client::new(
tx_mock,
&RES_SLOT,
unsafe { &mut *core::ptr::addr_of_mut!(BUF) },
$config,
);
(client, TX_CHANNEL.subscriber().unwrap(), &RES_SLOT)
}};
}
Expand All @@ -272,8 +280,7 @@

let sent = tokio::spawn(async move {
tx.next_message_pure().await;
rx.signal_response(Err(InternalError::Error).into())
.unwrap();
rx.signal_response(Err(InternalError::Error)).unwrap();
});

tokio::task::spawn_blocking(move || {
Expand All @@ -296,8 +303,7 @@

let sent = tokio::spawn(async move {
tx.next_message_pure().await;
rx.signal_response(Err(InternalError::Error).into())
.unwrap();
rx.signal_response(Err(InternalError::Error)).unwrap();
});

tokio::task::spawn_blocking(move || {
Expand Down
1 change: 1 addition & 0 deletions atat/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use embassy_time::{Duration, Instant};
///
/// [`Command`]: enum.Command.html
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[allow(unpredictable_function_pointer_comparisons)]
pub struct Config {
pub(crate) cmd_cooldown: Duration,
pub(crate) tx_timeout: Duration,
Expand Down
34 changes: 33 additions & 1 deletion atat/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ use serde_at::HexStr;
/// [`atat_derive`]: https://crates.io/crates/atat_derive
pub trait AtatLen {
const LEN: usize;
const ESCAPED_LEN: usize;
}

#[cfg(feature = "bytes")]
impl<const N: usize> AtatLen for heapless_bytes::Bytes<N> {
const LEN: usize = N;
const ESCAPED_LEN: usize = N;
}

macro_rules! impl_length {
($type:ty, $len:expr) => {
#[allow(clippy::use_self)]
impl AtatLen for $type {
const LEN: usize = $len;
const ESCAPED_LEN: usize = $len;
}
};
}
Expand Down Expand Up @@ -51,27 +54,32 @@ impl_length!(HexStr<u128>, 130);

impl<const T: usize> AtatLen for String<T> {
const LEN: usize = 1 + T + 1;
const ESCAPED_LEN: usize = 3 * T + 2;
}

impl<T: AtatLen> AtatLen for Option<T> {
const LEN: usize = T::LEN;
const ESCAPED_LEN: usize = T::ESCAPED_LEN;
}

impl<T: AtatLen> AtatLen for &T {
const LEN: usize = T::LEN;
const ESCAPED_LEN: usize = T::ESCAPED_LEN;
}

impl<T, const L: usize> AtatLen for Vec<T, L>
where
T: AtatLen,
{
const LEN: usize = L * <T as AtatLen>::LEN;
const ESCAPED_LEN: usize = L * <T as AtatLen>::ESCAPED_LEN;
}

// 0x F:F:F:F
// uN = (2 + (N*4) - 1) * 2 bytes
impl<const L: usize> AtatLen for HexStr<[u8; L]> {
const LEN: usize = (2 + L * 4 - 1) * 2;
const ESCAPED_LEN: usize = (2 + L * 4 - 1) * 2;
}

// Currently, stable rust (version at the time of writing: 1.93)
Expand All @@ -81,6 +89,7 @@ macro_rules! impl_nonzero_length {
($type:ty) => {
impl AtatLen for NonZero<$type> {
const LEN: usize = <$type as AtatLen>::LEN;
const ESCAPED_LEN: usize = <$type as AtatLen>::ESCAPED_LEN;
}
};
}
Expand Down Expand Up @@ -202,8 +211,18 @@ mod tests {
assert_eq!(<f32 as AtatLen>::LEN, 42);
assert_eq!(<f64 as AtatLen>::LEN, 312);

// For non-string primitives, ESCAPED_LEN == LEN
assert_eq!(<u8 as AtatLen>::ESCAPED_LEN, 3);
assert_eq!(<i64 as AtatLen>::ESCAPED_LEN, 20);

// String<T>: LEN = 1 + T + 1 (quotes), ESCAPED_LEN = 3*T + 2
assert_eq!(<String<10> as AtatLen>::LEN, 12);
assert_eq!(<String<10> as AtatLen>::ESCAPED_LEN, 32);

assert_eq!(<SimpleEnum as AtatLen>::LEN, 3);
assert_eq!(<SimpleEnumU32 as AtatLen>::LEN, 10);
assert_eq!(<SimpleEnum as AtatLen>::ESCAPED_LEN, 3);
assert_eq!(<SimpleEnumU32 as AtatLen>::ESCAPED_LEN, 10);

assert_eq!(<HexStr<u8> as AtatLen>::LEN, 10);
assert_eq!(<HexStr<u16> as AtatLen>::LEN, 18);
Expand All @@ -214,18 +233,31 @@ mod tests {
#[cfg(feature = "hex_str_arrays")]
{
assert_eq!(<HexStr<[u8; 16]> as AtatLen>::LEN, 130);
assert_eq!(<HexStr<[u8; 16]> as AtatLen>::ESCAPED_LEN, 130);
}

// (fields) + (n_fields - 1)
// (3 + (1 + 128 + 1) + 2 + (1 + 150 + 1) + 3 + 10 + 3 + (10*5)) + 7
// (3 + (1 + 128 + 1) + 2 + (1 + 150 + 1) + 3 + 10 + 3) + 6
assert_eq!(
<LengthTester<'_> as AtatLen>::LEN,
(3 + (1 + 128 + 1) + 2 + (1 + 150 + 1) + 3 + 10 + 3) + 6
);
// ESCAPED_LEN: String<128> -> 3*128+2=386, &str len=150 -> 3*150+2=452
// (3 + 386 + 2 + 452 + 3 + 10 + 3) + 6
assert_eq!(
<LengthTester<'_> as AtatLen>::ESCAPED_LEN,
(3 + (3 * 128 + 2) + 2 + (3 * 150 + 2) + 3 + 10 + 3) + 6
);
assert_eq!(
<MixedEnum<'_> as AtatLen>::LEN,
(3 + 3 + (1 + 10 + 1) + 20 + 10) + 4
);
// ESCAPED_LEN: String<10> -> 3*10+2=32
// max variant AdvancedTuple: (3 + 32 + 20 + 10) + 4 separators = 69
assert_eq!(
<MixedEnum<'_> as AtatLen>::ESCAPED_LEN,
3 + (3 + 32 + 20 + 10) + 4
);
}

#[test]
Expand Down
15 changes: 7 additions & 8 deletions atat/src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
pub trait Parser {
/// Parse a URC, if it exists.
///
/// - if no URC exists, return [ParseError::NoMatch]

Check warning on line 36 in atat/src/digest.rs

View workflow job for this annotation

GitHub Actions / clippy

item in documentation is missing backticks

warning: item in documentation is missing backticks --> atat/src/digest.rs:36:37 | 36 | /// - if no URC exists, return [ParseError::NoMatch] | ^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#doc_markdown = note: `-W clippy::doc-markdown` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::doc_markdown)]` help: try | 36 - /// - if no URC exists, return [ParseError::NoMatch] 36 + /// - if no URC exists, return [`ParseError::NoMatch`] |
/// - if a URC exists but is incomplete, return [ParseError::Incomplete]

Check warning on line 37 in atat/src/digest.rs

View workflow job for this annotation

GitHub Actions / clippy

item in documentation is missing backticks

warning: item in documentation is missing backticks --> atat/src/digest.rs:37:54 | 37 | /// - if a URC exists but is incomplete, return [ParseError::Incomplete] | ^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#doc_markdown help: try | 37 - /// - if a URC exists but is incomplete, return [ParseError::Incomplete] 37 + /// - if a URC exists but is incomplete, return [`ParseError::Incomplete`] |
/// - if a URC exists and is complete, return it and its length
fn parse(buf: &[u8]) -> Result<(&[u8], usize), ParseError>;
}
Expand Down Expand Up @@ -244,7 +244,7 @@
}
}

pub fn error_response(buf: &[u8]) -> IResult<&[u8], (DigestResult, usize)> {
pub fn error_response(buf: &[u8]) -> IResult<&[u8], (DigestResult<'_>, usize)> {
alt((
// Matches the equivalent of regex: "\r\n\+CME ERROR:\s*(\d+)\r\n"
map(numeric_error("\r\n+CME ERROR:"), |(error_code, len)| {
Expand Down Expand Up @@ -310,8 +310,8 @@
))(buf)
}

pub fn prompt_response(buf: &[u8]) -> IResult<&[u8], (DigestResult, usize)> {
for prompt in &[b'>', b'@'] {
pub fn prompt_response(buf: &[u8]) -> IResult<&[u8], (DigestResult<'_>, usize)> {
for prompt in b">@" {
if let Ok((buf, ((prefix, p), ws, _))) = tuple((
take_until_including::<_, _, nom::error::Error<_>>(&[*prompt][..]),
complete::multispace0,
Expand All @@ -333,7 +333,7 @@
)))
}

pub fn success_response(buf: &[u8]) -> IResult<&[u8], (DigestResult, usize)> {
pub fn success_response(buf: &[u8]) -> IResult<&[u8], (DigestResult<'_>, usize)> {
let (i, ((data, tag), ws)) = alt((
tuple((
take_until_including("\r\nOK\r\n"),
Expand Down Expand Up @@ -478,19 +478,19 @@
}

fn trim_ascii_whitespace(x: &[u8]) -> &[u8] {
let from = match x.iter().position(|x| !x.is_ascii_whitespace()) {
Some(i) => i,
None => return &x[0..0],
};

Check warning on line 484 in atat/src/digest.rs

View workflow job for this annotation

GitHub Actions / clippy

this could be rewritten as `let...else`

warning: this could be rewritten as `let...else` --> atat/src/digest.rs:481:9 | 481 | / let from = match x.iter().position(|x| !x.is_ascii_whitespace()) { 482 | | Some(i) => i, 483 | | None => return &x[0..0], 484 | | }; | |__________^ help: consider writing: `let Some(from) = x.iter().position(|x| !x.is_ascii_whitespace()) else { return &x[0..0] };` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#manual_let_else = note: `-W clippy::manual-let-else` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::manual_let_else)]`
let to = x.iter().rposition(|x| !x.is_ascii_whitespace()).unwrap();
&x[from..=to]
}

pub fn trim_start_ascii_space(x: &[u8]) -> &[u8] {

Check warning on line 489 in atat/src/digest.rs

View workflow job for this annotation

GitHub Actions / clippy

this function could have a `#[must_use]` attribute

warning: this function could have a `#[must_use]` attribute --> atat/src/digest.rs:489:12 | 489 | pub fn trim_start_ascii_space(x: &[u8]) -> &[u8] { | ^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#must_use_candidate = note: `-W clippy::must-use-candidate` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::must_use_candidate)]` help: add the attribute | 489 ~ #[must_use] 490 ~ pub fn trim_start_ascii_space(x: &[u8]) -> &[u8] { |
match x.iter().position(|&x| x != b' ') {
Some(offset) => &x[offset..],
None => &x[0..0],
}

Check warning on line 493 in atat/src/digest.rs

View workflow job for this annotation

GitHub Actions / clippy

use Option::map_or_else instead of an if let/else

warning: use Option::map_or_else instead of an if let/else --> atat/src/digest.rs:490:9 | 490 | / match x.iter().position(|&x| x != b' ') { 491 | | Some(offset) => &x[offset..], 492 | | None => &x[0..0], 493 | | } | |_________^ help: try: `x.iter().position(|&x| x != b' ').map_or_else(|| &x[0..0], |offset| &x[offset..])` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#option_if_let_else = note: `-W clippy::option-if-let-else` implied by `-W clippy::nursery` = help: to override `-W clippy::nursery` add `#[allow(clippy::option_if_let_else)]`
}
}
#[cfg(test)]
Expand All @@ -499,10 +499,9 @@

use super::parser::{echo, urc_helper};
use super::*;
use crate::{
error::{CmeError, CmsError, ConnectionError},
helpers::LossyStr,
};
#[cfg(feature = "string_errors")]
use crate::error::{CmsError, ConnectionError};
use crate::{error::CmeError, helpers::LossyStr};

const TEST_RX_BUF_LEN: usize = 256;

Expand Down
2 changes: 1 addition & 1 deletion atat/src/ingress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
UrcChannel,
};

#[derive(Debug, PartialEq)]

Check warning on line 6 in atat/src/ingress.rs

View workflow job for this annotation

GitHub Actions / clippy

you are deriving `PartialEq` and can implement `Eq`

warning: you are deriving `PartialEq` and can implement `Eq` --> atat/src/ingress.rs:6:17 | 6 | #[derive(Debug, PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#derive_partial_eq_without_eq = note: `-W clippy::derive-partial-eq-without-eq` implied by `-W clippy::nursery` = help: to override `-W clippy::nursery` add `#[allow(clippy::derive_partial_eq_without_eq)]`
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
ResponseSlotBusy,
Expand Down Expand Up @@ -104,12 +104,12 @@
const URC_SUBSCRIBERS: usize,
> Ingress<'a, D, Urc, RES_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>
{
pub fn new(
digester: D,
buf: &'a mut [u8],
res_slot: &'a ResponseSlot<RES_BUF_SIZE>,
urc_channel: &'a UrcChannel<Urc, URC_CAPACITY, URC_SUBSCRIBERS>,
) -> Self {

Check warning on line 112 in atat/src/ingress.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function which may panic missing `# Panics` section

warning: docs for function which may panic missing `# Panics` section --> atat/src/ingress.rs:107:5 | 107 | / pub fn new( 108 | | digester: D, 109 | | buf: &'a mut [u8], 110 | | res_slot: &'a ResponseSlot<RES_BUF_SIZE>, 111 | | urc_channel: &'a UrcChannel<Urc, URC_CAPACITY, URC_SUBSCRIBERS>, 112 | | ) -> Self { | |_____________^ | note: first possible panic found here --> atat/src/ingress.rs:118:28 | 118 | urc_publisher: urc_channel.0.publisher().unwrap(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#missing_panics_doc = note: `-W clippy::missing-panics-doc` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::missing_panics_doc)]`
Self {
digester,
buf,
Expand Down Expand Up @@ -181,7 +181,7 @@
match &resp {
Ok(r) => {
if r.is_empty() {
debug!("Received OK ({}/{})", swallowed, self.pos,)

Check warning on line 184 in atat/src/ingress.rs

View workflow job for this annotation

GitHub Actions / clippy

consider adding a `;` to the last statement for consistent formatting

warning: consider adding a `;` to the last statement for consistent formatting --> atat/src/ingress.rs:184:33 | 184 | ... debug!("Received OK ({}/{})", swallowed, self.pos,) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `debug!("Received OK ({}/{})", swallowed, self.pos,);` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#semicolon_if_nothing_returned = note: `-W clippy::semicolon-if-nothing-returned` implied by `-W clippy::pedantic` = help: to override `-W clippy::pedantic` add `#[allow(clippy::semicolon_if_nothing_returned)]`
} else {
debug!(
"Received response ({}/{}): {:?}",
Expand Down Expand Up @@ -217,7 +217,7 @@
Ok(())
}

async fn advance(&mut self, commit: usize) {

Check warning on line 220 in atat/src/ingress.rs

View workflow job for this annotation

GitHub Actions / clippy

future cannot be sent between threads safely

warning: future cannot be sent between threads safely --> atat/src/ingress.rs:220:5 | 220 | async fn advance(&mut self, commit: usize) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `advance` is not `Send` | note: future is not `Send` as this value is used across an await --> atat/src/ingress.rs:257:61 | 247 | if let Some(urc) = Urc::parse(urc_line) { | -------------------- has type `core::option::Option<<Urc as traits::AtatUrc>::Response>` which is not `Send` ... 257 | self.urc_publisher.publish(urc).await; | ^^^^^ await occurs here, with `Urc::parse(urc_line)` maybe used later = note: `<Urc as traits::AtatUrc>::Response` doesn't implement `core::marker::Send` note: future is not `Send` as this value is used across an await --> atat/src/ingress.rs:257:61 | 220 | async fn advance(&mut self, commit: usize) { | --------- has type `&mut ingress::Ingress<'_, D, Urc, RES_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>` which is not `Send` ... 257 | self.urc_publisher.publish(urc).await; | ^^^^^ await occurs here, with `&mut self` maybe used later = note: `D` doesn't implement `core::marker::Send` note: future is not `Send` as it awaits another future which is not `Send` --> atat/src/ingress.rs:257:29 | 257 | ... self.urc_publisher.publish(urc).await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `embassy_sync::pubsub::publisher::PublisherWaitFuture<'_, '_, embassy_sync::pubsub::PubSubChannel<embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex, <Urc as traits::AtatUrc>::Response, URC_CAPACITY, URC_SUBSCRIBERS, 1>, <Urc as traits::AtatUrc>::Response>`, which is not `Send` = note: `<Urc as traits::AtatUrc>::Response` doesn't implement `core::marker::Sync` = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#future_not_send = note: `-W clippy::future-not-send` implied by `-W clippy::nursery` = help: to override `-W clippy::nursery` add `#[allow(clippy::future_not_send)]`
self.pos += commit;
assert!(self.pos <= self.buf.len());

Expand Down Expand Up @@ -265,7 +265,7 @@
match &resp {
Ok(r) => {
if r.is_empty() {
debug!("Received OK ({}/{})", swallowed, self.pos,)

Check warning on line 268 in atat/src/ingress.rs

View workflow job for this annotation

GitHub Actions / clippy

consider adding a `;` to the last statement for consistent formatting

warning: consider adding a `;` to the last statement for consistent formatting --> atat/src/ingress.rs:268:33 | 268 | ... debug!("Received OK ({}/{})", swallowed, self.pos,) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `debug!("Received OK ({}/{})", swallowed, self.pos,);` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#semicolon_if_nothing_returned
} else {
debug!(
"Received response ({}/{}): {:?}",
Expand Down Expand Up @@ -476,7 +476,7 @@
}
impl embedded_io_async::Read for Reader {
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
assert!(buf.len() > 0);
assert!(!buf.is_empty());
if self.pos >= self.data.len() {
// Simulate waiting on more data.
loop {
Expand Down
8 changes: 3 additions & 5 deletions atat/src/response.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::InternalError;
use heapless::Vec;

#[derive(Debug, Clone, PartialEq)]

Check warning on line 4 in atat/src/response.rs

View workflow job for this annotation

GitHub Actions / clippy

you are deriving `PartialEq` and can implement `Eq`

warning: you are deriving `PartialEq` and can implement `Eq` --> atat/src/response.rs:4:24 | 4 | #[derive(Debug, Clone, PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#derive_partial_eq_without_eq
pub enum Response<const N: usize> {
Ok(Vec<u8, N>),
Prompt(u8),
Expand All @@ -19,7 +19,7 @@
}

impl<const N: usize> Response<N> {
pub fn ok(value: &[u8]) -> Self {

Check warning on line 22 in atat/src/response.rs

View workflow job for this annotation

GitHub Actions / clippy

this method could have a `#[must_use]` attribute

warning: this method could have a `#[must_use]` attribute --> atat/src/response.rs:22:12 | 22 | pub fn ok(value: &[u8]) -> Self { | ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#must_use_candidate help: add the attribute | 22 ~ #[must_use] 23 ~ pub fn ok(value: &[u8]) -> Self { |

Check warning on line 22 in atat/src/response.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function which may panic missing `# Panics` section

warning: docs for function which may panic missing `# Panics` section --> atat/src/response.rs:22:5 | 22 | pub fn ok(value: &[u8]) -> Self { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here --> atat/src/response.rs:23:22 | 23 | Response::Ok(Vec::from_slice(value).unwrap()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#missing_panics_doc
Response::Ok(Vec::from_slice(value).unwrap())
}
}
Expand Down Expand Up @@ -69,11 +69,9 @@
Response::AbortedError => Err(InternalError::Aborted),
Response::ParseError => Err(InternalError::Parse),
Response::OtherError => Err(InternalError::Error),
Response::CmeError(e) => Err(InternalError::CmeError((*e).try_into().unwrap())),
Response::CmsError(e) => Err(InternalError::CmsError((*e).try_into().unwrap())),
Response::ConnectionError(e) => {
Err(InternalError::ConnectionError((*e).try_into().unwrap()))
}
Response::CmeError(e) => Err(InternalError::CmeError((*e).into())),
Response::CmsError(e) => Err(InternalError::CmsError((*e).into())),
Response::ConnectionError(e) => Err(InternalError::ConnectionError((*e).into())),
Response::CustomError(e) => Err(InternalError::Custom(e)),
}
}
Expand Down
6 changes: 6 additions & 0 deletions atat/src/response_slot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@
#[derive(Debug)]
pub struct SlotInUseError;

impl<const N: usize> Default for ResponseSlot<N> {
fn default() -> Self {
Self::new()
}
}

impl<const N: usize> ResponseSlot<N> {
pub const fn new() -> Self {

Check warning on line 29 in atat/src/response_slot.rs

View workflow job for this annotation

GitHub Actions / clippy

this method could have a `#[must_use]` attribute

warning: this method could have a `#[must_use]` attribute --> atat/src/response_slot.rs:29:18 | 29 | pub const fn new() -> Self { | ^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#must_use_candidate help: add the attribute | 29 ~ #[must_use] 30 ~ pub const fn new() -> Self { |
Self(
Mutex::new(RefCell::new(Response::Ok(Vec::new()))),
Signal::new(),
Expand All @@ -33,7 +39,7 @@
}

/// Wait for a response to be signaled and get a guard to the response
pub async fn get<'a>(&'a self) -> ResponseSlotGuard<'a, N> {

Check warning on line 42 in atat/src/response_slot.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'a

warning: the following explicit lifetimes could be elided: 'a --> atat/src/response_slot.rs:42:22 | 42 | pub async fn get<'a>(&'a self) -> ResponseSlotGuard<'a, N> { | ^^ ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#elidable_lifetime_names

Check warning on line 42 in atat/src/response_slot.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function which may panic missing `# Panics` section

warning: docs for function which may panic missing `# Panics` section --> atat/src/response_slot.rs:42:5 | 42 | pub async fn get<'a>(&'a self) -> ResponseSlotGuard<'a, N> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here --> atat/src/response_slot.rs:46:9 | 46 | self.0.try_lock().unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#missing_panics_doc
self.1.wait().await;

// The mutex is not locked when signal is emitted
Expand All @@ -41,7 +47,7 @@
}

/// If signaled, get a guard to the response
pub fn try_get<'a>(&'a self) -> Option<ResponseSlotGuard<'a, N>> {

Check warning on line 50 in atat/src/response_slot.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'a

warning: the following explicit lifetimes could be elided: 'a --> atat/src/response_slot.rs:50:20 | 50 | pub fn try_get<'a>(&'a self) -> Option<ResponseSlotGuard<'a, N>> { | ^^ ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#elidable_lifetime_names help: elide the lifetimes | 50 - pub fn try_get<'a>(&'a self) -> Option<ResponseSlotGuard<'a, N>> { 50 + pub fn try_get(&self) -> Option<ResponseSlotGuard<'_, N>> { |

Check warning on line 50 in atat/src/response_slot.rs

View workflow job for this annotation

GitHub Actions / clippy

docs for function which may panic missing `# Panics` section

warning: docs for function which may panic missing `# Panics` section --> atat/src/response_slot.rs:50:5 | 50 | pub fn try_get<'a>(&'a self) -> Option<ResponseSlotGuard<'a, N>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first possible panic found here --> atat/src/response_slot.rs:53:18 | 53 | Some(self.0.try_lock().unwrap()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#missing_panics_doc
if self.1.signaled() {
// The mutex is not locked when signal is emitted
Some(self.0.try_lock().unwrap())
Expand All @@ -57,7 +63,7 @@

// Not currently signaled: We know that the client is not currently holding the response slot guard
{
let buf = self.0.try_lock().unwrap();

Check warning on line 66 in atat/src/response_slot.rs

View workflow job for this annotation

GitHub Actions / clippy

temporary with significant `Drop` can be early dropped

warning: temporary with significant `Drop` can be early dropped --> atat/src/response_slot.rs:66:17 | 65 | / { 66 | | let buf = self.0.try_lock().unwrap(); | | ^^^ 67 | | let mut res = buf.borrow_mut(); 68 | | *res = Response::Prompt(prompt); 69 | | } | |_________- temporary `buf` is currently being dropped at the end of its contained scope | = note: this might lead to unnecessary resource contention = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#significant_drop_tightening = note: `-W clippy::significant-drop-tightening` implied by `-W clippy::nursery` = help: to override `-W clippy::nursery` add `#[allow(clippy::significant_drop_tightening)]` help: merge the temporary construction with its single usage | 66 ~ 67 + let res = self.0.try_lock().unwrap().borrow_mut(); 68 ~ |
let mut res = buf.borrow_mut();
*res = Response::Prompt(prompt);
}
Expand All @@ -77,7 +83,7 @@

// Not currently signaled: We know that the client is not currently holding the response slot guard
{
let buf = self.0.try_lock().unwrap();

Check warning on line 86 in atat/src/response_slot.rs

View workflow job for this annotation

GitHub Actions / clippy

temporary with significant `Drop` can be early dropped

warning: temporary with significant `Drop` can be early dropped --> atat/src/response_slot.rs:86:17 | 85 | / { 86 | | let buf = self.0.try_lock().unwrap(); | | ^^^ 87 | | let mut res = buf.borrow_mut(); 88 | | *res = response.into(); 89 | | } | |_________- temporary `buf` is currently being dropped at the end of its contained scope | = note: this might lead to unnecessary resource contention = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#significant_drop_tightening help: merge the temporary construction with its single usage | 86 ~ 87 + let res = self.0.try_lock().unwrap().borrow_mut(); 88 ~ |
let mut res = buf.borrow_mut();
*res = response.into();
}
Expand Down
8 changes: 8 additions & 0 deletions atat/src/urc_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@
pub(crate) PubSubChannel<CriticalSectionRawMutex, Urc::Response, CAPACITY, SUBSCRIBERS, 1>,
);

impl<Urc: AtatUrc, const CAPACITY: usize, const SUBSCRIBERS: usize> Default
for UrcChannel<Urc, CAPACITY, SUBSCRIBERS>
{
fn default() -> Self {
Self::new()
}
}

impl<Urc: AtatUrc, const CAPACITY: usize, const SUBSCRIBERS: usize>
UrcChannel<Urc, CAPACITY, SUBSCRIBERS>
{
pub const fn new() -> Self {

Check warning on line 32 in atat/src/urc_channel.rs

View workflow job for this annotation

GitHub Actions / clippy

this method could have a `#[must_use]` attribute

warning: this method could have a `#[must_use]` attribute --> atat/src/urc_channel.rs:32:18 | 32 | pub const fn new() -> Self { | ^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#must_use_candidate help: add the attribute | 32 ~ #[must_use] 33 ~ pub const fn new() -> Self { |
Self(PubSubChannel::new())
}

Expand Down
Loading
Loading