pub enum GameModSeed {
Mode {
mode: GameMode,
deny_unknown_fields: bool,
},
GuessMode {
deny_unknown_fields: bool,
},
}Available on crate feature
serde only.Expand description
Struct to pass parameters into a GameMod deserialization.
This deserializes an integer as bitflags, a string as an acronym, or a map
as a GameMod struct.
§Examples
If the GameMode is available, we can use the Mode variant.
use rosu_mods::{GameMod, GameMode, serde::GameModSeed, generated_mods::DifficultyAdjustMania};
use serde::de;
// Note that `GameMod` does not implement `Deserialize` so we must
// implement it manually.
#[derive(serde::Deserialize)]
struct MyStruct(
#[serde(deserialize_with = "custom_deser")]
GameMod
);
// If this is our JSON...
const JSON: &str = r#"{
"mode": 3,
"mod": {
"acronym": "DA",
"settings": {
"drain_rate": 0.73
}
}
}"#;
// ... our deserialization could look like this
fn custom_deser<'de, D: de::Deserializer<'de>>(d: D) -> Result<GameMod, D::Error> {
struct MyVisitor;
impl<'de> de::Visitor<'de> for MyVisitor {
type Value = GameMod;
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("MyStruct")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>
{
let Some("mode") = map.next_key()? else {
return Err(de::Error::custom("expected `mode` as first field"));
};
let mode: GameMode = map.next_value()?;
let Some("mod") = map.next_key()? else {
return Err(de::Error::custom("expected `mod` as second field"));
};
let seed = GameModSeed::Mode { mode, deny_unknown_fields: true }; // <-
map.next_value_seed(seed)
}
}
d.deserialize_map(MyVisitor)
}
let MyStruct(gamemod) = serde_json::from_str(JSON).unwrap();
assert_eq!(
gamemod,
GameMod::DifficultyAdjustMania(DifficultyAdjustMania {
drain_rate: Some(0.73),
..Default::default()
})
);If the mode is not available, we can use the GuessMode variant.
use rosu_mods::{GameMod, serde::GameModSeed, generated_mods::DifficultyAdjustTaiko};
use serde::de;
#[derive(serde::Deserialize)]
struct MyStruct(
#[serde(deserialize_with = "custom_deser")]
GameMod,
);
// No mode in here so we can only guess
const JSON: &str = r#"{
"acronym": "DA",
"settings": {
"scroll_speed": 0.95
}
}"#;
// For the above JSON, the deserialization will try to use each mode's
// `GameMod` variant for the `DA` acronym.
// First it tries `DifficultyAdjustOsu` but sees that it has no
// `scroll_speed` field so it continues on and succeeds for the taiko
// variant. Note that if `deny_unknown_fields` was set to `false`, the
// unknown `scroll_speed` field would not have caused an error when
// deserializing the `DifficultyAdjustOsu`.
fn custom_deser<'de, D: de::Deserializer<'de>>(d: D) -> Result<GameMod, D::Error> {
d.deserialize_map(GameModSeed::GuessMode { deny_unknown_fields: true })
}
let MyStruct(gamemod) = serde_json::from_str(JSON).unwrap();
assert_eq!(
gamemod,
GameMod::DifficultyAdjustTaiko(DifficultyAdjustTaiko {
scroll_speed: Some(0.95),
..Default::default()
})
);Variants§
Mode
Use a specified GameMode for deserialization.
GuessMode
Try to deserialize for each GameMode and pick the first one that
doesn’t fail.
Trait Implementations§
Source§impl Clone for GameModSeed
impl Clone for GameModSeed
Source§fn clone(&self) -> GameModSeed
fn clone(&self) -> GameModSeed
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl<'de> DeserializeSeed<'de> for GameModSeed
impl<'de> DeserializeSeed<'de> for GameModSeed
Source§impl<'de> Visitor<'de> for GameModSeed
impl<'de> Visitor<'de> for GameModSeed
Source§fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult
fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult
Format a message stating what data this Visitor expects to receive. Read more
Source§fn visit_str<E: DeError>(self, v: &str) -> Result<Self::Value, E>
fn visit_str<E: DeError>(self, v: &str) -> Result<Self::Value, E>
The input contains a string. The lifetime of the string is ephemeral and
it may be destroyed after this method returns. Read more
Source§fn visit_string<E: DeError>(self, v: String) -> Result<Self::Value, E>
fn visit_string<E: DeError>(self, v: String) -> Result<Self::Value, E>
Available on crate features
std or alloc only.The input contains a string and ownership of the string is being given
to the
Visitor. Read moreSource§fn visit_i64<E: DeError>(self, v: i64) -> Result<Self::Value, E>
fn visit_i64<E: DeError>(self, v: i64) -> Result<Self::Value, E>
The input contains an
i64. Read moreSource§fn visit_u32<E: DeError>(self, v: u32) -> Result<Self::Value, E>
fn visit_u32<E: DeError>(self, v: u32) -> Result<Self::Value, E>
The input contains a
u32. Read moreSource§fn visit_u64<E: DeError>(self, v: u64) -> Result<Self::Value, E>
fn visit_u64<E: DeError>(self, v: u64) -> Result<Self::Value, E>
The input contains a
u64. Read moreSource§fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error>
fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error>
The input contains a key-value map. Read more
Source§fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>where
E: Error,
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>where
E: Error,
The input contains a boolean. Read more
Source§fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>where
E: Error,
fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>where
E: Error,
The input contains an
i8. Read moreSource§fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>where
E: Error,
fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>where
E: Error,
The input contains an
i16. Read moreSource§fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>where
E: Error,
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>where
E: Error,
The input contains an
i32. Read moreSource§fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>where
E: Error,
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>where
E: Error,
The input contains a
i128. Read moreSource§fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>where
E: Error,
fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>where
E: Error,
The input contains a
u8. Read moreSource§fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>where
E: Error,
fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>where
E: Error,
The input contains a
u16. Read moreSource§fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>where
E: Error,
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>where
E: Error,
The input contains a
u128. Read moreSource§fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>where
E: Error,
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>where
E: Error,
The input contains an
f32. Read moreSource§fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>where
E: Error,
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>where
E: Error,
The input contains an
f64. Read moreSource§fn visit_char<E>(self, v: char) -> Result<Self::Value, E>where
E: Error,
fn visit_char<E>(self, v: char) -> Result<Self::Value, E>where
E: Error,
The input contains a
char. Read moreSource§fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>where
E: Error,
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>where
E: Error,
The input contains a string that lives at least as long as the
Deserializer. Read moreSource§fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>where
E: Error,
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>where
E: Error,
The input contains a byte array. The lifetime of the byte array is
ephemeral and it may be destroyed after this method returns. Read more
Source§fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>where
E: Error,
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>where
E: Error,
The input contains a byte array that lives at least as long as the
Deserializer. Read moreSource§fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>where
E: Error,
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>where
E: Error,
Available on crate features
std or alloc only.The input contains a byte array and ownership of the byte array is being
given to the
Visitor. Read moreSource§fn visit_none<E>(self) -> Result<Self::Value, E>where
E: Error,
fn visit_none<E>(self) -> Result<Self::Value, E>where
E: Error,
The input contains an optional that is absent. Read more
Source§fn visit_some<D>(
self,
deserializer: D,
) -> Result<Self::Value, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn visit_some<D>(
self,
deserializer: D,
) -> Result<Self::Value, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
The input contains an optional that is present. Read more
Source§fn visit_unit<E>(self) -> Result<Self::Value, E>where
E: Error,
fn visit_unit<E>(self) -> Result<Self::Value, E>where
E: Error,
The input contains a unit
(). Read moreSource§fn visit_newtype_struct<D>(
self,
deserializer: D,
) -> Result<Self::Value, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn visit_newtype_struct<D>(
self,
deserializer: D,
) -> Result<Self::Value, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
The input contains a newtype struct. Read more
Source§fn visit_seq<A>(
self,
seq: A,
) -> Result<Self::Value, <A as SeqAccess<'de>>::Error>where
A: SeqAccess<'de>,
fn visit_seq<A>(
self,
seq: A,
) -> Result<Self::Value, <A as SeqAccess<'de>>::Error>where
A: SeqAccess<'de>,
The input contains a sequence of elements. Read more
Source§fn visit_enum<A>(
self,
data: A,
) -> Result<Self::Value, <A as EnumAccess<'de>>::Error>where
A: EnumAccess<'de>,
fn visit_enum<A>(
self,
data: A,
) -> Result<Self::Value, <A as EnumAccess<'de>>::Error>where
A: EnumAccess<'de>,
The input contains an enum. Read more
impl Copy for GameModSeed
Auto Trait Implementations§
impl Freeze for GameModSeed
impl RefUnwindSafe for GameModSeed
impl Send for GameModSeed
impl Sync for GameModSeed
impl Unpin for GameModSeed
impl UnsafeUnpin for GameModSeed
impl UnwindSafe for GameModSeed
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
The archived version of the pointer metadata for this type.
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Converts some archived metadata to the pointer metadata for itself.
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Returns the layout of the type.
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Returns whether the given value has been niched. Read more
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
Writes data to
out indicating that a T is niched.