10998: Add number representation assists r=Veykril a=errx

Reimplemented assists from this PR https://github.com/rust-analyzer/rust-analyzer/pull/3683 with current APIs.
![image](https://user-images.githubusercontent.com/462486/145726792-47700215-26f2-4fdc-9520-63d1487901e5.png)
![image](https://user-images.githubusercontent.com/462486/145726802-f528a2f7-9159-41d3-b459-fc3fae033e60.png)


I've decided not to add options about size of the groups so behaviour is similar to clippy's. 
Minimal number length is also taken from clippy.


Co-authored-by: Oleg Matrokhin <matrokhin@gmail.com>
This commit is contained in:
bors[bot] 2021-12-13 18:49:06 +00:00 committed by GitHub
commit 791722b70a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 224 additions and 29 deletions

View file

@ -623,41 +623,38 @@ impl ast::IntNumber {
}
}
pub fn value(&self) -> Option<u128> {
let token = self.syntax();
let mut text = token.text();
if let Some(suffix) = self.suffix() {
text = &text[..text.len() - suffix.len()];
}
pub fn split_into_parts(&self) -> (&str, &str, &str) {
let radix = self.radix();
text = &text[radix.prefix_len()..];
let (prefix, mut text) = self.text().split_at(radix.prefix_len());
let buf;
if text.contains('_') {
buf = text.replace('_', "");
text = buf.as_str();
};
let value = u128::from_str_radix(text, radix as u32).ok()?;
Some(value)
}
pub fn suffix(&self) -> Option<&str> {
let text = self.text();
let radix = self.radix();
let mut indices = text.char_indices();
if radix != Radix::Decimal {
indices.next()?;
indices.next()?;
}
let is_suffix_start: fn(&(usize, char)) -> bool = match radix {
Radix::Hexadecimal => |(_, c)| matches!(c, 'g'..='z' | 'G'..='Z'),
_ => |(_, c)| c.is_ascii_alphabetic(),
};
let (suffix_start, _) = indices.find(is_suffix_start)?;
Some(&text[suffix_start..])
let mut suffix = "";
if let Some((suffix_start, _)) = text.char_indices().find(is_suffix_start) {
let (text2, suffix2) = text.split_at(suffix_start);
text = text2;
suffix = suffix2;
};
(prefix, text, suffix)
}
pub fn value(&self) -> Option<u128> {
let (_, text, _) = self.split_into_parts();
let value = u128::from_str_radix(&text.replace("_", ""), self.radix() as u32).ok()?;
Some(value)
}
pub fn suffix(&self) -> Option<&str> {
let (_, _, suffix) = self.split_into_parts();
if suffix.is_empty() {
None
} else {
Some(suffix)
}
}
}