Skip to main content

GameModSeed

Enum GameModSeed 

Source
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.

Fields

§deny_unknown_fields: bool
§

GuessMode

Try to deserialize for each GameMode and pick the first one that doesn’t fail.

Fields

§deny_unknown_fields: bool

Trait Implementations§

Source§

impl Clone for GameModSeed

Source§

fn clone(&self) -> GameModSeed

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'de> DeserializeSeed<'de> for GameModSeed

Source§

type Value = GameMod

The type produced by using this seed.
Source§

fn deserialize<D: Deserializer<'de>>( self, d: D, ) -> Result<Self::Value, D::Error>

Equivalent to the more common Deserialize::deserialize method, except with some initial piece of data (the seed) passed in.
Source§

impl<'de> Visitor<'de> for GameModSeed

Source§

type Value = GameMod

The value produced by this visitor.
Source§

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>

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>

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 more
Source§

fn visit_i64<E: DeError>(self, v: i64) -> Result<Self::Value, E>

The input contains an i64. Read more
Source§

fn visit_u32<E: DeError>(self, v: u32) -> Result<Self::Value, E>

The input contains a u32. Read more
Source§

fn visit_u64<E: DeError>(self, v: u64) -> Result<Self::Value, E>

The input contains a u64. Read more
Source§

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,

The input contains a boolean. Read more
Source§

fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
where E: Error,

The input contains an i8. Read more
Source§

fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
where E: Error,

The input contains an i16. Read more
Source§

fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where E: Error,

The input contains an i32. Read more
Source§

fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where E: Error,

The input contains a i128. Read more
Source§

fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
where E: Error,

The input contains a u8. Read more
Source§

fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
where E: Error,

The input contains a u16. Read more
Source§

fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where E: Error,

The input contains a u128. Read more
Source§

fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where E: Error,

The input contains an f32. Read more
Source§

fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where E: Error,

The input contains an f64. Read more
Source§

fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
where E: Error,

The input contains a char. Read more
Source§

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 more
Source§

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,

The input contains a byte array that lives at least as long as the Deserializer. Read more
Source§

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 more
Source§

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>,

The input contains an optional that is present. Read more
Source§

fn visit_unit<E>(self) -> Result<Self::Value, E>
where E: Error,

The input contains a unit (). Read more
Source§

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>,

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>,

The input contains an enum. Read more
Source§

impl Copy for GameModSeed

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<'de, T> Expected for T
where T: Visitor<'de>,

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error>

Format an explanation of what data was being expected. Same signature as the Display and Debug traits.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> LayoutRaw for T

Source§

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
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

Source§

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>>)

Writes data to out indicating that a T is niched.
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.