Skip to main content

chess/
arbitrary.rs

1use arbitrary::{Arbitrary, Error, Result, Unstructured};
2
3use crate::{
4    Game, Key, Position, Scharnagl,
5    formats::{Fen, Pgn},
6    game::Mode,
7    key::base58::Base58,
8};
9
10impl<'a> Arbitrary<'a> for Base58 {
11    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
12        Vec::<u8>::arbitrary(input).map(|bytes| Self::new(&bytes))
13    }
14}
15
16impl<'a> Arbitrary<'a> for Fen {
17    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
18        Position::arbitrary(input).map(Into::into)
19    }
20}
21
22impl<'a> Arbitrary<'a> for Game {
23    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
24        let choices = Vec::<u8>::arbitrary(input)?;
25        let game = match Mode::arbitrary(input)? {
26            Mode::Chess => Game::new(Position::start()),
27            Mode::Freestyle => Game::freestyle(Position::freestyle(Scharnagl::arbitrary(input)?)),
28        };
29        let mut cursor = game.into_cursor();
30
31        for choice in choices.into_iter().take(256) {
32            let position = cursor.position();
33            let legal = position.legal();
34            if legal.is_empty() {
35                break;
36            }
37            let play = legal[usize::from(choice) % legal.len()];
38            cursor.option_mut_or_push(play).map_err(|_| Error::IncorrectFormat)?;
39        }
40
41        Ok(cursor.into_game())
42    }
43}
44
45impl<'a> Arbitrary<'a> for Key {
46    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
47        u128::arbitrary(input).map(Self)
48    }
49}
50
51impl<'a> Arbitrary<'a> for Mode {
52    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
53        bool::arbitrary(input).map(Into::into)
54    }
55}
56
57impl<'a> Arbitrary<'a> for Pgn {
58    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
59        Game::arbitrary(input).map(Into::into)
60    }
61}
62
63impl<'a> Arbitrary<'a> for Position {
64    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
65        let game = Game::arbitrary(input)?;
66        let mut position = game.start();
67        while let Ok(play) = position.main() {
68            position = play.position();
69        }
70        Ok(position.position())
71    }
72}
73
74impl<'a> Arbitrary<'a> for Scharnagl {
75    fn arbitrary(input: &mut Unstructured<'a>) -> Result<Self> {
76        let index: u16 = input.int_in_range(0..=959)?;
77        Ok(Self::new(index).expect("Scharnagl index in range"))
78    }
79}