Skip to main content

steel_core/player/advancement/
saving.rs

1use crate::player::advancement::progress::{AdvancementProgress, CriterionProgress};
2use rustc_hash::FxHashMap;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::borrow::Cow;
5use steel_utils::Identifier;
6use steel_utils::serial::vec_as_map;
7
8/// JSON representation of a player's persisted advancement progress.
9#[derive(Deserialize)]
10pub(crate) struct PersistedAdvancements {
11    /// Progress keyed by advancement identifier.
12    #[serde(with = "vec_as_map")]
13    pub(crate) entries: Vec<(Identifier, AdvancementProgress)>,
14}
15
16/// Borrowed variant used to serialize a save without cloning the entries.
17#[derive(Serialize)]
18pub(crate) struct PersistedAdvancementsRef<'a> {
19    /// Progress keyed by advancement identifier.
20    #[serde(with = "vec_as_map")]
21    pub(crate) entries: &'a [(Identifier, AdvancementProgress)],
22}
23
24impl Serialize for AdvancementProgress {
25    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
26    where
27        S: Serializer,
28    {
29        let done = self
30            .criteria()
31            .iter()
32            .filter(|(_key, criterion)| criterion.is_done());
33        serializer.collect_map(done)
34    }
35}
36
37impl<'de> Deserialize<'de> for AdvancementProgress {
38    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
39    where
40        D: Deserializer<'de>,
41    {
42        let criteria =
43            FxHashMap::<Cow<'static, str>, CriterionProgress>::deserialize(deserializer)?;
44        Ok(Self::new(criteria))
45    }
46}