Skip to content

Instantly share code, notes, and snippets.

@simonsan
Forked from ayazhafiz/compress.rs
Created February 16, 2024 06:18
Show Gist options
  • Save simonsan/b5e7ebbe34eb3978eb3ffb22e1d5857d to your computer and use it in GitHub Desktop.
Save simonsan/b5e7ebbe34eb3978eb3ffb22e1d5857d to your computer and use it in GitHub Desktop.
Emits an identical rust program with comments removed and whitespace minimized.
use rustc_lexer::{tokenize, Token, TokenKind};
use std::io::{self, Read};
enum Cmd {
Print(usize),
Space,
Skip(usize),
}
fn layout(toks: impl Iterator<Item = Token>) -> impl Iterator<Item = Cmd> {
use Cmd::*;
use TokenKind::*;
let mut last_ident_like = false;
toks.flat_map(move |Token { kind, len }| {
let mut simple = match kind {
Whitespace | LineComment { .. } | BlockComment { .. } => vec![],
Ident | RawIdent | Literal { .. } | Lifetime { .. } if last_ident_like => {
vec![Space, Print(len)]
}
Ident | RawIdent | Literal { .. } | Lifetime { .. } => {
last_ident_like = true;
vec![Print(len)]
}
_ => {
last_ident_like = false;
vec![Print(len)]
}
};
simple.push(Skip(len));
simple.into_iter()
})
}
fn emit(toks: impl Iterator<Item = Cmd>, orig: &str) -> String {
use Cmd::*;
let mut out = String::with_capacity(orig.len());
let mut i = 0;
for tok in toks {
match tok {
Print(len) => out.push_str(&orig[i..i + len]),
Space => out.push(' '),
Skip(len) => i += len,
}
}
out
}
fn main() -> io::Result<()> {
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer)?;
let toks = tokenize(&buffer);
let cmds = layout(toks);
let out = emit(cmds, &buffer);
print!("{}", out);
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment