uds_client/uds_client/
response.rs1use std::{cell::RefCell, time::Duration};
2use tokio::sync::{Mutex, Notify};
3
4use super::{
5 DiagError,
6 frame::{FrameError, UdsFrame},
7};
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum Response {
11 Ok(UdsFrame),
12 Error,
13}
14
15pub struct ResponseSlot(pub Mutex<RefCell<Response>>, pub Notify);
17
18impl Default for ResponseSlot {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl ResponseSlot {
25 const TIMEOUT: u64 = 1000;
27
28 pub fn new() -> Self {
30 Self(Mutex::new(RefCell::new(Response::Error)), Notify::new())
31 }
32
33 pub async fn get(&self) -> Result<Response, DiagError> {
35 self.1.notified().await;
36 let res = self.0.try_lock().unwrap().to_owned().into_inner();
37 Ok(res)
38 }
39
40 pub async fn wait_for_response(&self) -> Response {
42 tokio::select! {
43 _ = self.1.notified() => {
44 let data = self.0.lock().await;
45 data.borrow().clone()
46 }
47 _ = tokio::time::sleep(Duration::from_millis(Self::TIMEOUT)) => {
48 Response::Error
49 }
50 }
51 }
52
53 pub async fn update_response(&self, new_data: Vec<u8>) -> Result<(), FrameError> {
55 let res = UdsFrame::from_vec(new_data)?;
56 self.0.lock().await.replace(Response::Ok(res)); self.1.notify_one(); Ok(())
59 }
60}