1use crate::{
2 formats::uci,
3 game::{self, Node, Slot},
4};
5
6#[derive(Clone, Debug, Deserialize, Serialize)]
7pub struct Archive {
8 #[serde(default, skip_serializing_if = "Vec::is_empty")]
9 pub games: Vec<Game>,
10 #[serde(default, skip_serializing_if = "Vec::is_empty")]
11 pub plays: Vec<Play>,
12}
13
14#[derive(Clone, Debug, Deserialize, Serialize)]
15pub struct Game {
16 #[serde(default)]
17 pub roster: game::Roster,
18 #[serde(default, skip_serializing_if = "Vec::is_empty")]
19 pub tags: Vec<game::Tag>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub intro: Option<game::Text>,
22 #[serde(default, skip_serializing_if = "game::Outcome::is_unknown")]
23 pub outcome: game::Outcome,
24 pub start: String,
25 #[serde(default, skip_serializing_if = "Vec::is_empty")]
26 pub options: Vec<Slot>,
27}
28
29#[derive(Clone, Debug, Deserialize, Serialize)]
30pub struct Play {
31 pub slot: Slot,
32 #[serde(default, skip_serializing_if = "Node::is_start")]
33 pub previous: Node,
34 #[serde(default, skip_serializing_if = "game::Meta::is_empty")]
35 pub meta: game::Meta,
36 pub play: uci::Move,
37 #[serde(default, skip_serializing_if = "Vec::is_empty")]
38 pub options: Vec<Slot>,
39}
40
41impl game::Outcome {
42 pub fn is_unknown(&self) -> bool {
43 matches!(self, game::Outcome::Unknown)
44 }
45}
46
47impl game::Game {
48 pub fn store(&self) -> Archive {
49 Archive {
50 games: vec![Game::from(self)],
51 plays: self.tree.plays().map(Play::from).collect(),
52 }
53 }
54
55 pub fn load(_archive: Archive) -> game::Result<Self> {
56 todo!()
57 }
58}
59
60impl From<&game::Game> for Game {
61 fn from(game: &game::Game) -> Self {
62 Self {
63 roster: game.roster.clone(),
64 tags: game.tags.clone(),
65 intro: game.intro.clone(),
66 outcome: game.outcome,
67 start: game.start().fen(),
68 options: game.tree.start().to_vec(),
69 }
70 }
71}
72
73impl From<&game::Play> for Play {
74 fn from(play: &game::Play) -> Self {
75 Self {
76 slot: play.slot(),
77 previous: play.previous(),
78 meta: play.meta.clone(),
79 play: uci::Move {
80 from: play.play.from,
81 to: play.play.to,
82 promotion: play.play.promotes(),
83 },
84 options: play.options.clone(),
85 }
86 }
87}