mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-20 02:20:25 +00:00
Explicit as_str
(no deref), add no allocation methods (#8826)
## Summary This PR is a follow-up to the AST refactor which does the following: - Remove `Deref` implementation on `StringLiteralValue` and use explicit `as_str` calls instead. The `Deref` implementation would implicitly perform allocations in case of implicitly concatenated strings. This is to make sure the allocation is explicit. - Now, certain methods can be implemented to do zero allocations which have been implemented in this PR. They are: - `is_empty` - `len` - `chars` - Custom `PartialEq` implementation to compare each character ## Test Plan Run the linter test suite and make sure all tests pass.
This commit is contained in:
parent
017e829115
commit
626b0577cd
28 changed files with 95 additions and 77 deletions
|
@ -1213,7 +1213,26 @@ impl StringLiteralValue {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the string literal value is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Returns the total length of the string literal value, in bytes, not
|
||||
/// [`char`]s or graphemes.
|
||||
pub fn len(&self) -> usize {
|
||||
self.parts().fold(0, |acc, part| acc + part.value.len())
|
||||
}
|
||||
|
||||
/// Returns an iterator over the [`char`]s of each string literal part.
|
||||
pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
|
||||
self.parts().flat_map(|part| part.value.chars())
|
||||
}
|
||||
|
||||
/// Returns the concatenated string value as a [`str`].
|
||||
///
|
||||
/// Note that this will perform an allocation on the first invocation if the
|
||||
/// string value is implicitly concatenated.
|
||||
pub fn as_str(&self) -> &str {
|
||||
match &self.inner {
|
||||
StringLiteralValueInner::Single(value) => value.as_str(),
|
||||
|
@ -1224,21 +1243,17 @@ impl StringLiteralValue {
|
|||
|
||||
impl PartialEq<str> for StringLiteralValue {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
self.as_str() == other
|
||||
if self.len() != other.len() {
|
||||
return false;
|
||||
}
|
||||
// The `zip` here is safe because we have checked the length of both parts.
|
||||
self.chars().zip(other.chars()).all(|(c1, c2)| c1 == c2)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<String> for StringLiteralValue {
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
self.as_str() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for StringLiteralValue {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_str()
|
||||
self == other.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue