11use std:: {
2- collections :: HashMap ,
2+ fmt ,
33 hash:: Hash ,
44 num:: TryFromIntError ,
55 ops:: { Add , AddAssign , IndexMut } ,
@@ -12,11 +12,11 @@ pub type Size = (usize, usize);
1212#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
1313pub struct Index ( ( usize , usize ) ) ;
1414
15- pub fn monadic ( size : Size , index : Index ) -> usize {
15+ fn monadic ( size : Size , index : Index ) -> usize {
1616 index. 0 . 0 + index. 0 . 1 * size. 0
1717}
1818
19- pub fn dyadic ( size : Size , index : usize ) -> Index {
19+ fn dyadic ( size : Size , index : usize ) -> Index {
2020 Index ( ( index % size. 0 , index / size. 0 ) )
2121}
2222
@@ -48,7 +48,7 @@ pub struct Grid<T> {
4848impl < T > Grid < T > {
4949 pub fn new ( size : Size , elements : Vec < T > ) -> Grid < T > {
5050 if size. 0 * size. 1 != elements. len ( ) {
51- panic ! ( "Misatched size" ) ;
51+ panic ! ( "Mismatched size" ) ;
5252 }
5353 Grid { size, elements }
5454 }
@@ -79,42 +79,86 @@ impl<T> Grid<T> {
7979 let rows = self . size . 0 ;
8080 self . iter_indices ( ) . chunks ( rows)
8181 }
82- }
8382
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+ }
8786
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 )
9193 }
9294}
9395
96+ pub struct GridParser < M > {
97+ mapping : M ,
98+ }
99+
94100#[ derive( Debug ) ]
95101pub struct GridParseError ;
96102
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 {
99105 Self { mapping }
100106 }
101107
102- pub fn parse ( self , s : & str ) -> Result < Grid < T > , GridParseError > {
108+ pub fn parse ( mut self , s : & str ) -> Result < Grid < T > , GridParseError > {
103109 let lines: Vec < _ > = s. lines ( ) . collect ( ) ;
104110 if lines. is_empty ( ) {
105111 return Ok ( Grid :: new ( ( 0 , 0 ) , Vec :: new ( ) ) ) ;
106112 }
107113 let size = ( lines[ 0 ] . len ( ) , lines. len ( ) ) ;
108- let things: Option < Vec < _ > > = lines
114+ let things: Vec < _ > = lines
109115 . into_iter ( )
110116 . 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+ }
113143
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+ ) ?;
117160 }
161+ Ok ( ( ) )
118162 }
119163}
120164
0 commit comments