1use std::convert::Infallible;
2
3use thiserror::Error;
4
5use crate::{
6 color::{ColorPair, mutation::ColorMutationError},
7 grapheme,
8 mutation::{Mutable, Mutation},
9};
10
11#[derive(Debug, Error)]
12pub enum TileMutationError {
13 #[error("Failed to mutate color")]
14 Color(
15 #[source]
16 #[from]
17 ColorMutationError,
18 ),
19}
20
21impl From<Infallible> for TileMutationError {
22 fn from(error: Infallible) -> Self {
23 match error {}
24 }
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
28pub struct Tile {
29 pub colors: ColorPair,
30 pub grapheme: grapheme::Id,
31}
32
33impl Default for Tile {
34 fn default() -> Self {
35 Self { colors: ColorPair::default(), grapheme: grapheme::Id::from(' ') }
36 }
37}
38
39impl Mutable for Tile {
40 type Error = TileMutationError;
41}
42
43impl Mutable for grapheme::Id {
44 type Error = Infallible;
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
48pub struct MutateColors<M>(pub M);
49
50impl<M> Mutation<Tile> for MutateColors<M>
51where
52 M: Mutation<ColorPair>,
53{
54 fn mutate(
55 self,
56 mut target: Tile,
57 ) -> Result<Tile, <Tile as Mutable>::Error> {
58 let Self(mutation) = self;
59 target.colors = mutation.mutate(target.colors)?;
60 Ok(target)
61 }
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
65pub struct MutateGrapheme<M>(pub M);
66
67impl<M> Mutation<Tile> for MutateGrapheme<M>
68where
69 M: Mutation<grapheme::Id>,
70{
71 fn mutate(
72 self,
73 mut target: Tile,
74 ) -> Result<Tile, <Tile as Mutable>::Error> {
75 let Self(mutation) = self;
76 target.grapheme = mutation.mutate(target.grapheme)?;
77 Ok(target)
78 }
79}