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}