1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*!
Parsing pattern files for Conway's Game of Life.

The parsers read a string and return an iterator of coordinates of living cells.

## Supported formats

- [RLE](https://www.conwaylife.com/wiki/Run_Length_Encoded)
- [Plaintext](https://www.conwaylife.com/wiki/Plaintext)
- [apgcode](https://www.conwaylife.com/wiki/Apgcode)
- [Macrocell](https://www.conwaylife.com/wiki/Macrocell)

## Example

### Reading from a string:

```rust
use ca_formats::rle::Rle;

const GLIDER: &str = r"#N Glider
#O Richard K. Guy
#C The smallest, most common, and first discovered spaceship. Diagonal, has period 4 and speed c/4.
#C www.conwaylife.com/wiki/index.php?title=Glider
x = 3, y = 3, rule = B3/S23
bob$2bo$3o!";

let glider = Rle::new(GLIDER).unwrap();
assert_eq!(glider.header_data().unwrap().x, 3);
assert_eq!(glider.header_data().unwrap().y, 3);
assert_eq!(glider.header_data().unwrap().rule, Some(String::from("B3/S23")));

let cells = glider.map(|cell| cell.unwrap().position).collect::<Vec<_>>();
assert_eq!(cells, vec![(1, 0), (2, 1), (0, 2), (1, 2), (2, 2)]);
```

### Reading from a file:

```rust
use std::fs::File;
use ca_formats::rle::Rle;

let file = File::open("tests/sirrobin.rle").unwrap();
let sirrobin = Rle::new_from_file(file).unwrap();

assert_eq!(sirrobin.count(), 282);
```

## See also

- [ca-rules](https://crates.io/crates/ca-rules) - A parser for rule strings.
- [game-of-life-parsers](https://crates.io/crates/game-of-life-parsers)
    by René Perschon - Parsers for [Life 1.05](https://www.conwaylife.com/wiki/Life_1.05)
    and [Life 1.06](https://www.conwaylife.com/wiki/Life_1.06) format.

*/

#![cfg_attr(docs_rs, feature(doc_cfg))]

pub mod apgcode;
mod input;
pub mod macrocell;
pub mod plaintext;
pub mod rle;

pub use input::Input;

pub type Coordinates = (i64, i64);

/// Position and state of a cell.
///
/// Rules with more than 256 states are not supported.
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Default, Hash)]
pub struct CellData {
    /// Coordinates of the cell.
    pub position: Coordinates,
    /// State of the cell.
    ///
    /// For rules with only 2 states, `0` means dead and `1` means alive.
    pub state: u8,
}

/// Convert the coordinates into a [`CellData`] with state `1`.
impl From<Coordinates> for CellData {
    fn from(position: Coordinates) -> Self {
        Self { position, state: 1 }
    }
}