use crate::{
prelude::*,
replay::{replay, Replay},
};
#[cfg_attr(feature = "ser-de", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct ScoreList {
pub version: u32,
pub beatmaps: Vec<BeatmapScores>,
}
impl ScoreList {
pub fn from_bytes(bytes: &[u8]) -> Result<ScoreList, Error> {
scores(bytes).map(|(_rem, scores)| scores)
}
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<ScoreList, Error> {
Self::from_bytes(&fs::read(path)?)
}
pub fn to_writer<W: Write>(&self, mut out: W) -> io::Result<()> {
self.wr(&mut out)
}
pub fn save<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
self.to_writer(BufWriter::new(File::create(path)?))
}
}
#[cfg_attr(feature = "ser-de", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct BeatmapScores {
pub hash: Option<String>,
pub scores: Vec<Replay>,
}
fn scores(bytes: &[u8]) -> Result<(&[u8], ScoreList), Error> {
let (rem, version) = int(bytes)?;
let (mut rem, len) = int(rem)?;
let mut beatmaps = Vec::with_capacity(len as usize);
for _ in 0..len {
let (rem_, beatmap_scores) = beatmap_scores(rem)?;
beatmaps.push(beatmap_scores);
rem = rem_;
}
let list = ScoreList { version, beatmaps };
Ok((rem, list))
}
fn beatmap_scores(bytes: &[u8]) -> Result<(&[u8], BeatmapScores), Error> {
let (rem, hash) = opt_string(bytes)?;
let (mut rem, len) = int(rem)?;
let mut scores = Vec::with_capacity(len as usize);
for _ in 0..len {
let (rem_, replay) = replay(rem, false)?;
rem = rem_;
scores.push(replay);
}
let scores = BeatmapScores { hash, scores };
Ok((rem, scores))
}
writer!(ScoreList [this,out] {
this.version.wr(out)?;
PrefixedList(&this.beatmaps).wr(out)?;
});
writer!(BeatmapScores [this,out] {
this.hash.wr(out)?;
PrefixedList(&this.scores).wr_args(out,None)?;
});