···11//! Events that effect gameplay and aren't purely visual.
2233-use crate::{impl_timed, loose_enum};
33+use crate::impl_timed;
44+use loose_enum::loose_enum;
45use serde::{Deserialize, Serialize};
5667/// Controls the rotation that interactable objects spawn in 90/360 degree difficulties.
···25262627loose_enum!(
2728 /// Determines when a [`LaneRotationEvent`] will be applied to objects.
2828- #[derive(Default, Copy)]
2929- ExecutionTime: i32 {
2929+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
3030+ #[cfg_attr(
3131+ feature = "bevy_reflect",
3232+ derive(bevy_reflect::Reflect),
3333+ reflect(Debug, Clone, PartialEq)
3434+ )]
3535+ pub enum ExecutionTime: i32 {
3036 /// The [`LaneRotationEvent`] will affect objects with a beat *greater than or equal to* the event's beat.
3137 #[default]
3238 Early = 0,
+24-9
src/difficulty/lightshow.rs
···1414#[doc(hidden)]
1515pub use group::*;
16161717-use crate::loose_enum;
1717+use loose_enum::loose_enum;
18181919loose_enum! {
2020 /// The way that the distribution value is used.
2121- #[derive(Default, Copy)]
2222- DistributionType: i32 {
2121+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
2222+ #[cfg_attr(
2323+ feature = "bevy_reflect",
2424+ derive(bevy_reflect::Reflect),
2525+ reflect(Debug, Clone, PartialEq)
2626+ )]
2727+ pub enum DistributionType: i32 {
2328 /// The distribution value represents the difference between *the last and first step*.
2429 #[default]
2530 Wave = 1,
···122127 fraction * modified_value
123128 }
124129 DistributionType::Step => dist_value * filtered_id,
125125- DistributionType::Unknown(_) => 0.0,
130130+ DistributionType::Undefined(_) => 0.0,
126131 }
127132 }
128133···171176172177loose_enum! {
173178 /// Controls how the state is changed relative to the previous event.
174174- #[derive(Default, Copy)]
175175- TransitionType: i32 {
179179+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
180180+ #[cfg_attr(
181181+ feature = "bevy_reflect",
182182+ derive(bevy_reflect::Reflect),
183183+ reflect(Debug, Clone, PartialEq)
184184+ )]
185185+ pub enum TransitionType: i32 {
176186 /// The state will blend from the previous event's state, using the events [easing](Easing).
177187 #[default]
178188 Transition = 0,
···183193184194loose_enum! {
185195 /// The axis that a rotation/translation event effects.
186186- #[derive(Default, Copy)]
187187- EventAxis: i32 {
196196+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
197197+ #[cfg_attr(
198198+ feature = "bevy_reflect",
199199+ derive(bevy_reflect::Reflect),
200200+ reflect(Debug, Clone, PartialEq)
201201+ )]
202202+ pub enum EventAxis: i32 {
188203 #[default]
189204 X = 0,
190205 Y = 1,
···198213mod tests {
199214 use super::*;
200215 use crate::difficulty::lightshow::filter::FilterType;
201201- use crate::utils::LooseBool;
216216+ use crate::loose_bool::LooseBool;
202217203218 #[test]
204219 fn wave() {
+10-5
src/difficulty/lightshow/easing.rs
···11//! The easing that a [transition](crate::lightshow::TransitionType::Transition) event will use.
2233-use crate::loose_enum;
33+use loose_enum::loose_enum;
44use simple_easing::*;
5566loose_enum! {
77 /// The easing that a [transition](crate::lightshow::TransitionType::Transition) event will use.
88- #[derive(Default, Copy)]
99- Easing: i32 {
88+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
99+ #[cfg_attr(
1010+ feature = "bevy_reflect",
1111+ derive(bevy_reflect::Reflect),
1212+ reflect(Debug, Clone, PartialEq)
1313+ )]
1414+ pub enum Easing: i32 {
1015 #[default]
1116 None = -1,
1217···5560 /// Applies the relevant easing function.
5661 ///
5762 /// The Beatsaber specific easing use the standard equivalent instead.
5858- /// If the easing is [`None`](Self::None) or [`Unknown`](Self::Unknown), then the result will be zero.
6363+ /// If the easing is [`None`](Self::None) or [`Undefined`](Self::Undefined), then the result will be zero.
5964 pub fn ease(&self, num: f32) -> f32 {
6065 match self {
6166 Easing::None => 0.0,
···95100 Easing::BeatSaberInOutBack => back_in_out(num),
96101 Easing::BeatSaberInOutElastic => elastic_in_out(num),
97102 Easing::BeatSaberInOutBounce => bounce_in_out(num),
9898- Easing::Unknown(_) => 0.0,
103103+ Easing::Undefined(_) => 0.0,
99104 }
100105 }
101106}
+34-19
src/difficulty/lightshow/filter.rs
···11//! Controls which light IDs are affected by an event.
2233-use crate::loose_enum;
44-use crate::utils::LooseBool;
33+use crate::loose_bool::LooseBool;
44+use loose_enum::loose_enum;
55use serde::{Deserialize, Serialize};
6677/// Controls which light IDs are affected by an event.
···72727373impl Filter {
7474 /// Returns true if the light ID is in the filter.
7575- /// # Unknown
7676- /// If the [`FilterType`] is `Unknown` then the result will be `true`.
7575+ /// # Undefined
7676+ /// If the [`FilterType`] is `Undefined` then the result will be `true`.
7777 /// # Panics
7878 /// Will panic if the light ID is greater than or equal to the group size.
7979 #[must_use]
···111111 let offset_light_id = light_id - self.parameter1;
112112 offset_light_id % self.parameter2.max(1) == 0 && offset_light_id >= 0
113113 }
114114- FilterType::Unknown(_) => true,
114114+ FilterType::Undefined(_) => true,
115115 }
116116 }
117117···120120 /// This is required for distribution calculations.
121121 ///
122122 /// Also see [`count_filtered`](Self::count_filtered).
123123- /// # Unknown
124124- /// If the [`FilterType`] is `Unknown` then the result will be the same as `group_size`.
123123+ /// # Undefined
124124+ /// If the [`FilterType`] is `Undefined` then the result will be the same as `group_size`.
125125 #[must_use]
126126 #[inline]
127127 #[deprecated(note = "Experimental. Does not consider random in calculations.")]
···142142 FilterType::StepAndOffset => {
143143 group_size / self.parameter2.max(1) - self.parameter1 / self.parameter2.max(1)
144144 }
145145- FilterType::Unknown(_) => group_size,
145145+ FilterType::Undefined(_) => group_size,
146146 }
147147 }
148148···150150 /// Returns the number of light chunks effected by the filter.
151151 ///
152152 /// Also see [`count_filtered_without_limit`](Self::count_filtered_without_limit).
153153- /// # Unknown
154154- /// If the [`FilterType`] is `Unknown` then the result will be the same as `group_size`.
153153+ /// # Undefined
154154+ /// If the [`FilterType`] is `Undefined` then the result will be the same as `group_size`.
155155 #[must_use]
156156 #[inline]
157157 #[deprecated(note = "Experimental. Does not consider random in calculations.")]
···168168169169 #[allow(deprecated)]
170170 /// Returns the light chunk ID relative to the [filtered count](Self::count_filtered).
171171- /// # Unknown
172172- /// If the [`FilterType`] is `Unknown` then the result will be the same as `light_id`.
171171+ /// # Undefined
172172+ /// If the [`FilterType`] is `Undefined` then the result will be the same as `light_id`.
173173 /// # Panics
174174 /// Will panic if the light ID is greater than or equal to the group size.
175175 // Todo what is the behaviour when the light ID is not in the filter?
···200200 let offset_light_id = light_id - self.parameter1;
201201 offset_light_id / self.parameter2.max(1)
202202 }
203203- FilterType::Unknown(_) => group_size,
203203+ FilterType::Undefined(_) => group_size,
204204 }
205205 }
206206}
···208208loose_enum! {
209209 /// Controls how a [`Filter`]'s [`parameter1`](Filter::parameter1)
210210 /// and [`parameter2`](Filter::parameter2) values are used.
211211- #[derive(Default, Copy)]
212212- FilterType: i32 {
211211+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
212212+ #[cfg_attr(
213213+ feature = "bevy_reflect",
214214+ derive(bevy_reflect::Reflect),
215215+ reflect(Debug, Clone, PartialEq)
216216+ )]
217217+ pub enum FilterType: i32 {
213218 /// Splits the group up into equal sections and selects one.
214219 /// - [`parameter1`](Filter::parameter1) determines the number of sections.
215220 /// It will be rounded up to the nearest multiple of the group size.
···224229}
225230226231loose_enum!(
227227- #[derive(Default, Copy)]
228228- RandomBehaviour: i32 {
232232+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
233233+ #[cfg_attr(
234234+ feature = "bevy_reflect",
235235+ derive(bevy_reflect::Reflect),
236236+ reflect(Debug, Clone, PartialEq)
237237+ )]
238238+ pub enum RandomBehaviour: i32 {
229239 #[default]
230240 None = 0,
231241 KeepOrder = 1,
···239249 /// To see this in practice, check out [this video](https://youtube.com/watch?v=NJPPBvyHJjg&t=338).
240250 ///
241251 /// Includes the option to only enable for beat distribution and not value distribution, and vice versa.
242242- #[derive(Default, Copy)]
243243- LimitBehaviour: i32 {
252252+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
253253+ #[cfg_attr(
254254+ feature = "bevy_reflect",
255255+ derive(bevy_reflect::Reflect),
256256+ reflect(Debug, Clone, PartialEq)
257257+ )]
258258+ pub enum LimitBehaviour: i32 {
244259 #[default]
245260 None = 0,
246261 Beat = 1,
+17-6
src/difficulty/lightshow/group/color.rs
···33use crate::difficulty::lightshow::DistributionType;
44use crate::difficulty::lightshow::easing::Easing;
55use crate::difficulty::lightshow::filter::Filter;
66-use crate::utils::LooseBool;
77-use crate::{impl_event_box, impl_event_data, impl_event_group, impl_timed, loose_enum};
66+use crate::loose_bool::LooseBool;
77+use crate::{impl_event_box, impl_event_data, impl_event_group, impl_timed};
88+use loose_enum::loose_enum;
89use serde::{Deserialize, Serialize};
9101011/// A collection of [`ColorEventGroup`]s that share the same group ID and beat.
···161162162163loose_enum! {
163164 /// Controls how the state is changed relative to the previous event.
164164- #[derive(Default, Copy)]
165165- ColorTransitionType: i32 {
165165+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
166166+ #[cfg_attr(
167167+ feature = "bevy_reflect",
168168+ derive(bevy_reflect::Reflect),
169169+ reflect(Debug, Clone, PartialEq)
170170+ )]
171171+ pub enum ColorTransitionType: i32 {
166172 /// Unique to color events.
167173 /// Has the same effect as using [`TransitionType::Transition`](crate::lightshow::TransitionType::Transition)
168174 /// and [`Easing::None`] in rotation/translation events.
···177183178184loose_enum! {
179185 /// Controls which color to display, based on a map or environment's [color scheme](crate::info::color_scheme::ColorScheme).
180180- #[derive(Default, Copy)]
181181- LightColor: i32 {
186186+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
187187+ #[cfg_attr(
188188+ feature = "bevy_reflect",
189189+ derive(bevy_reflect::Reflect),
190190+ reflect(Debug, Clone, PartialEq)
191191+ )]
192192+ pub enum LightColor: i32 {
182193 #[default]
183194 Primary = 0,
184195 Secondary = 1,
···11//! The interactable objects of a difficulty.
2233-use crate::{impl_duration, impl_timed, loose_enum};
33+use crate::{impl_duration, impl_timed};
44+use loose_enum::loose_enum;
45use serde::{Deserialize, Serialize};
5667/// The standard block/note that a player cuts.
···38393940loose_enum! {
4041 /// The color of a note, which determines which saber should be used to cut it.
4141- #[derive(Default, Copy)]
4242- NoteColor: i32 {
4242+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
4343+ #[cfg_attr(
4444+ feature = "bevy_reflect",
4545+ derive(bevy_reflect::Reflect),
4646+ reflect(Debug, Clone, PartialEq)
4747+ )]
4848+ pub enum NoteColor: i32 {
4349 #[default]
4450 Left = 0,
4551 Right = 1,
···48544955loose_enum! {
5056 /// The direction a note should be cut.
5151- #[derive(Default, Copy)]
5252- CutDirection: i32 {
5757+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
5858+ #[cfg_attr(
5959+ feature = "bevy_reflect",
6060+ derive(bevy_reflect::Reflect),
6161+ reflect(Debug, Clone, PartialEq)
6262+ )]
6363+ pub enum CutDirection: i32 {
5364 #[default]
5465 Up = 0,
5566 Down = 1,
···6778impl CutDirection {
6879 /// Returns the number of degrees a note is rotated, with zero degrees being a downward note.
6980 ///
7070- /// Returns zero if the cut direction is unknown/any.
8181+ /// Returns zero if the cut direction is undefined/any.
7182 pub fn get_degrees(&self) -> f32 {
7283 match self {
7384 CutDirection::Up => 180.0,
···7990 CutDirection::DownLeft => -45.0,
8091 CutDirection::DownRight => 45.0,
8192 CutDirection::Any => 0.0,
8282- CutDirection::Unknown(_) => 0.0,
9393+ CutDirection::Undefined(_) => 0.0,
8394 }
8495 }
8596}
···231242232243loose_enum! {
233244 /// Controls how an arc curves from its head to its tail.
234234- #[derive(Default, Copy)]
235235- MidAnchorMode: i32 {
245245+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
246246+ #[cfg_attr(
247247+ feature = "bevy_reflect",
248248+ derive(bevy_reflect::Reflect),
249249+ reflect(Debug, Clone, PartialEq)
250250+ )]
251251+ pub enum MidAnchorMode: i32 {
236252 #[default]
237253 Straight = 0,
238254 Clockwise = 1,
+29-9
src/info.rs
···4455#[doc(hidden)]
66pub use color_scheme::*;
77+use loose_enum::loose_enum;
7888-use crate::loose_enum;
99use serde::{Deserialize, Serialize};
10101111/// A map's `Info.dat` file.
···6767 /// The world that surrounds the player and defines which lights are available.
6868 ///
6969 /// For 90/360 degree mode, see [`AllDirectionEnvironment`].
7070- #[derive(Default)]
7171- Environment: String {
7070+ #[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
7171+ #[cfg_attr(
7272+ feature = "bevy_reflect",
7373+ derive(bevy_reflect::Reflect),
7474+ reflect(Debug, Clone, PartialEq)
7575+ )]
7676+ pub enum Environment: String {
7277 #[default]
7378 #[doc(alias = "Default")]
7479 TheFirst = "DefaultEnvironment",
···124129 /// The world that surrounds the player while playing 90/360 degree mode.
125130 ///
126131 /// For standard mode, see [`Environment`].
127127- #[derive(Default)]
128128- AllDirectionEnvironment: String {
132132+ #[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
133133+ #[cfg_attr(
134134+ feature = "bevy_reflect",
135135+ derive(bevy_reflect::Reflect),
136136+ reflect(Debug, Clone, PartialEq)
137137+ )]
138138+ pub enum AllDirectionEnvironment: String {
129139 #[default]
130140 GlassDesert = "GlassDesertEnvironment",
131141 }
···150160 ///
151161 /// Note that [`Lawless`](Self::Lawless) and [`Lightshow`](Self::Lightshow) are modded characteristics,
152162 /// and may cause problems in un-modded versions of the game.
153153- #[derive(Default)]
154154- Characteristic: String {
163163+ #[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
164164+ #[cfg_attr(
165165+ feature = "bevy_reflect",
166166+ derive(bevy_reflect::Reflect),
167167+ reflect(Debug, Clone, PartialEq)
168168+ )]
169169+ pub enum Characteristic: String {
155170 #[default]
156171 Standard = "Standard",
157172 NoArrows = "NoArrows",
···202217}
203218204219loose_enum! {
205205- #[derive(Default, Copy)]
206206- DifficultyRank: i32 {
220220+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
221221+ #[cfg_attr(
222222+ feature = "bevy_reflect",
223223+ derive(bevy_reflect::Reflect),
224224+ reflect(Debug, Clone, PartialEq)
225225+ )]
226226+ pub enum DifficultyRank: i32 {
207227 Easy = 1,
208228 Normal = 3,
209229 Hard = 5,
+2-2
src/info/color_scheme/presets.rs
···6969 /// White light colors are not currently supported, and are therefor ignored.
7070 pub fn get_color_scheme(&self) -> ColorScheme {
7171 match self {
7272- Environment::Unknown(_)
7272+ Environment::Undefined(_)
7373 | Environment::TheFirst
7474 | Environment::Triangle
7575 | Environment::Nice
···423423 rgb!(0.32222217, 0.6111111, 0.75),
424424 rgb!(0.03844783, 0.62239975, 0.90566039)
425425 ),
426426- AllDirectionEnvironment::Unknown(_) => ColorScheme::default(),
426426+ AllDirectionEnvironment::Undefined(_) => ColorScheme::default(),
427427 }
428428 }
429429}
+1-4
src/lib.rs
···2233pub mod difficulty;
44pub mod info;
55+mod loose_bool;
56pub mod timing_traits;
66-77-mod utils;
8798#[doc(hidden)]
109pub use difficulty::*;
···1211pub use info::*;
1312#[doc(hidden)]
1413pub use timing_traits::*;
1515-/// An integer repr bool, with 0 being false and 1 being true. Any other value will be saved as `Unknown`.
1616-pub use utils::LooseBool;
+92
src/loose_bool.rs
···11+//! Taken from [this example](https://github.com/AlephCubed/loose_enum/blob/main/examples/loose_bool.rs).
22+33+use core::error::Error;
44+use core::fmt::{Display, Formatter};
55+use loose_enum::loose_enum;
66+77+loose_enum! {
88+ /// An integer repr bool, with 0 being false and 1 being true. Any other value will be saved as Undefined.
99+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
1010+ #[cfg_attr(
1111+ feature = "bevy_reflect",
1212+ derive(bevy_reflect::Reflect),
1313+ reflect(Debug, Clone, PartialEq)
1414+ )]
1515+ pub enum LooseBool: i32 {
1616+ /// A falsy value of zero.
1717+ #[default]
1818+ False = 0,
1919+ /// A truthy value of one.
2020+ True = 1,
2121+ }
2222+}
2323+2424+impl LooseBool {
2525+ /// Returns true if the value is [`True`](Self::True).
2626+ pub fn is_true(&self) -> bool {
2727+ matches!(self, Self::True)
2828+ }
2929+3030+ /// Returns true if the value is [`False`](Self::False).
3131+ pub fn is_false(&self) -> bool {
3232+ matches!(self, Self::False)
3333+ }
3434+}
3535+3636+impl From<bool> for LooseBool {
3737+ fn from(value: bool) -> Self {
3838+ match value {
3939+ true => Self::True,
4040+ false => Self::False,
4141+ }
4242+ }
4343+}
4444+4545+impl TryFrom<LooseBool> for bool {
4646+ type Error = UndefinedBoolError;
4747+4848+ fn try_from(value: LooseBool) -> Result<Self, Self::Error> {
4949+ match value {
5050+ LooseBool::False => Ok(false),
5151+ LooseBool::True => Ok(true),
5252+ LooseBool::Undefined(_) => Err(UndefinedBoolError),
5353+ }
5454+ }
5555+}
5656+5757+/// Error returned when attempting to convert a [`LooseBool::Undefined`] into a `bool`.
5858+#[derive(Debug, Eq, PartialEq, Hash)]
5959+pub struct UndefinedBoolError;
6060+6161+impl Display for UndefinedBoolError {
6262+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
6363+ write!(f, "Cannot convert `LooseBool::Undefined` into `bool`.")
6464+ }
6565+}
6666+6767+impl Error for UndefinedBoolError {}
6868+6969+#[cfg(test)]
7070+mod tests {
7171+ use super::*;
7272+7373+ #[test]
7474+ fn loose_to_bool() {
7575+ assert_eq!(bool::try_from(LooseBool::True), Ok(true));
7676+ assert_eq!(bool::try_from(LooseBool::False), Ok(false));
7777+7878+ for i in 2..256 {
7979+ assert_eq!(
8080+ bool::try_from(LooseBool::Undefined(i)),
8181+ Err(UndefinedBoolError),
8282+ "Failed for i={i}"
8383+ );
8484+ }
8585+ }
8686+8787+ #[test]
8888+ fn bool_to_loose() {
8989+ assert_eq!(LooseBool::from(false), LooseBool::False);
9090+ assert_eq!(LooseBool::from(true), LooseBool::True);
9191+ }
9292+}
-180
src/utils.rs
···11-/// Defines a repr enum that supports any value. If a value does not match any case, it will be parsed as `Unknown`.
22-#[macro_export]
33-#[doc(hidden)]
44-macro_rules! loose_enum {
55- // Special case for strings:
66- (
77- $(#[$outer:meta])*
88- $name:ident: String
99- {
1010- $(
1111- $(#[$meta:meta])*
1212- $variant:ident = $value:expr
1313- ),+ $(,)?
1414- }
1515- ) => {
1616- #[derive(Debug, Clone, Eq, PartialEq, Hash)]
1717- #[cfg_attr(
1818- feature = "bevy_reflect",
1919- derive(bevy_reflect::Reflect),
2020- reflect(Debug, Clone, PartialEq)
2121- )]
2222- $(#[$outer])*
2323- pub enum $name {
2424- $(
2525- $(#[$meta])*
2626- $variant
2727- ),+,
2828- Unknown(String),
2929- }
3030-3131- impl<'de> serde::Deserialize<'de> for $name {
3232- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
3333- where
3434- D: serde::Deserializer<'de>,
3535- {
3636- let val = String::deserialize(deserializer)?;
3737- Ok(match val.as_str() {
3838- $( $value => $name::$variant, )+
3939- other => $name::Unknown(other.to_string()),
4040- })
4141- }
4242- }
4343-4444- impl serde::Serialize for $name {
4545- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
4646- where
4747- S: serde::Serializer,
4848- {
4949- match self {
5050- $( $name::$variant => str::serialize($value, serializer), )+
5151- $name::Unknown(val) => str::serialize(val, serializer),
5252- }
5353- }
5454- }
5555-5656- impl From<String> for $name {
5757- fn from(value: String) -> Self {
5858- match value.as_str() {
5959- $( $value => $name::$variant, )+
6060- other => $name::Unknown(other.to_string()),
6161- }
6262- }
6363- }
6464-6565- impl From<$name> for String {
6666- fn from(value: $name) -> Self {
6767- match value {
6868- $( $name::$variant => $value.to_string(), )+
6969- $name::Unknown(val) => val,
7070- }
7171- }
7272- }
7373- };
7474- // All other types:
7575- (
7676- $(#[$outer:meta])*
7777- $name:ident: $ty:ident
7878- {
7979- $(
8080- $(#[$meta:meta])*
8181- $variant:ident = $value:expr
8282- ),+ $(,)?
8383- }
8484- ) => {
8585- #[derive(Debug, Clone, Eq, PartialEq, Hash)]
8686- #[cfg_attr(
8787- feature = "bevy_reflect",
8888- derive(bevy_reflect::Reflect),
8989- reflect(Debug, Clone, PartialEq)
9090- )]
9191- $(#[$outer])*
9292- pub enum $name {
9393- $(
9494- $(#[$meta])*
9595- $variant
9696- ),+,
9797- Unknown($ty),
9898- }
9999-100100- impl<'de> serde::Deserialize<'de> for $name {
101101- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
102102- where
103103- D: serde::Deserializer<'de>,
104104- {
105105- let val = $ty::deserialize(deserializer)?;
106106- Ok(match val {
107107- $( $value => $name::$variant, )+
108108- other => $name::Unknown(other),
109109- })
110110- }
111111- }
112112-113113- impl serde::Serialize for $name {
114114- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115115- where
116116- S: serde::Serializer,
117117- {
118118- match self {
119119- $( $name::$variant => $ty::serialize(&$value, serializer), )+
120120- $name::Unknown(val) => $ty::serialize(val, serializer),
121121- }
122122- }
123123- }
124124-125125- impl From<$ty> for $name {
126126- fn from(value: $ty) -> Self {
127127- match value {
128128- $( $value => $name::$variant, )+
129129- other => $name::Unknown(other),
130130- }
131131- }
132132- }
133133-134134- impl From<$name> for $ty {
135135- fn from(value: $name) -> Self {
136136- match value {
137137- $( $name::$variant => $value, )+
138138- $name::Unknown(val) => val,
139139- }
140140- }
141141- }
142142- };
143143-}
144144-145145-loose_enum! {
146146- /// An integer repr bool, with 0 being false and 1 being true. Any other value will be saved as `Unknown`.
147147- #[derive(Default, Copy)]
148148- LooseBool: i32 {
149149- #[default]
150150- False = 0,
151151- True = 1,
152152- }
153153-}
154154-155155-impl LooseBool {
156156- pub fn is_true(&self) -> bool {
157157- match self {
158158- LooseBool::False => false,
159159- LooseBool::True => true,
160160- LooseBool::Unknown(_) => false,
161161- }
162162- }
163163-164164- pub fn is_false(&self) -> bool {
165165- match self {
166166- LooseBool::False => true,
167167- LooseBool::True => false,
168168- LooseBool::Unknown(_) => false,
169169- }
170170- }
171171-}
172172-173173-impl From<bool> for LooseBool {
174174- fn from(value: bool) -> Self {
175175- match value {
176176- true => Self::True,
177177- false => Self::False,
178178- }
179179- }
180180-}