ble_ledly/capability/
sw_animate.rs1use super::brightness::BrightnessOption;
2use crate::capability::color::ColorOption;
3use crate::communication_protocol::Protocol;
4use crate::device::Device;
5use crate::device::Write;
6use crate::error::{BluetoothError};
7use async_trait::async_trait;
8
9use std::time::Duration;
10use tokio::time;
11
12pub enum SWAnimateOption<'e> {
16 Breathing(&'e ColorOption, &'e SWAnimationRepeat, &'e SWAnimationSpeed),
17}
18
19pub enum SWAnimationRepeat {
20 FiniteCount(i32),
21 InfiniteCount,
22}
23
24pub enum SWAnimationSpeed {
25 Slowest,
26 Slower,
27 Slow,
28 Normal,
29 Fast,
30 Faster,
31 Fastest,
32}
33fn sw_animation_speed(speed: &SWAnimationSpeed) -> u64 {
37 match speed {
38 SWAnimationSpeed::Fastest => 5,
39 SWAnimationSpeed::Faster => 20,
40 SWAnimationSpeed::Fast => 50,
41 SWAnimationSpeed::Normal => 200,
42 SWAnimationSpeed::Slow => 300,
43 SWAnimationSpeed::Slower => 400,
44 SWAnimationSpeed::Slowest => 600,
45 }
46}
47
48#[async_trait]
49pub trait SWAnimate {
50 async fn set<'e, P: Protocol + std::marker::Send + std::marker::Sync>(
51 &self,
52 protocol: &'e P,
53 option: &'e SWAnimateOption,
54 ) -> Result<(), BluetoothError>;
55 async fn _breathing<'e, P: Protocol + std::marker::Send + std::marker::Sync>(
56 &self,
57 protocol: &'e P,
58 color: &'e ColorOption,
59 interval: u64,
60 ) -> Result<(), BluetoothError>;
61 async fn breathing<'e, P: Protocol + std::marker::Send + std::marker::Sync>(
62 &self,
63 protocol: &'e P,
64 color: &'e ColorOption,
65 repeat: &'e SWAnimationRepeat,
66 speed: &'e SWAnimationSpeed,
67 ) -> Result<(), BluetoothError>;
68}
69
70#[async_trait]
74impl<D: Device + std::marker::Sync> SWAnimate for D {
75 async fn set<'e, P: Protocol + std::marker::Send + std::marker::Sync>(
77 &self,
78 protocol: &'e P,
79 option: &'e SWAnimateOption,
80 ) -> Result<(), BluetoothError> {
81 match option {
82 SWAnimateOption::Breathing(color, repeat, speed) => {
83 self.breathing(protocol, color, repeat, speed).await?;
84 }
85 }
86 Ok(())
87 }
88
89 async fn _breathing<'e, P: Protocol + std::marker::Send + std::marker::Sync>(
94 &self,
95 protocol: &'e P,
96 color: &'e ColorOption,
97 interval: u64,
98 ) -> Result<(), BluetoothError> {
99 for i in 0..=100 {
101 let e_bytes = protocol.brightness(&BrightnessOption::LevelWithColor(
102 i as f32 / 100 as f32,
103 color,
104 ));
105 self.push(&(e_bytes)[..]).await?;
106 time::sleep(Duration::from_millis(interval)).await;
107 }
108 for i in (0..=100).rev() {
109 let e_bytes = protocol.brightness(&BrightnessOption::LevelWithColor(
110 i as f32 / 100 as f32,
111 color,
112 ));
113 self.push(&(e_bytes)[..]).await?;
114 time::sleep(Duration::from_millis(interval)).await;
115 }
116 Ok(())
117 }
118
119 async fn breathing<'e, P: Protocol + std::marker::Send + std::marker::Sync>(
120 &self,
121 protocol: &'e P,
122 color: &'e ColorOption,
123 repeat: &'e SWAnimationRepeat,
124 speed: &'e SWAnimationSpeed,
125 ) -> Result<(), BluetoothError> {
126 match repeat {
127 SWAnimationRepeat::FiniteCount(count) => {
128 let mut i = 0;
129 while i < *count {
130 self._breathing(protocol, &color, sw_animation_speed(speed))
131 .await?;
132 i += 1;
133 }
134 }
135 SWAnimationRepeat::InfiniteCount => loop {
136 self._breathing(protocol, &color, sw_animation_speed(speed))
137 .await?;
138 },
139 }
140 Ok(())
141 }
142}