1
1
use std:: {
2
- collections :: HashMap ,
2
+ fmt ,
3
3
hash:: Hash ,
4
4
num:: TryFromIntError ,
5
5
ops:: { Add , AddAssign , IndexMut } ,
@@ -12,11 +12,11 @@ pub type Size = (usize, usize);
12
12
#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
13
13
pub struct Index ( ( usize , usize ) ) ;
14
14
15
- pub fn monadic ( size : Size , index : Index ) -> usize {
15
+ fn monadic ( size : Size , index : Index ) -> usize {
16
16
index. 0 . 0 + index. 0 . 1 * size. 0
17
17
}
18
18
19
- pub fn dyadic ( size : Size , index : usize ) -> Index {
19
+ fn dyadic ( size : Size , index : usize ) -> Index {
20
20
Index ( ( index % size. 0 , index / size. 0 ) )
21
21
}
22
22
@@ -48,7 +48,7 @@ pub struct Grid<T> {
48
48
impl < T > Grid < T > {
49
49
pub fn new ( size : Size , elements : Vec < T > ) -> Grid < T > {
50
50
if size. 0 * size. 1 != elements. len ( ) {
51
- panic ! ( "Misatched size" ) ;
51
+ panic ! ( "Mismatched size" ) ;
52
52
}
53
53
Grid { size, elements }
54
54
}
@@ -79,42 +79,86 @@ impl<T> Grid<T> {
79
79
let rows = self . size . 0 ;
80
80
self . iter_indices ( ) . chunks ( rows)
81
81
}
82
- }
83
82
84
- pub struct GridParser < T > {
85
- mapping : HashMap < char , T > ,
86
- }
83
+ pub fn make_index ( & self , monadic : usize ) -> Index {
84
+ dyadic ( self . size , monadic )
85
+ }
87
86
88
- impl < T : Copy , const N : usize > From < [ ( char , T ) ; N ] > for GridParser < T > {
89
- fn from ( arr : [ ( char , T ) ; N ] ) -> Self {
90
- Self :: new ( arr. into ( ) )
87
+ pub fn display < ' a , O , M > ( & ' a self , overlay : O , mapping : M ) -> GridDisplayer < ' a , M , O , T >
88
+ where
89
+ O : Fn ( Index ) -> Option < char > ,
90
+ M : Fn ( & T ) -> char ,
91
+ {
92
+ GridDisplayer :: new ( mapping, overlay, & self )
91
93
}
92
94
}
93
95
96
+ pub struct GridParser < M > {
97
+ mapping : M ,
98
+ }
99
+
94
100
#[ derive( Debug ) ]
95
101
pub struct GridParseError ;
96
102
97
- impl < T : Copy > GridParser < T > {
98
- pub fn new ( mapping : HashMap < char , T > ) -> Self {
103
+ impl < M : FnMut ( char ) -> Result < T , GridParseError > , T > GridParser < M > {
104
+ pub fn new ( mapping : M ) -> Self {
99
105
Self { mapping }
100
106
}
101
107
102
- pub fn parse ( self , s : & str ) -> Result < Grid < T > , GridParseError > {
108
+ pub fn parse ( mut self , s : & str ) -> Result < Grid < T > , GridParseError > {
103
109
let lines: Vec < _ > = s. lines ( ) . collect ( ) ;
104
110
if lines. is_empty ( ) {
105
111
return Ok ( Grid :: new ( ( 0 , 0 ) , Vec :: new ( ) ) ) ;
106
112
}
107
113
let size = ( lines[ 0 ] . len ( ) , lines. len ( ) ) ;
108
- let things: Option < Vec < _ > > = lines
114
+ let things: Vec < _ > = lines
109
115
. into_iter ( )
110
116
. flat_map ( |v| v. chars ( ) )
111
- . map ( |c| self . mapping . get ( & c) . map ( |t| * t) )
112
- . collect ( ) ;
117
+ . map ( |c| ( self . mapping ) ( c) )
118
+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
119
+
120
+ Ok ( Grid :: new ( size, things) )
121
+ }
122
+ }
123
+
124
+ pub struct GridDisplayer < ' a , M , O , T > {
125
+ mapping : M ,
126
+ overlay : O ,
127
+ grid : & ' a Grid < T > ,
128
+ }
129
+
130
+ impl < ' a , M , O , T > GridDisplayer < ' a , M , O , T >
131
+ where
132
+ M : Fn ( & T ) -> char ,
133
+ O : Fn ( Index ) -> Option < char > ,
134
+ {
135
+ pub fn new ( mapping : M , overlay : O , grid : & ' a Grid < T > ) -> Self {
136
+ Self {
137
+ mapping,
138
+ overlay,
139
+ grid,
140
+ }
141
+ }
142
+ }
113
143
114
- match things {
115
- Some ( things) => Ok ( Grid :: new ( size, things) ) ,
116
- None => Err ( GridParseError ) ,
144
+ impl < ' a , M , O , T > fmt:: Display for GridDisplayer < ' a , M , O , T >
145
+ where
146
+ // I would like to have this a FnMut (as it is Map),
147
+ // but the fmt::Display-interface forbids that
148
+ M : Fn ( & T ) -> char ,
149
+ O : Fn ( Index ) -> Option < char > ,
150
+ {
151
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
152
+ for row in self . grid . iter_indices_by_rows ( ) . into_iter ( ) {
153
+ writeln ! (
154
+ f,
155
+ "{}" ,
156
+ row. into_iter( )
157
+ . map( |i| ( ( self . overlay) ( i) ) . unwrap_or_else( || ( self . mapping) ( & self . grid[ i] ) ) )
158
+ . collect:: <String >( )
159
+ ) ?;
117
160
}
161
+ Ok ( ( ) )
118
162
}
119
163
}
120
164
0 commit comments