1
- use crate :: parse:: { parse_program_str, BorrowedCommand , OwnedCommand } ;
1
+ use crate :: parse:: { parse_program_str, Command } ;
2
2
use std:: collections:: HashMap ;
3
3
use std:: fmt:: { self , Display } ;
4
4
use std:: io:: { self , prelude:: * , BufReader , Read , Write } ;
63
63
}
64
64
}
65
65
66
- let c = OwnedCommand :: from_line ( & program_line) ;
66
+ let c = Command :: from_line ( & program_line) ;
67
67
if c. is_err ( ) {
68
68
if !program_line. trim ( ) . is_empty ( ) {
69
69
eprintln ! ( "invalid command: \" {}\" " , program_line) ;
@@ -75,20 +75,18 @@ where
75
75
executed. last ( ) . unwrap ( )
76
76
} ;
77
77
78
- // println!("{:?} {:?}", stack, command);
79
-
80
78
// TODO: Deduplicate this code
81
79
match command {
82
- OwnedCommand :: PutThisPancakeOnTop ( adjective) => {
80
+ Command :: PutThisPancakeOnTop ( adjective) => {
83
81
stack. push ( adjective. graphemes ( true ) . count ( ) as u32 ) ;
84
82
}
85
- OwnedCommand :: EatThePancakeOnTop => {
83
+ Command :: EatThePancakeOnTop => {
86
84
if stack. is_empty ( ) {
87
85
return Err ( Error :: OutOfPancakes ) ;
88
86
}
89
87
stack. pop ( ) ;
90
88
}
91
- OwnedCommand :: PutTheTopPancakesTogether => {
89
+ Command :: PutTheTopPancakesTogether => {
92
90
if stack. len ( ) < 2 {
93
91
return Err ( Error :: OutOfPancakes ) ;
94
92
}
@@ -97,29 +95,29 @@ where
97
95
let result = first. checked_add ( second) . ok_or ( Error :: PancakeOverflow ) ?;
98
96
stack. push ( result) ;
99
97
}
100
- OwnedCommand :: GiveMeAPancake => {
98
+ Command :: GiveMeAPancake => {
101
99
input. read_line ( & mut in_line) ?;
102
100
let number_input = in_line
103
101
. parse ( )
104
102
. map_err ( |_| Error :: InvalidPancake ( in_line. clone ( ) ) ) ?;
105
103
stack. push ( number_input) ;
106
104
in_line. clear ( ) ;
107
105
}
108
- OwnedCommand :: HowAboutAHotcake => {
106
+ Command :: HowAboutAHotcake => {
109
107
let buf = input. fill_buf ( ) ?;
110
- let number_input = * buf. get ( 0 ) . unwrap_or ( & 0 ) ;
108
+ let number_input = * buf. first ( ) . unwrap_or ( & 0 ) ;
111
109
input. consume ( 1 ) ;
112
110
stack. push ( u32:: from ( number_input) ) ;
113
111
}
114
- OwnedCommand :: ShowMeAPancake => {
112
+ Command :: ShowMeAPancake => {
115
113
if stack. is_empty ( ) {
116
114
return Err ( Error :: OutOfPancakes ) ;
117
115
}
118
116
let top = stack. last ( ) . unwrap ( ) ;
119
117
let c = char:: from_u32 ( * top) . ok_or ( Error :: CanNotShowPancake ( * top) ) ?;
120
118
write ! ( output, "{}" , c) ?;
121
119
}
122
- OwnedCommand :: TakeFromTheTopPancakes => {
120
+ Command :: TakeFromTheTopPancakes => {
123
121
if stack. len ( ) < 2 {
124
122
return Err ( Error :: OutOfPancakes ) ;
125
123
}
@@ -128,7 +126,7 @@ where
128
126
let result = first. checked_sub ( second) . ok_or ( Error :: PancakeUnderflow ) ?;
129
127
stack. push ( result) ;
130
128
}
131
- OwnedCommand :: FlipThePancakesOnTop => {
129
+ Command :: FlipThePancakesOnTop => {
132
130
if stack. len ( ) < 2 {
133
131
return Err ( Error :: OutOfPancakes ) ;
134
132
}
@@ -137,68 +135,68 @@ where
137
135
stack. push ( first) ;
138
136
stack. push ( second) ;
139
137
}
140
- OwnedCommand :: PutAnotherPancakeOnTop => {
138
+ Command :: PutAnotherPancakeOnTop => {
141
139
if stack. is_empty ( ) {
142
140
return Err ( Error :: OutOfPancakes ) ;
143
141
}
144
142
stack. push ( * stack. last ( ) . unwrap ( ) ) ;
145
143
}
146
- OwnedCommand :: Label ( label) => {
144
+ Command :: Label ( label) => {
147
145
if stack. is_empty ( ) {
148
146
return Err ( Error :: OutOfPancakes ) ;
149
147
}
150
148
let top = stack. last ( ) . unwrap ( ) ;
151
149
labels. insert ( label. clone ( ) , ( * top - 1 ) as usize ) ;
152
150
}
153
- OwnedCommand :: IfThePancakeIsntTastyGoOverTo ( target_label) => {
151
+ Command :: IfThePancakeIsntTastyGoOverTo ( target_label) => {
154
152
if stack. is_empty ( ) {
155
153
return Err ( Error :: OutOfPancakes ) ;
156
154
}
157
155
let top = * stack. last ( ) . unwrap ( ) ;
158
156
if top == 0 {
159
157
let label_position = labels
160
158
. get ( target_label)
161
- . ok_or_else ( || Error :: UndefinedLabel ( target_label. clone ( ) ) ) ?;
159
+ . ok_or_else ( || Error :: UndefinedLabel ( target_label. to_string ( ) ) ) ?;
162
160
current_statement = Some ( * label_position) ;
163
161
}
164
162
}
165
- OwnedCommand :: IfThePancakeIsTastyGoOverTo ( target_label) => {
163
+ Command :: IfThePancakeIsTastyGoOverTo ( target_label) => {
166
164
if stack. is_empty ( ) {
167
165
return Err ( Error :: OutOfPancakes ) ;
168
166
}
169
167
let top = * stack. last ( ) . unwrap ( ) ;
170
168
if top != 0 {
171
169
let label_position = labels
172
170
. get ( target_label)
173
- . ok_or_else ( || Error :: UndefinedLabel ( target_label. clone ( ) ) ) ?;
171
+ . ok_or_else ( || Error :: UndefinedLabel ( target_label. to_string ( ) ) ) ?;
174
172
current_statement = Some ( * label_position) ;
175
173
}
176
174
}
177
- OwnedCommand :: PutSyrupOnThePancakes => {
175
+ Command :: PutSyrupOnThePancakes => {
178
176
for value in & mut stack {
179
177
* value = value. checked_add ( 1 ) . ok_or ( Error :: PancakeOverflow ) ?;
180
178
}
181
179
}
182
- OwnedCommand :: PutButterOnThePancakes => {
180
+ Command :: PutButterOnThePancakes => {
183
181
if stack. is_empty ( ) {
184
182
return Err ( Error :: OutOfPancakes ) ;
185
183
}
186
184
let top = stack. last_mut ( ) . unwrap ( ) ;
187
185
* top = top. checked_add ( 1 ) . ok_or ( Error :: PancakeOverflow ) ?;
188
186
}
189
- OwnedCommand :: TakeOffTheSyrup => {
187
+ Command :: TakeOffTheSyrup => {
190
188
for value in & mut stack {
191
189
* value = value. checked_sub ( 1 ) . ok_or ( Error :: PancakeUnderflow ) ?;
192
190
}
193
191
}
194
- OwnedCommand :: TakeOffTheButter => {
192
+ Command :: TakeOffTheButter => {
195
193
if stack. is_empty ( ) {
196
194
return Err ( Error :: OutOfPancakes ) ;
197
195
}
198
196
let top = stack. last_mut ( ) . unwrap ( ) ;
199
197
* top = top. checked_sub ( 1 ) . ok_or ( Error :: PancakeUnderflow ) ?;
200
198
}
201
- OwnedCommand :: EatAllOfThePancakes => {
199
+ Command :: EatAllOfThePancakes => {
202
200
break ;
203
201
}
204
202
}
@@ -256,11 +254,7 @@ where
256
254
///
257
255
/// # Errors
258
256
/// Will return `Err` if the given program performs an illegal operation or an io error occurs. See [`Error`](./enum.Error.html).
259
- pub fn run_program < I , O > (
260
- program : & [ BorrowedCommand < ' _ > ] ,
261
- input : I ,
262
- mut output : O ,
263
- ) -> Result < ( ) , Error >
257
+ pub fn run_program < I , O > ( program : & [ Command < ' _ > ] , input : I , mut output : O ) -> Result < ( ) , Error >
264
258
where
265
259
I : Read ,
266
260
O : Write ,
@@ -275,20 +269,18 @@ where
275
269
while let Some ( command) = program. get ( current_statement) {
276
270
current_statement += 1 ;
277
271
278
- // println!("{:?} {:?}", stack, command);
279
-
280
272
// TODO: Deduplicate this code
281
273
match command {
282
- BorrowedCommand :: PutThisPancakeOnTop ( adjective) => {
274
+ Command :: PutThisPancakeOnTop ( adjective) => {
283
275
stack. push ( adjective. graphemes ( true ) . count ( ) as u32 ) ;
284
276
}
285
- BorrowedCommand :: EatThePancakeOnTop => {
277
+ Command :: EatThePancakeOnTop => {
286
278
if stack. is_empty ( ) {
287
279
return Err ( Error :: OutOfPancakes ) ;
288
280
}
289
281
stack. pop ( ) ;
290
282
}
291
- BorrowedCommand :: PutTheTopPancakesTogether => {
283
+ Command :: PutTheTopPancakesTogether => {
292
284
if stack. len ( ) < 2 {
293
285
return Err ( Error :: OutOfPancakes ) ;
294
286
}
@@ -297,29 +289,29 @@ where
297
289
let result = first. checked_add ( second) . ok_or ( Error :: PancakeOverflow ) ?;
298
290
stack. push ( result) ;
299
291
}
300
- BorrowedCommand :: GiveMeAPancake => {
292
+ Command :: GiveMeAPancake => {
301
293
input. read_line ( & mut in_line) ?;
302
294
let number_input = in_line
303
295
. parse ( )
304
296
. map_err ( |_| Error :: InvalidPancake ( in_line. clone ( ) ) ) ?;
305
297
stack. push ( number_input) ;
306
298
in_line. clear ( ) ;
307
299
}
308
- BorrowedCommand :: HowAboutAHotcake => {
300
+ Command :: HowAboutAHotcake => {
309
301
let buf = input. fill_buf ( ) ?;
310
- let number_input = * buf. get ( 0 ) . unwrap_or ( & 0 ) ;
302
+ let number_input = * buf. first ( ) . unwrap_or ( & 0 ) ;
311
303
input. consume ( 1 ) ;
312
304
stack. push ( u32:: from ( number_input) ) ;
313
305
}
314
- BorrowedCommand :: ShowMeAPancake => {
306
+ Command :: ShowMeAPancake => {
315
307
if stack. is_empty ( ) {
316
308
return Err ( Error :: OutOfPancakes ) ;
317
309
}
318
310
let top = stack. last ( ) . unwrap ( ) ;
319
311
let c = char:: from_u32 ( * top) . ok_or ( Error :: CanNotShowPancake ( * top) ) ?;
320
312
write ! ( output, "{}" , c) ?;
321
313
}
322
- BorrowedCommand :: TakeFromTheTopPancakes => {
314
+ Command :: TakeFromTheTopPancakes => {
323
315
if stack. len ( ) < 2 {
324
316
return Err ( Error :: OutOfPancakes ) ;
325
317
}
@@ -328,7 +320,7 @@ where
328
320
let result = first. checked_sub ( second) . ok_or ( Error :: PancakeUnderflow ) ?;
329
321
stack. push ( result) ;
330
322
}
331
- BorrowedCommand :: FlipThePancakesOnTop => {
323
+ Command :: FlipThePancakesOnTop => {
332
324
if stack. len ( ) < 2 {
333
325
return Err ( Error :: OutOfPancakes ) ;
334
326
}
@@ -337,20 +329,20 @@ where
337
329
stack. push ( first) ;
338
330
stack. push ( second) ;
339
331
}
340
- BorrowedCommand :: PutAnotherPancakeOnTop => {
332
+ Command :: PutAnotherPancakeOnTop => {
341
333
if stack. is_empty ( ) {
342
334
return Err ( Error :: OutOfPancakes ) ;
343
335
}
344
336
stack. push ( * stack. last ( ) . unwrap ( ) ) ;
345
337
}
346
- BorrowedCommand :: Label ( label) => {
338
+ Command :: Label ( label) => {
347
339
if stack. is_empty ( ) {
348
340
return Err ( Error :: OutOfPancakes ) ;
349
341
}
350
342
let top = stack. last ( ) . unwrap ( ) ;
351
- labels. insert ( * label, ( * top - 1 ) as usize ) ;
343
+ labels. insert ( label, ( * top - 1 ) as usize ) ;
352
344
}
353
- BorrowedCommand :: IfThePancakeIsntTastyGoOverTo ( target_label) => {
345
+ Command :: IfThePancakeIsntTastyGoOverTo ( target_label) => {
354
346
if stack. is_empty ( ) {
355
347
return Err ( Error :: OutOfPancakes ) ;
356
348
}
@@ -362,7 +354,7 @@ where
362
354
current_statement = * label_position;
363
355
}
364
356
}
365
- BorrowedCommand :: IfThePancakeIsTastyGoOverTo ( target_label) => {
357
+ Command :: IfThePancakeIsTastyGoOverTo ( target_label) => {
366
358
if stack. is_empty ( ) {
367
359
return Err ( Error :: OutOfPancakes ) ;
368
360
}
@@ -374,31 +366,31 @@ where
374
366
current_statement = * label_position;
375
367
}
376
368
}
377
- BorrowedCommand :: PutSyrupOnThePancakes => {
369
+ Command :: PutSyrupOnThePancakes => {
378
370
for value in & mut stack {
379
371
* value = value. checked_add ( 1 ) . ok_or ( Error :: PancakeOverflow ) ?;
380
372
}
381
373
}
382
- BorrowedCommand :: PutButterOnThePancakes => {
374
+ Command :: PutButterOnThePancakes => {
383
375
if stack. is_empty ( ) {
384
376
return Err ( Error :: OutOfPancakes ) ;
385
377
}
386
378
let top = stack. last_mut ( ) . unwrap ( ) ;
387
379
* top = top. checked_add ( 1 ) . ok_or ( Error :: PancakeOverflow ) ?;
388
380
}
389
- BorrowedCommand :: TakeOffTheSyrup => {
381
+ Command :: TakeOffTheSyrup => {
390
382
for value in & mut stack {
391
383
* value = value. checked_sub ( 1 ) . ok_or ( Error :: PancakeUnderflow ) ?;
392
384
}
393
385
}
394
- BorrowedCommand :: TakeOffTheButter => {
386
+ Command :: TakeOffTheButter => {
395
387
if stack. is_empty ( ) {
396
388
return Err ( Error :: OutOfPancakes ) ;
397
389
}
398
390
let top = stack. last_mut ( ) . unwrap ( ) ;
399
391
* top = top. checked_sub ( 1 ) . ok_or ( Error :: PancakeUnderflow ) ?;
400
392
}
401
- BorrowedCommand :: EatAllOfThePancakes => {
393
+ Command :: EatAllOfThePancakes => {
402
394
break ;
403
395
}
404
396
}
0 commit comments