1use crate::encode::Encode;
2use alloc::borrow::Cow;
3use core::fmt::Display;
4use serde::{Deserialize, Serialize};
5
6pub enum BoardValidationError {
7 EmptyName,
8 NameTooLong,
9 MinGtMax,
10}
11
12impl BoardValidationError {
13 #[must_use]
14 pub const fn as_str(&self) -> &'static str {
15 match self {
16 Self::EmptyName => "name must not be empty",
17 Self::NameTooLong => "name is too long",
18 Self::MinGtMax => "min must be less than or equal to max",
19 }
20 }
21}
22
23impl Display for BoardValidationError {
24 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
25 write!(f, "{}", self.as_str())
26 }
27}
28
29#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
30pub struct Boards<'a> {
31 #[serde(borrow)]
32 pub boards: Cow<'a, [Board<'a>]>,
33}
34
35impl<'a> Boards<'a> {
36 #[must_use]
37 pub const fn new(boards: Cow<'a, [Board<'a>]>) -> Self {
38 Self { boards }
39 }
40}
41
42impl<'a> Encode<'a> for Boards<'a> {}
43
44#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
45pub struct Board<'a> {
46 pub position: u16,
48
49 pub min: i16,
55
56 pub max: i16,
60
61 pub time: bool,
63
64 pub decimals: u8,
66
67 pub name: &'a str,
69}
70
71impl Board<'_> {
72 pub const fn validate(&self) -> Result<(), BoardValidationError> {
78 if self.name.is_empty() {
79 return Err(BoardValidationError::EmptyName);
80 }
81 if self.name.len() > 64 {
82 return Err(BoardValidationError::NameTooLong);
83 }
84 if self.min > self.max {
85 return Err(BoardValidationError::MinGtMax);
86 }
87 Ok(())
88 }
89}