ide_assists/handlers/
convert_char_literal.rs1use syntax::{AstToken, ast};
2
3use crate::{AssistContext, AssistId, Assists, GroupLabel};
4
5pub(crate) fn convert_char_literal(acc: &mut Assists, ctx: &AssistContext<'_, '_>) -> Option<()> {
16 if !ctx.has_empty_selection() {
17 return None;
18 }
19
20 let literal = ctx.find_node_at_offset::<ast::Literal>()?;
21 let literal = match literal.kind() {
22 ast::LiteralKind::Char(it) => it,
23 _ => return None,
24 };
25
26 let value = literal.value().ok()?;
27 let text = literal.syntax().text().to_owned();
28 let range = literal.syntax().text_range();
29 let group_id = GroupLabel("Convert char representation".into());
30
31 let mut add_assist = |converted: String| {
32 if converted == text {
34 return;
35 }
36 let label = format!("Convert {text} to {converted}");
37 acc.add_group(
38 &group_id,
39 AssistId::refactor_rewrite("convert_char_literal"),
40 label,
41 range,
42 |builder| builder.replace(range, converted),
43 );
44 };
45
46 if value.is_ascii() {
47 add_assist(format!("'\\x{:02x}'", value as u32));
48 }
49
50 add_assist(format!("'\\u{{{:x}}}'", value as u32));
51
52 Some(())
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::tests::check_assist_by_label;
58
59 use super::convert_char_literal;
60
61 #[test]
62 fn ascii_char_to_ascii_and_unicode() {
63 let before = "const _: char = 'a'$0;";
64 check_assist_by_label(
65 convert_char_literal,
66 before,
67 "const _: char = '\\x61';",
68 "Convert 'a' to '\\x61'",
69 );
70 check_assist_by_label(
71 convert_char_literal,
72 before,
73 "const _: char = '\\u{61}';",
74 "Convert 'a' to '\\u{61}'",
75 );
76 }
77
78 #[test]
79 fn non_ascii_char_only_unicode() {
80 check_assist_by_label(
81 convert_char_literal,
82 "const _: char = '😀'$0;",
83 "const _: char = '\\u{1f600}';",
84 "Convert '😀' to '\\u{1f600}'",
85 );
86 }
87
88 #[test]
89 fn ascii_escape_can_convert_to_unicode() {
90 check_assist_by_label(
91 convert_char_literal,
92 "const _: char = '\\x61'$0;",
93 "const _: char = '\\u{61}';",
94 "Convert '\\x61' to '\\u{61}'",
95 );
96 }
97}