libgtp/model/
types.rs

1use crate::model::Entity;
2use alloc::borrow::ToOwned;
3use alloc::fmt::Display;
4use core::fmt;
5use alloc::format;
6use alloc::string::String;
7use alloc::string::ToString;
8use alloc::vec::Vec;
9use core::iter::FromIterator;
10use core::ops::IndexMut;
11use core::ops::Index;
12use core::str::FromStr;
13use super::ParseError;
14
15//use log::debug;
16
17
18// MACROS
19#[macro_export]
20macro_rules! collection {
21    ($($elem:expr),*) => {
22        {
23            let mut v : Vec<crate::model::SimpleEntity> = Vec::new();
24
25            $(
26                v.push($elem);
27            )*
28            crate::model::Collection::from_vec(v)
29        }
30    };
31}
32
33#[macro_export]
34macro_rules! list {
35    ($t:ty; $($elem:expr),*) => {
36        {
37            let mut v : Vec<$t> = Vec::new();
38
39            $(
40                v.push($elem);
41            )*
42            crate::model::types::List::from_vec(v)
43        }
44    };
45}
46
47#[derive(Debug, Clone, Copy)]
48pub enum Boolean {
49    True,
50    False,
51}
52
53impl Display for Boolean {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        match self {
56            Self::True => write!(f, "true"),
57            Self::False => write!(f, "false"),
58        }
59    }
60}
61
62impl FromStr for Boolean {
63    type Err = crate::model::ParseError;
64
65    fn from_str(str: &str) -> Result<Self, Self::Err> {
66        match str.to_uppercase().as_str() {
67            "TRUE" => Ok(Self::True),
68            "FALSE" => Ok(Self::False),
69            _ => Err(Self::Err::WrongBool),
70        }
71    }
72}
73
74#[derive(Debug, Clone)]
75pub struct Score(String);
76
77impl FromStr for Score {
78    type Err = crate::model::ParseError;
79
80    fn from_str(str: &str) -> Result<Self, Self::Err> {
81        if str.is_empty() {
82            return Err(Self::Err::EmptyString);
83        } else if str == "0" {
84            Ok(Self(str.to_string()))
85        } else {
86            let split: Vec<&str> = str.split('+').collect();
87            if split.len() > 2 {
88                return Err(Self::Err::WrongScore);
89            }
90
91            match split[0] {
92                "W" | "B" => (),
93                _ => {return Err(Self::Err::WrongColor);}
94            }
95
96            split[1].parse::<f32>()?;
97
98            Ok(Self(str.to_string()))
99        }
100    }
101}
102
103impl Display for Score {
104    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105        write!(f, "{}", self.0)
106    }
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
110pub enum Vertex {
111    Coord(u8, u8),
112    Pass,
113    Resign,
114}
115
116impl Entity for Vertex {}
117
118impl FromStr for Vertex {
119    type Err = ParseError;
120
121    fn from_str(str: &str) -> Result<Self, Self::Err> {
122        if str.is_empty() {
123            return Err(Self::Err::EmptyString);
124        }
125        let str = str.to_uppercase();
126        if str == "PASS" {
127            return Ok(Self::Pass)
128        } else if str == "RESIGN" {
129            return Ok(Self::Resign)
130        } else if str == "" {
131            return Err(ParseError::WrongCoordinates)
132        }
133
134        let mut c = str.bytes().next().unwrap() - 64;
135        if (1..=20).contains(&c) {
136            if c > 9 { // We skip I on the goban for readability
137                c -= 1;
138            }
139
140            if let Ok(number) = str[1..].parse::<u8>() {
141                Ok(Self::Coord(c, number))
142            } else {
143                Err(ParseError::WrongCoordinates)
144            }
145        } else {
146            Err(ParseError::WrongCoordinates)
147        }
148    }
149}
150
151impl Display for Vertex {
152    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
153        match self {
154            Self::Coord(x, y) => {
155                let mut x : u8 = x.clone();
156                if x > 8 { // We skip I on the goban for readability
157                    x = x + 1;
158                }
159                write!(f, "{}{}", ((x+64) as char).to_uppercase(), y)
160            },
161            Self::Pass => write!(f, "PASS"),
162            Self::Resign => write!(f, "RESIGN"),
163        }
164    }
165}
166
167impl From<Vertex> for String {
168    fn from(vertex: Vertex) -> Self {
169        format!("{}", vertex)
170    }
171}
172
173impl core::cmp::PartialEq<&str> for Vertex {
174    fn eq(&self, rhs: &&str) -> bool {
175        format!("{}", self) == *rhs.to_uppercase()
176    }
177}
178
179impl core::cmp::PartialEq<String> for Vertex {
180    fn eq(&self, rhs: &String) -> bool {
181        format!("{}", self) == *rhs.to_uppercase()
182    }
183}
184
185impl Vertex {
186    pub const fn to_tuple(&self) -> Option<(u8, u8)> {
187        match self {
188            Self::Coord(x, y) => Some((*x, *y)),
189            Self::Pass => None,
190            Self::Resign => None,
191        }
192    }
193}
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
196pub enum Color {
197    Black,
198    White,
199}
200
201impl Entity for Color {}
202
203impl Display for Color {
204    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
205        match self {
206            Self::Black => write!(f, "B"),
207            Self::White => write!(f, "W"),
208        }
209    }
210}
211
212impl FromStr for Color {
213    type Err = ParseError;
214
215    fn from_str(str: &str) -> Result<Self, Self::Err> {
216        if str.is_empty() {
217            return Err(Self::Err::EmptyString);
218        }
219        let str = str.to_uppercase();
220        match &*str {
221            "B" | "BLACK" => Ok(Self::Black),
222            "W" | "WHITE" => Ok(Self::White),
223            _ => Err(ParseError::WrongColor),
224        }
225    }
226}
227
228impl From<Color> for String {
229    fn from(col: Color) -> Self {
230        format!("{}", col)
231    }
232}
233
234impl core::cmp::PartialEq<&str> for Color {
235    fn eq(&self, rhs: &&str) -> bool {
236        format!("{}", self) == *rhs.to_uppercase()
237    }
238}
239
240impl core::cmp::PartialEq<String> for Color {
241    fn eq(&self, rhs: &String) -> bool {
242        format!("{}", self) == *rhs.to_uppercase()
243    }
244}
245
246#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
247pub struct Move {
248    pub color: Color,
249    pub vertex: Vertex,
250}
251
252impl Entity for Move {}
253
254impl Display for Move {
255    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
256        write!(f, "{} {}", self.color, self.vertex)
257    }
258}
259
260impl FromStr for Move {
261    type Err = ParseError;
262
263    fn from_str(str: &str) -> Result<Self, Self::Err> {
264        if str.is_empty() {
265            return Err(ParseError::EmptyString);
266        }
267        let str = str.to_uppercase();
268        let mut str = str.split_ascii_whitespace();
269        Ok(Move {
270            color: str.next().unwrap().parse()?,
271            vertex: str.next().unwrap().parse()?,
272        })
273    }
274}
275
276impl From<Move> for String {
277    fn from(mov: Move) -> Self {
278        format!("{}", mov)
279    }
280}
281
282impl core::cmp::PartialEq<&str> for Move {
283    fn eq(&self, rhs: &&str) -> bool {
284        format!("{}", self) == *rhs.to_uppercase()
285    }
286}
287
288impl core::cmp::PartialEq<String> for Move {
289    fn eq(&self, rhs: &String) -> bool {
290        format!("{}", self) == *rhs.to_uppercase()
291    }
292}
293
294#[derive(Debug, Clone, Copy, Hash)]
295pub enum SimpleEntity {
296    Vertex(Vertex),
297    Color(Color),
298    Move(Move),
299}
300
301impl alloc::fmt::Display for SimpleEntity {
302    fn fmt(&self, f: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
303        match self {
304            SimpleEntity::Vertex(v) => write!(f, "{}", v),
305            SimpleEntity::Color(c) => write!(f, "{}", c),
306            SimpleEntity::Move(m) => write!(f, "{}", m),
307        }
308    }
309}
310
311impl FromStr for SimpleEntity {
312    type Err = ParseError;
313
314    fn from_str(str: &str) -> Result<SimpleEntity, Self::Err> {
315        if let Ok(v) = str.parse::<Vertex>() {
316            Ok(SimpleEntity::Vertex(v))
317        } else if let Ok(c) = str.parse::<Color>() {
318            Ok(SimpleEntity::Color(c))
319        } else if let Ok(m) = str.parse::<Move>() {
320            Ok(SimpleEntity::Move(m))
321        } else {
322            Err(ParseError::WrongSimpleEntity)
323        }
324    }
325}
326
327impl From<Vertex> for SimpleEntity {
328    fn from(v: Vertex) -> Self {
329        SimpleEntity::Vertex(v)
330    }
331}
332
333impl From<Color> for SimpleEntity {
334    fn from(c: Color) -> Self {
335        SimpleEntity::Color(c)
336    }
337}
338
339impl From<Move> for SimpleEntity {
340    fn from(m: Move) -> Self {
341        SimpleEntity::Move(m)
342    }
343}
344
345impl SimpleEntity {
346    pub fn as_vertex(self) -> Option<Vertex> {
347        match self {
348            Self::Vertex(v) => Some(v),
349            _ => None,
350        }
351    }
352
353    pub fn as_color(self) -> Option<Color> {
354        match self {
355            Self::Color(c) => Some(c),
356            _ => None,
357        }
358    }
359
360    pub fn as_move(self) -> Option<Move> {
361        match self {
362            Self::Move(m) => Some(m),
363            _ => None,
364        }
365    }
366}
367
368#[derive(Debug, Clone, Hash)]
369pub struct Collection(Vec<SimpleEntity>);
370
371impl Entity for Collection {}
372
373impl Display for Collection {
374    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
375        if !self.0.is_empty() {
376            write!(f, "{}", self.0[0])?;
377            if self.0.len() > 1 {
378                for entity in &self.0[1..] {
379                    write!(f, " {}", entity)?;
380                }
381            }
382            Ok(())
383        } else {
384            Ok(())
385        }
386    }
387}
388
389impl FromStr for Collection {
390    type Err = ParseError;
391
392    fn from_str(str: &str) -> Result<Self, Self::Err> {
393        let elems : Vec<SimpleEntity> = str.to_uppercase().split_ascii_whitespace()
394            .map(|e| if let Ok(elem) = e.parse::<SimpleEntity>() {
395                elem
396            } else {
397                panic!()
398            }).collect();
399
400        Ok(Self(elems))
401    }
402}
403
404impl Index<usize> for Collection {
405    type Output = SimpleEntity;
406
407    fn index(&self, i: usize) -> &Self::Output {
408        &self.0[i]
409    }
410}
411
412impl IndexMut<usize> for Collection {
413    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Self::Output {
414        &mut self.0[i]
415    }
416}
417
418impl Default for Collection {
419    fn default() -> Self {
420        Self {
421            0: Vec::new(),
422        }
423    }
424}
425
426impl From<Vec<SimpleEntity>> for Collection {
427    fn from(vec: Vec<SimpleEntity>) -> Self {
428        Self(vec)
429    }
430}
431
432impl FromIterator<SimpleEntity> for Collection {
433    fn from_iter<I: IntoIterator<Item=SimpleEntity>>(it: I) -> Self {
434        Self(it.into_iter().collect())
435    }
436}
437
438impl IntoIterator for Collection {
439    type Item = SimpleEntity;
440    type IntoIter = alloc::vec::IntoIter<Self::Item>;
441
442    fn into_iter(self) -> Self::IntoIter {
443        self.0.into_iter()
444    }
445}
446
447impl<'a> IntoIterator for &'a Collection {
448    type Item = SimpleEntity;
449    type IntoIter = alloc::vec::IntoIter<Self::Item>;
450
451    fn into_iter(self) -> Self::IntoIter {
452        self.0.to_owned().into_iter()
453    }
454}
455
456impl<'a> IntoIterator for &'a mut Collection {
457    type Item = SimpleEntity;
458    type IntoIter = alloc::vec::IntoIter<Self::Item>;
459
460    fn into_iter(self) -> Self::IntoIter {
461        self.0.to_owned().into_iter()
462    }
463}
464
465impl Collection {
466    pub fn new() -> Self {
467        Self::default()
468    }
469
470    pub const fn from_vec(vec: Vec<SimpleEntity>) -> Self {
471        Self(vec)
472    }
473
474    pub fn push(&mut self, elem: SimpleEntity) {
475        self.0.push(elem);
476    }
477
478    pub fn remove(&mut self, index: usize) -> SimpleEntity {
479        self.0.remove(index)
480    }
481
482    pub fn into_vec(self) -> Vec<SimpleEntity> {
483        self.0
484    }
485
486    pub const fn inner(&self) -> &Vec<SimpleEntity> {
487        &self.0
488    }
489
490    pub fn mut_inner(&mut self) -> &mut Vec<SimpleEntity> {
491        &mut self.0
492    }
493
494    pub fn iter(&self) -> core::slice::Iter<'_, SimpleEntity> {
495        self.0.iter()
496    }
497
498    pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, SimpleEntity> {
499        self.0.iter_mut()
500    }
501}
502
503#[derive(Debug, Clone, Hash)]
504pub struct List<T : Entity>(Vec<T>);
505
506impl<T: Entity> Entity for List<T> {}
507
508impl<T: Entity> Display for List<T> {
509    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
510        if !self.0.is_empty() {
511            write!(f, "{}", self.0[0])?;
512            if self.0.len() > 1 {
513                for entity in &self.0[1..] {
514                    write!(f, " {}", entity)?;
515                }
516            }
517            Ok(())
518        } else {
519            Ok(())
520        }
521    }
522}
523
524impl<T: Entity> FromStr for List<T> {
525    type Err = ParseError;
526
527    fn from_str(str: &str) -> Result<Self, Self::Err> {
528        let check_line_return: Vec<&str> = str.split('\n').collect();
529        if check_line_return.len() > 2 {
530            return Err(Self::Err::WrongArgs);
531        }
532
533        let elems : Vec<T> = str.split_ascii_whitespace()
534            .take_while(|e| e.clone() != "".to_string())
535            .map(|e| if let Ok(elem) = e.parse::<T>() {
536                elem
537            } else {
538                panic!()
539            }).collect();
540
541        Ok(Self(elems))
542    }
543}
544
545impl<T: Entity> Index<usize> for List<T> {
546    type Output = T;
547
548    fn index(&self, i: usize) -> &Self::Output {
549        &self.0[i]
550    }
551}
552
553impl<T: Entity> IndexMut<usize> for List<T> {
554    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut Self::Output {
555        &mut self.0[i]
556    }
557}
558
559impl<T: Entity> Default for List<T> {
560    fn default() -> Self {
561        Self {
562            0: Vec::new(),
563        }
564    }
565}
566
567impl<T: Entity> From<Vec<T>> for List<T> {
568    fn from(vec: Vec<T>) -> Self {
569        Self(vec)
570    }
571}
572
573impl<T: Entity> FromIterator<T> for List<T> {
574    fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Self {
575        Self(it.into_iter().collect())
576    }
577}
578
579impl<T: Entity> IntoIterator for List<T> {
580    type Item = T;
581    type IntoIter = alloc::vec::IntoIter<Self::Item>;
582
583    fn into_iter(self) -> Self::IntoIter {
584        self.0.into_iter()
585    }
586}
587
588impl<'a, T: Entity> IntoIterator for &'a List<T> {
589    type Item = T;
590    type IntoIter = alloc::vec::IntoIter<Self::Item>;
591
592    fn into_iter(self) -> Self::IntoIter {
593        self.0.to_owned().into_iter()
594    }
595}
596
597impl<'a, T: Entity> IntoIterator for &'a mut List<T> {
598    type Item = T;
599    type IntoIter = alloc::vec::IntoIter<Self::Item>;
600
601    fn into_iter(self) -> Self::IntoIter {
602        self.0.to_owned().into_iter()
603    }
604}
605
606impl<T: Entity> List<T> {
607    pub fn new() -> Self {
608        Self::default()
609    }
610
611    pub fn from_vec(vec: Vec<T>) -> Self {
612        Self(vec)
613    }
614
615    pub fn push(&mut self, elem: T) {
616        self.0.push(elem);
617    }
618
619    pub fn remove(&mut self, index: usize) -> T {
620        self.0.remove(index)
621    }
622
623    pub fn into_vec(self) -> Vec<T> {
624        self.0
625    }
626
627    pub fn inner(&self) -> &Vec<T> {
628        &self.0
629    }
630
631    pub fn mut_inner(&mut self) -> &mut Vec<T> {
632        &mut self.0
633    }
634
635    pub fn iter(&self) -> core::slice::Iter<'_, T> {
636        self.0.iter()
637    }
638
639    pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
640        self.0.iter_mut()
641    }
642}