Skip to main content

lego_powered_up/iodevice/
basic.rs

1//! The basic bricks of device control.
2//! All the other device traits are sugar for these 3 commands.
3
4use async_trait::async_trait;
5use core::fmt::Debug;
6use tokio::sync::broadcast;
7
8use crate::error::Result;
9use crate::hubs::Tokens;
10use crate::notifications::{
11    CompletionInfo, InputSetupCombined, InputSetupCombinedSubcommand,
12    InputSetupSingle, NotificationMessage, PortOutputCommandFormat,
13    PortOutputSubcommand, PortValueSingleFormat, StartupInfo,
14};
15
16#[async_trait]
17pub trait Basic: Debug + Send + Sync {
18    fn port(&self) -> u8;
19    fn tokens(&self) -> Tokens;
20    fn get_rx(&self) -> Result<broadcast::Receiver<PortValueSingleFormat>>;
21    async fn commit(&self, msg: NotificationMessage) -> Result<()> {
22        match crate::hubs::send(self.tokens(), msg).await {
23            Ok(()) => Ok(()),
24            Err(e) => Err(e),
25        }
26    }
27
28    async fn device_mode(
29        &self,
30        mode: u8,
31        delta: u32,
32        notification_enabled: bool,
33    ) -> Result<()> {
34        let msg =
35            NotificationMessage::PortInputFormatSetupSingle(InputSetupSingle {
36                port_id: self.port(),
37                mode,
38                delta,
39                notification_enabled,
40            });
41        self.commit(msg).await
42    }
43
44    async fn device_mode_combined(
45        &self,
46        subcommand: InputSetupCombinedSubcommand,
47    ) -> Result<()> {
48        let msg = NotificationMessage::PortInputFormatSetupCombinedmode(
49            InputSetupCombined {
50                port_id: self.port(),
51                subcommand,
52            },
53        );
54        self.commit(msg).await
55    }
56
57    async fn device_command(
58        &self,
59        subcommand: PortOutputSubcommand,
60        startup_info: StartupInfo,
61        completion_info: CompletionInfo,
62    ) -> Result<()> {
63        let msg =
64            NotificationMessage::PortOutputCommand(PortOutputCommandFormat {
65                port_id: self.port(),
66                startup_info,
67                completion_info,
68                subcommand,
69            });
70        self.commit(msg).await
71    }
72}