Single Rust
In the name of building unnecessary things with Rust, here you have Single Rust. Why press Shift every time you write a string? Type 'hello' and Single Rust turns it into the "hello" Rust wants. And yes, the engine doing the swapping is written in Rust too.
Rust only uses single quotes for single characters, so on its own 'hello' won't compile. Single Rust rewrites those strings with double quotes, and leaves real character literals, lifetimes and loop labels alone. If you're coming from JavaScript or Python, your fingers already type single quotes anyway.
// Before
let greeting = 'hello world';
let quote = 'she said "it\'s fine"';
println!('{} {}', greeting, quote);
// After
let greeting = "hello world";
let quote = "she said \"it's fine\"";
println!("{} {}", greeting, quote);
Usage
There's nothing to set up. Write your strings with single quotes:
- Quotes come in pairs: typing
' inserts the closing ' too, the way " does. Where a lifetime is likely, such as after < or & (<'a>, &'a str), you get a single quote instead.
- As you type: a string converts as soon as you type the character after its closing quote, such as
;, ,, ), a space or Enter. A letter right after the quote leaves it alone, so 'it's here' stays one string.
- When you save: anything left over, such as pasted code, converts when the file is saved, auto saves included. Cargo only builds saved files, so it never sees a single-quoted string.
Single Rust works alongside your formatter, so rustfmt (through rust-analyzer) keeps formatting your code as before. To keep single quotes on a string that was just converted, press undo (⌘Z or Ctrl+Z).
To convert a file or selection by hand, open the Command Palette (⇧⌘P on macOS, Ctrl+Shift+P elsewhere) and run Single Rust: Convert Single-Quoted Strings. If you have text selected, only the strings in the selection change.
Settings
| Setting |
Default |
What it does |
single-rust.autoCloseQuotes |
true |
Insert a closing ' when you type one. |
single-rust.convertOnType |
true |
Convert strings as you type. |
single-rust.convertOnSave |
true |
Convert anything left over when you save. |
Turn both off to convert only with the command.
What it changes
| Before |
After |
'hello' |
"hello" |
'it\'s', 'it's here' |
"it's", "it's here" |
'say "hi"' |
"say \"hi\"" |
'' |
"" |
b'bytes' |
b"bytes" |
r'\d+' |
r"\d+" |
'\d+' |
"\\d+" |
Escapes Rust doesn't support, like \d, keep their backslash as a literal one (as in Python), so the result compiles.
What it leaves alone
- Character literals:
'a', '\n', '\'', '\u{1F600}'
- Lifetimes and labels:
'a, 'static, <'de>, 'outer: loop
- Double-quoted strings, raw strings and comments
Code that already compiles is left as it is. When a quote could start either a lifetime or a string, Single Rust reads the rest of the line both ways and only converts it if the lifetime reading can't be right. A few unclear cases are left for you to fix:
- A string whose first word is followed by
//, like 'see // here'
- A string that runs onto a second line
- A quote at the start of a word inside a string, like
'rock 'n' roll'
- A string containing a single
", like 'Say "hi', can stop strings after it from being converted
Privacy
Everything runs locally in a small WebAssembly module. Single Rust makes no network requests and collects no telemetry.
Requirements
VS Code 1.85 or later. Nothing else to install.