Skip to content

Commit b0c52c5

Browse files
committed
Auto merge of #38909 - clarcharr:char_struct_display, r=alexcrichton
Implement Display for char Escape*, To*case. See: rust-lang/rfcs#1848. A good example of where this is useful would be in the example `print!("{}", 'ß'.to_uppercase())`. Not sure if this requires a formal RFC, but I decided to write the code for it anyway regardless.
2 parents 927c55d + 3a79f2e commit b0c52c5

File tree

3 files changed

+277
-175
lines changed

3 files changed

+277
-175
lines changed

src/libcore/char.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
use char_private::is_printable;
1919
use convert::TryFrom;
20-
use fmt;
20+
use fmt::{self, Write};
2121
use slice;
2222
use iter::FusedIterator;
2323
use mem::transmute;
@@ -588,6 +588,16 @@ impl ExactSizeIterator for EscapeUnicode {
588588
#[unstable(feature = "fused", issue = "35602")]
589589
impl FusedIterator for EscapeUnicode {}
590590

591+
#[stable(feature = "char_struct_display", since = "1.17.0")]
592+
impl fmt::Display for EscapeUnicode {
593+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
594+
for c in self.clone() {
595+
f.write_char(c)?;
596+
}
597+
Ok(())
598+
}
599+
}
600+
591601
/// An iterator that yields the literal escape code of a `char`.
592602
///
593603
/// This `struct` is created by the [`escape_default()`] method on [`char`]. See
@@ -691,6 +701,16 @@ impl ExactSizeIterator for EscapeDefault {
691701
#[unstable(feature = "fused", issue = "35602")]
692702
impl FusedIterator for EscapeDefault {}
693703

704+
#[stable(feature = "char_struct_display", since = "1.17.0")]
705+
impl fmt::Display for EscapeDefault {
706+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
707+
for c in self.clone() {
708+
f.write_char(c)?;
709+
}
710+
Ok(())
711+
}
712+
}
713+
694714
/// An iterator that yields the literal escape code of a `char`.
695715
///
696716
/// This `struct` is created by the [`escape_debug()`] method on [`char`]. See its
@@ -715,6 +735,13 @@ impl ExactSizeIterator for EscapeDebug { }
715735
#[unstable(feature = "fused", issue = "35602")]
716736
impl FusedIterator for EscapeDebug {}
717737

738+
#[stable(feature = "char_struct_display", since = "1.17.0")]
739+
impl fmt::Display for EscapeDebug {
740+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
741+
fmt::Display::fmt(&self.0, f)
742+
}
743+
}
744+
718745

719746

720747
/// An iterator over an iterator of bytes of the characters the bytes represent

src/libcoretest/char.rs

+99-125
Original file line numberDiff line numberDiff line change
@@ -75,47 +75,53 @@ fn test_to_digit() {
7575

7676
#[test]
7777
fn test_to_lowercase() {
78-
fn lower(c: char) -> Vec<char> {
79-
c.to_lowercase().collect()
78+
fn lower(c: char) -> String {
79+
let iter: String = c.to_lowercase().collect();
80+
let disp: String = c.to_lowercase().to_string();
81+
assert_eq!(iter, disp);
82+
iter
8083
}
81-
assert_eq!(lower('A'), ['a']);
82-
assert_eq!(lower('Ö'), ['ö']);
83-
assert_eq!(lower('ß'), ['ß']);
84-
assert_eq!(lower('Ü'), ['ü']);
85-
assert_eq!(lower('💩'), ['💩']);
86-
assert_eq!(lower('Σ'), ['σ']);
87-
assert_eq!(lower('Τ'), ['τ']);
88-
assert_eq!(lower('Ι'), ['ι']);
89-
assert_eq!(lower('Γ'), ['γ']);
90-
assert_eq!(lower('Μ'), ['μ']);
91-
assert_eq!(lower('Α'), ['α']);
92-
assert_eq!(lower('Σ'), ['σ']);
93-
assert_eq!(lower('Dž'), ['dž']);
94-
assert_eq!(lower('fi'), ['fi']);
95-
assert_eq!(lower('İ'), ['i', '\u{307}']);
84+
assert_eq!(lower('A'), "a");
85+
assert_eq!(lower('Ö'), "ö");
86+
assert_eq!(lower('ß'), "ß");
87+
assert_eq!(lower('Ü'), "ü");
88+
assert_eq!(lower('💩'), "💩");
89+
assert_eq!(lower('Σ'), "σ");
90+
assert_eq!(lower('Τ'), "τ");
91+
assert_eq!(lower('Ι'), "ι");
92+
assert_eq!(lower('Γ'), "γ");
93+
assert_eq!(lower('Μ'), "μ");
94+
assert_eq!(lower('Α'), "α");
95+
assert_eq!(lower('Σ'), "σ");
96+
assert_eq!(lower('Dž'), "dž");
97+
assert_eq!(lower('fi'), "fi");
98+
assert_eq!(lower('İ'), "i\u{307}");
9699
}
97100

98101
#[test]
99102
fn test_to_uppercase() {
100-
fn upper(c: char) -> Vec<char> {
101-
c.to_uppercase().collect()
103+
fn upper(c: char) -> String {
104+
let iter: String = c.to_uppercase().collect();
105+
let disp: String = c.to_uppercase().to_string();
106+
assert_eq!(iter, disp);
107+
iter
102108
}
103-
assert_eq!(upper('a'), ['A']);
104-
assert_eq!(upper('ö'), ['Ö']);
105-
assert_eq!(upper('ß'), ['S', 'S']); // not ẞ: Latin capital letter sharp s
106-
assert_eq!(upper('ü'), ['Ü']);
107-
assert_eq!(upper('💩'), ['💩']);
108-
109-
assert_eq!(upper('σ'), ['Σ']);
110-
assert_eq!(upper('τ'), ['Τ']);
111-
assert_eq!(upper('ι'), ['Ι']);
112-
assert_eq!(upper('γ'), ['Γ']);
113-
assert_eq!(upper('μ'), ['Μ']);
114-
assert_eq!(upper('α'), ['Α']);
115-
assert_eq!(upper('ς'), ['Σ']);
116-
assert_eq!(upper('Dž'), ['DŽ']);
117-
assert_eq!(upper('fi'), ['F', 'I']);
118-
assert_eq!(upper('ᾀ'), ['Ἀ', 'Ι']);
109+
assert_eq!(upper('a'), "A");
110+
assert_eq!(upper('ö'), "Ö");
111+
assert_eq!(upper('ß'), "SS"); // not ẞ: Latin capital letter sharp s
112+
assert_eq!(upper('ü'), "Ü");
113+
assert_eq!(upper('💩'), "💩");
114+
115+
assert_eq!(upper('σ'), "Σ");
116+
assert_eq!(upper('τ'), "Τ");
117+
assert_eq!(upper('ι'), "Ι");
118+
assert_eq!(upper('γ'), "Γ");
119+
assert_eq!(upper('μ'), "Μ");
120+
assert_eq!(upper('α'), "Α");
121+
assert_eq!(upper('ς'), "Σ");
122+
assert_eq!(upper('Dž'), "DŽ");
123+
assert_eq!(upper('fi'), "FI");
124+
assert_eq!(upper('ᾀ'), "ἈΙ");
119125
}
120126

121127
#[test]
@@ -144,107 +150,75 @@ fn test_is_digit() {
144150
#[test]
145151
fn test_escape_debug() {
146152
fn string(c: char) -> String {
147-
c.escape_debug().collect()
153+
let iter: String = c.escape_debug().collect();
154+
let disp: String = c.escape_debug().to_string();
155+
assert_eq!(iter, disp);
156+
iter
148157
}
149-
let s = string('\n');
150-
assert_eq!(s, "\\n");
151-
let s = string('\r');
152-
assert_eq!(s, "\\r");
153-
let s = string('\'');
154-
assert_eq!(s, "\\'");
155-
let s = string('"');
156-
assert_eq!(s, "\\\"");
157-
let s = string(' ');
158-
assert_eq!(s, " ");
159-
let s = string('a');
160-
assert_eq!(s, "a");
161-
let s = string('~');
162-
assert_eq!(s, "~");
163-
let s = string('é');
164-
assert_eq!(s, "é");
165-
let s = string('文');
166-
assert_eq!(s, "文");
167-
let s = string('\x00');
168-
assert_eq!(s, "\\u{0}");
169-
let s = string('\x1f');
170-
assert_eq!(s, "\\u{1f}");
171-
let s = string('\x7f');
172-
assert_eq!(s, "\\u{7f}");
173-
let s = string('\u{80}');
174-
assert_eq!(s, "\\u{80}");
175-
let s = string('\u{ff}');
176-
assert_eq!(s, "\u{ff}");
177-
let s = string('\u{11b}');
178-
assert_eq!(s, "\u{11b}");
179-
let s = string('\u{1d4b6}');
180-
assert_eq!(s, "\u{1d4b6}");
181-
let s = string('\u{200b}'); // zero width space
182-
assert_eq!(s, "\\u{200b}");
183-
let s = string('\u{e000}'); // private use 1
184-
assert_eq!(s, "\\u{e000}");
185-
let s = string('\u{100000}'); // private use 2
186-
assert_eq!(s, "\\u{100000}");
158+
assert_eq!(string('\n'), "\\n");
159+
assert_eq!(string('\r'), "\\r");
160+
assert_eq!(string('\''), "\\'");
161+
assert_eq!(string('"'), "\\\"");
162+
assert_eq!(string(' '), " ");
163+
assert_eq!(string('a'), "a");
164+
assert_eq!(string('~'), "~");
165+
assert_eq!(string('é'), "é");
166+
assert_eq!(string('文'), "文");
167+
assert_eq!(string('\x00'), "\\u{0}");
168+
assert_eq!(string('\x1f'), "\\u{1f}");
169+
assert_eq!(string('\x7f'), "\\u{7f}");
170+
assert_eq!(string('\u{80}'), "\\u{80}");
171+
assert_eq!(string('\u{ff}'), "\u{ff}");
172+
assert_eq!(string('\u{11b}'), "\u{11b}");
173+
assert_eq!(string('\u{1d4b6}'), "\u{1d4b6}");
174+
assert_eq!(string('\u{200b}'),"\\u{200b}"); // zero width space
175+
assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
176+
assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
187177
}
188178

189179
#[test]
190180
fn test_escape_default() {
191181
fn string(c: char) -> String {
192-
c.escape_default().collect()
182+
let iter: String = c.escape_default().collect();
183+
let disp: String = c.escape_default().to_string();
184+
assert_eq!(iter, disp);
185+
iter
193186
}
194-
let s = string('\n');
195-
assert_eq!(s, "\\n");
196-
let s = string('\r');
197-
assert_eq!(s, "\\r");
198-
let s = string('\'');
199-
assert_eq!(s, "\\'");
200-
let s = string('"');
201-
assert_eq!(s, "\\\"");
202-
let s = string(' ');
203-
assert_eq!(s, " ");
204-
let s = string('a');
205-
assert_eq!(s, "a");
206-
let s = string('~');
207-
assert_eq!(s, "~");
208-
let s = string('é');
209-
assert_eq!(s, "\\u{e9}");
210-
let s = string('\x00');
211-
assert_eq!(s, "\\u{0}");
212-
let s = string('\x1f');
213-
assert_eq!(s, "\\u{1f}");
214-
let s = string('\x7f');
215-
assert_eq!(s, "\\u{7f}");
216-
let s = string('\u{80}');
217-
assert_eq!(s, "\\u{80}");
218-
let s = string('\u{ff}');
219-
assert_eq!(s, "\\u{ff}");
220-
let s = string('\u{11b}');
221-
assert_eq!(s, "\\u{11b}");
222-
let s = string('\u{1d4b6}');
223-
assert_eq!(s, "\\u{1d4b6}");
224-
let s = string('\u{200b}'); // zero width space
225-
assert_eq!(s, "\\u{200b}");
226-
let s = string('\u{e000}'); // private use 1
227-
assert_eq!(s, "\\u{e000}");
228-
let s = string('\u{100000}'); // private use 2
229-
assert_eq!(s, "\\u{100000}");
187+
assert_eq!(string('\n'), "\\n");
188+
assert_eq!(string('\r'), "\\r");
189+
assert_eq!(string('\''), "\\'");
190+
assert_eq!(string('"'), "\\\"");
191+
assert_eq!(string(' '), " ");
192+
assert_eq!(string('a'), "a");
193+
assert_eq!(string('~'), "~");
194+
assert_eq!(string('é'), "\\u{e9}");
195+
assert_eq!(string('\x00'), "\\u{0}");
196+
assert_eq!(string('\x1f'), "\\u{1f}");
197+
assert_eq!(string('\x7f'), "\\u{7f}");
198+
assert_eq!(string('\u{80}'), "\\u{80}");
199+
assert_eq!(string('\u{ff}'), "\\u{ff}");
200+
assert_eq!(string('\u{11b}'), "\\u{11b}");
201+
assert_eq!(string('\u{1d4b6}'), "\\u{1d4b6}");
202+
assert_eq!(string('\u{200b}'), "\\u{200b}"); // zero width space
203+
assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
204+
assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
230205
}
231206

232207
#[test]
233208
fn test_escape_unicode() {
234-
fn string(c: char) -> String { c.escape_unicode().collect() }
235-
236-
let s = string('\x00');
237-
assert_eq!(s, "\\u{0}");
238-
let s = string('\n');
239-
assert_eq!(s, "\\u{a}");
240-
let s = string(' ');
241-
assert_eq!(s, "\\u{20}");
242-
let s = string('a');
243-
assert_eq!(s, "\\u{61}");
244-
let s = string('\u{11b}');
245-
assert_eq!(s, "\\u{11b}");
246-
let s = string('\u{1d4b6}');
247-
assert_eq!(s, "\\u{1d4b6}");
209+
fn string(c: char) -> String {
210+
let iter: String = c.escape_unicode().collect();
211+
let disp: String = c.escape_unicode().to_string();
212+
assert_eq!(iter, disp);
213+
iter
214+
}
215+
216+
assert_eq!(string('\x00'), "\\u{0}");
217+
assert_eq!(string('\n'), "\\u{a}");
218+
assert_eq!(string(' '), "\\u{20}");
219+
assert_eq!(string('a'), "\\u{61}");
220+
assert_eq!(string('\u{11b}'), "\\u{11b}");
221+
assert_eq!(string('\u{1d4b6}'), "\\u{1d4b6}");
248222
}
249223

250224
#[test]

0 commit comments

Comments
 (0)