1pub mod events;
2mod player;
3pub mod token;
4
5use crate::error::{Error, Result};
6pub use player::Player;
7
8#[derive(Debug, PartialEq)]
9pub struct Gcg {
10 pub player1: Player,
11 pub player2: Player,
12 pub description: Option<String>,
14}
15
16impl Gcg {
17 pub fn build(text: &str) -> Result<Gcg> {
18 let mut player1 = None::<Player>;
19 let mut player2 = None::<Player>;
20 let mut description = None::<String>;
21
22 for (i, line) in text.lines().enumerate() {
23 if line.starts_with("#player1") {
24 let player = Player::build(line).map_err(|e| Error::InvalidLine {
25 line_index: i.saturating_add(1),
26 source: e,
27 })?;
28 player1 = Some(player);
29 } else if line.starts_with("#player2") {
30 let player = Player::build(line).map_err(|e| Error::InvalidLine {
31 line_index: i.saturating_add(1),
32 source: e,
33 })?;
34 player2 = Some(player);
35 } else if line.starts_with("#description") {
36 let (_, desc) = line.split_once(' ').unwrap_or_default();
37
38 description = Some(desc.to_string());
39 } else {
40 return Err(Error::UnknownPragma {
41 line: text.to_string(),
42 line_index: i.saturating_add(1),
43 });
44 }
45 }
46
47 let gcg = Gcg {
48 player1: player1.ok_or_else(|| Error::MissingPragma {
49 keyword: "player1".to_string(),
50 })?,
51 player2: player2.ok_or_else(|| Error::MissingPragma {
52 keyword: "player2".to_string(),
53 })?,
54 description,
55 };
56
57 Ok(gcg)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use anyhow::{Ok, Result};
65
66 #[test]
67 fn should_parse_player_names() -> Result<()> {
68 let text = [
69 "#player1 20jasper Jacob Asper",
70 "#player2 xXFerrisXx Ferris The Crab",
71 ]
72 .join("\n");
73
74 let gcg = Gcg::build(&text)?;
75
76 assert_eq!(
77 gcg.player1,
78 Player {
79 nickname: "20jasper".to_string(),
80 full_name: "Jacob Asper".to_string(),
81 },
82 );
83 assert_eq!(
84 gcg.player2,
85 Player {
86 nickname: "xXFerrisXx".to_string(),
87 full_name: "Ferris The Crab".to_string(),
88 },
89 );
90
91 Ok(())
92 }
93
94 #[test]
95 fn should_error_when_missing_player() {
96 let text = ["#player2 20jasper Jacob Asper"].join("\n");
97
98 let error = Gcg::build(&text)
99 .unwrap_err()
100 .to_string()
101 .to_lowercase();
102
103 assert!(error.contains("player1"));
104 }
105
106 #[test]
107 fn should_error_with_unknown_pragma() {
108 let text = ["#whatisthispragma what idk"].join("\n");
109
110 let error = Gcg::build(&text)
111 .unwrap_err()
112 .to_string()
113 .to_lowercase();
114
115 assert!(error.contains("unknown pragma"));
116 assert!(error.contains("#whatisthispragma"));
117 }
118
119 #[test]
120 fn should_parse_description() -> Result<()> {
121 let text = [
122 "#player1 20jasper Jacob Asper",
123 "#player2 xXFerrisXx Ferris The Crab",
124 "#description 20jasper vs xXFerrisXx",
125 ]
126 .join("\n");
127
128 let gcg = Gcg::build(&text)?;
129
130 assert_eq!(gcg.description, Some("20jasper vs xXFerrisXx".to_string()));
131
132 Ok(())
133 }
134}