Beatsaber Rust Utilities: A Beatsaber V3 parsing library.
beatsaber
beatmap
1//! Taken from [this example](https://github.com/AlephCubed/loose_enum/blob/main/examples/loose_bool.rs).
2
3use core::error::Error;
4use core::fmt::{Display, Formatter};
5use loose_enum::loose_enum;
6
7loose_enum! {
8 /// An integer repr bool, with 0 being false and 1 being true. Any other value will be saved as Undefined.
9 #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
10 #[cfg_attr(
11 feature = "bevy_reflect",
12 derive(bevy_reflect::Reflect),
13 reflect(Debug, Clone, PartialEq)
14 )]
15 pub enum LooseBool: i32 {
16 /// A falsy value of zero.
17 #[default]
18 False = 0,
19 /// A truthy value of one.
20 True = 1,
21 }
22}
23
24impl LooseBool {
25 /// Returns true if the value is [`True`](Self::True).
26 pub fn is_true(&self) -> bool {
27 matches!(self, Self::True)
28 }
29
30 /// Returns true if the value is [`False`](Self::False).
31 pub fn is_false(&self) -> bool {
32 matches!(self, Self::False)
33 }
34}
35
36impl From<bool> for LooseBool {
37 fn from(value: bool) -> Self {
38 match value {
39 true => Self::True,
40 false => Self::False,
41 }
42 }
43}
44
45impl TryFrom<LooseBool> for bool {
46 type Error = UndefinedBoolError;
47
48 fn try_from(value: LooseBool) -> Result<Self, Self::Error> {
49 match value {
50 LooseBool::False => Ok(false),
51 LooseBool::True => Ok(true),
52 LooseBool::Undefined(_) => Err(UndefinedBoolError),
53 }
54 }
55}
56
57/// Error returned when attempting to convert a [`LooseBool::Undefined`] into a `bool`.
58#[derive(Debug, Eq, PartialEq, Hash)]
59pub struct UndefinedBoolError;
60
61impl Display for UndefinedBoolError {
62 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
63 write!(f, "Cannot convert `LooseBool::Undefined` into `bool`.")
64 }
65}
66
67impl Error for UndefinedBoolError {}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn loose_to_bool() {
75 assert_eq!(bool::try_from(LooseBool::True), Ok(true));
76 assert_eq!(bool::try_from(LooseBool::False), Ok(false));
77
78 for i in 2..256 {
79 assert_eq!(
80 bool::try_from(LooseBool::Undefined(i)),
81 Err(UndefinedBoolError),
82 "Failed for i={i}"
83 );
84 }
85 }
86
87 #[test]
88 fn bool_to_loose() {
89 assert_eq!(LooseBool::from(false), LooseBool::False);
90 assert_eq!(LooseBool::from(true), LooseBool::True);
91 }
92}