Skip to content

Commit 524b1be

Browse files
committed
another example
1 parent 8e4a6c9 commit 524b1be

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

text/0000-if-let-guard.md

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,55 @@ match ui.wait_event() {
2525

2626
`accept` may in general be lengthy and inconvenient to move into another function, for example if it refers to many locals.
2727

28-
The code is clearer with an `if let` guard as follows.
28+
Here is an (incomplete) example taken from a real codebase, to respond to ANSI CSI escape sequences:
29+
30+
```rust
31+
#[inline]
32+
fn csi_dispatch(&mut self, parms: &[i64], ims: &[u8], ignore: bool, x: char) {
33+
match x {
34+
'C' => if let &[n] = parms { self.screen.move_x( n as _) }
35+
else { log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
36+
parms, ims, ignore, x) },
37+
'D' => if let &[n] = parms { self.screen.move_x(-n as _) }
38+
else { log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
39+
parms, ims, ignore, x) },
40+
'J' => self.screen.erase(match parms {
41+
&[] |
42+
&[0] => Erasure::ScreenFromCursor,
43+
&[1] => Erasure::ScreenToCursor,
44+
&[2] => Erasure::Screen,
45+
_ => { log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
46+
parms, ims, ignore, x); return },
47+
}, false),
48+
'K' => self.screen.erase(match parms {
49+
&[] |
50+
&[0] => Erasure::LineFromCursor,
51+
&[1] => Erasure::LineToCursor,
52+
&[2] => Erasure::Line,
53+
_ => { log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
54+
parms, ims, ignore, x); return },
55+
}, false),
56+
'm' => match parms {
57+
&[] |
58+
&[0] => *self.screen.def_attr_mut() = Attr { fg_code: 0, fg_rgb: [0xFF; 3],
59+
bg_code: 0, bg_rgb: [0x00; 3],
60+
flags: AttrFlags::empty() },
61+
&[n] => if let (3, Some(rgb)) = (n / 10, color_for_code(n % 10, 0xFF)) {
62+
self.screen.def_attr_mut().fg_rgb = rgb;
63+
} else {
64+
log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
65+
parms, ims, ignore, x);
66+
},
67+
_ => log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
68+
parms, ims, ignore, x),
69+
},
70+
_ => log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
71+
parms, ims, ignore, x),
72+
}
73+
}
74+
```
75+
76+
These examples are both clearer with `if let` guards as follows. Particularly in the latter example, in the author's opinion, the control flow is easier to follow.
2977

3078
# Guide-level explanation
3179
[guide-level-explanation]: #guide-level-explanation
@@ -44,6 +92,53 @@ match ui.wait_event() {
4492
}
4593
```
4694

95+
Here is another example, to respond to ANSI CSI escape sequences:
96+
97+
```rust
98+
#[inline]
99+
fn csi_dispatch(&mut self, parms: &[i64], ims: &[u8], ignore: bool, x: char) {
100+
match x {
101+
'C' if let &[n] = parms => self.screen.move_x( n as _),
102+
'D' if let &[n] = parms => self.screen.move_x(-n as _),
103+
_ if let Some(e) = erasure(x, parms) => self.screen.erase(e, false),
104+
'm' => match parms {
105+
&[] |
106+
&[0] => *self.screen.def_attr_mut() = Attr { fg_code: 0, fg_rgb: [0xFF; 3],
107+
bg_code: 0, bg_rgb: [0x00; 3],
108+
flags: AttrFlags::empty() },
109+
&[n] if let (3, Some(rgb)) = (n / 10, color_for_code(n % 10, 0xFF)) =>
110+
self.screen.def_attr_mut().fg_rgb = rgb,
111+
_ => log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
112+
parms, ims, ignore, x),
113+
},
114+
_ => log_debug!("Unknown CSI sequence: {:?}, {:?}, {:?}, {:?}",
115+
parms, ims, ignore, x),
116+
}
117+
}
118+
119+
#[inline]
120+
fn erasure(x: char, parms: &[i64]) -> Option<Erasure> {
121+
match x {
122+
'J' => match parms {
123+
&[] |
124+
&[0] => Some(Erasure::ScreenFromCursor),
125+
&[1] => Some(Erasure::ScreenToCursor),
126+
&[2] => Some(Erasure::Screen),
127+
_ => None,
128+
},
129+
'K' => match parms {
130+
&[] |
131+
&[0] => Some(Erasure::LineFromCursor),
132+
&[1] => Some(Erasure::LineToCursor),
133+
&[2] => Some(Erasure::Line),
134+
_ => None,
135+
},
136+
_ => None,
137+
}
138+
}
139+
```
140+
141+
47142
# Reference-level explanation
48143
[reference-level-explanation]: #reference-level-explanation
49144

0 commit comments

Comments
 (0)