|
1 | 1 | #![allow(dead_code)] |
2 | 2 |
|
3 | 3 | use crate::meeting_duration::MeetingDuration; |
| 4 | +use core::ops::{Div, Mul}; |
4 | 5 | use defmt::Format; |
5 | 6 | use embassy_time::Duration; |
| 7 | +use num_traits::{PrimInt, Unsigned}; |
6 | 8 | use serde::{Deserialize, Serialize}; |
7 | 9 |
|
8 | 10 | // fifo_full_threshold (RX) |
@@ -47,21 +49,25 @@ impl From<MeetingDuration> for QuarterSeconds { |
47 | 49 | #[serde(transparent)] |
48 | 50 | pub struct ProgressRatio(pub u8); |
49 | 51 | impl ProgressRatio { |
50 | | - fn from_values(numerator: u8, denominator: u8) -> Option<Self> { |
51 | | - if denominator == 0 { |
52 | | - return None; // Avoid division by zero |
53 | | - } |
54 | | - if numerator > denominator { |
55 | | - return None; // Avoid ratios greater than 1 |
| 52 | + /// Create a ratio from `numerator / denominator`, scaled to 0..=255 |
| 53 | + pub fn from_values<T>(numerator: T, denominator: T) -> Option<Self> |
| 54 | + where |
| 55 | + T: PrimInt + Unsigned, |
| 56 | + { |
| 57 | + if denominator.is_zero() { |
| 58 | + return None; |
56 | 59 | } |
57 | 60 |
|
58 | | - let ratio = ((numerator as u16) * (u8::MAX as u16) / denominator as u16) as u8; |
59 | | - Some(Self(ratio)) |
| 61 | + let scaled = (numerator.to_u32()? * u8::MAX as u32) / denominator.to_u32()?; |
| 62 | + Some(Self(scaled.min(u8::MAX as u32) as u8)) |
60 | 63 | } |
61 | 64 |
|
62 | | - fn apply_to_value(&self, value: u16) -> u16 { |
63 | | - // Apply the progress ratio to a value |
64 | | - (value as u32 * self.0 as u32 / u8::MAX as u32) as u16 |
| 65 | + /// Apply the ratio to a value of arbitrary unsigned integer type |
| 66 | + pub fn apply_to<T>(&self, value: T) -> T |
| 67 | + where |
| 68 | + T: Mul<u32, Output = T> + Div<u32, Output = T>, |
| 69 | + { |
| 70 | + value * self.0 as u32 / u8::MAX as u32 |
65 | 71 | } |
66 | 72 | } |
67 | 73 |
|
|
0 commit comments