1use std::convert::identity;
4
5use crate::prelude::*;
6
7#[cfg_attr(feature = "ser-de", derive(Serialize, Deserialize))]
10#[derive(Clone, Debug, PartialEq)]
11pub struct CollectionList {
12 pub version: u32,
13 pub collections: Vec<Collection>,
14}
15impl CollectionList {
16 pub fn from_bytes(bytes: &[u8]) -> Result<CollectionList, Error> {
18 Ok(collections(bytes).map(|(_rem, collections)| collections)?)
19 }
20
21 pub fn from_file<P: AsRef<Path>>(path: P) -> Result<CollectionList, Error> {
23 Self::from_bytes(&fs::read(path)?)
24 }
25
26 pub fn to_writer<W: Write>(&self, mut out: W) -> io::Result<()> {
28 self.wr(&mut out)
29 }
30
31 pub fn to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
33 self.to_writer(BufWriter::new(File::create(path)?))
34 }
35}
36
37#[cfg_attr(feature = "ser-de", derive(Serialize, Deserialize))]
40#[derive(Clone, Debug, PartialEq)]
41pub struct Collection {
42 pub name: Option<String>,
43 pub beatmap_hashes: Vec<Option<String>>,
44}
45
46fn collections(bytes: &[u8]) -> IResult<&[u8], CollectionList> {
47 let (rem, version) = int(bytes)?;
48 let (rem, collections) = length_count(map(int, identity), collection)(rem)?;
49
50 let list = CollectionList {
51 version,
52 collections,
53 };
54
55 Ok((rem, list))
56}
57
58fn collection(bytes: &[u8]) -> IResult<&[u8], Collection> {
59 let (rem, name) = opt_string(bytes)?;
60 let (rem, beatmap_hashes) = length_count(map(int, identity), opt_string)(rem)?;
61
62 let collection = Collection {
63 name,
64 beatmap_hashes,
65 };
66
67 Ok((rem, collection))
68}
69
70writer!(CollectionList [this,out] {
71 this.version.wr(out)?;
72 PrefixedList(&this.collections).wr(out)?;
73});
74
75writer!(Collection [this,out] {
76 this.name.wr(out)?;
77 PrefixedList(&this.beatmap_hashes).wr(out)?;
78});