Create a newtype wrapper around Vec<FStringElement> (#11400)

## Summary

This PR adds a newtype wrapper around `Vec<FStringElement>` that derefs
to a `&Vec<FStringElement>`.

Both f-string and format specifier are made up of `Vec<FStringElement>`.
By creating a newtype wrapper around it, we can share the methods for
both parent types.
This commit is contained in:
Dhruv Manilawala 2024-05-13 21:34:04 +05:30 committed by GitHub
parent 0dc130e841
commit 4b41e4de7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 71 additions and 39 deletions

View file

@ -2814,7 +2814,7 @@ impl AstNode for ast::FStringFormatSpec {
where
V: PreorderVisitor<'a> + ?Sized,
{
for element in &self.elements {
for element in self.elements.iter() {
visitor.visit_f_string_element(element);
}
}
@ -2864,7 +2864,7 @@ impl AstNode for ast::FStringExpressionElement {
visitor.visit_expr(expression);
if let Some(format_spec) = format_spec {
for spec_part in &format_spec.elements {
for spec_part in format_spec.elements.iter() {
visitor.visit_f_string_element(spec_part);
}
}
@ -4800,7 +4800,7 @@ impl AstNode for ast::FString {
flags: _,
} = self;
for fstring_element in elements {
for fstring_element in elements.iter() {
visitor.visit_f_string_element(fstring_element);
}
}

View file

@ -3,7 +3,7 @@
use std::fmt;
use std::fmt::Debug;
use std::iter::FusedIterator;
use std::ops::Deref;
use std::ops::{Deref, DerefMut};
use std::slice::{Iter, IterMut};
use std::sync::OnceLock;
@ -1084,7 +1084,7 @@ impl From<ExprCall> for Expr {
#[derive(Clone, Debug, PartialEq)]
pub struct FStringFormatSpec {
pub range: TextRange,
pub elements: Vec<FStringElement>,
pub elements: FStringElements,
}
impl Ranged for FStringFormatSpec {
@ -1484,26 +1484,10 @@ impl fmt::Debug for FStringFlags {
#[derive(Clone, Debug, PartialEq)]
pub struct FString {
pub range: TextRange,
pub elements: Vec<FStringElement>,
pub elements: FStringElements,
pub flags: FStringFlags,
}
impl FString {
/// Returns an iterator over all the [`FStringLiteralElement`] nodes contained in this f-string.
pub fn literals(&self) -> impl Iterator<Item = &FStringLiteralElement> {
self.elements
.iter()
.filter_map(|element| element.as_literal())
}
/// Returns an iterator over all the [`FStringExpressionElement`] nodes contained in this f-string.
pub fn expressions(&self) -> impl Iterator<Item = &FStringExpressionElement> {
self.elements
.iter()
.filter_map(|element| element.as_expression())
}
}
impl Ranged for FString {
fn range(&self) -> TextRange {
self.range
@ -1520,6 +1504,48 @@ impl From<FString> for Expr {
}
}
/// A newtype wrapper around a list of [`FStringElement`].
#[derive(Clone, Default, PartialEq)]
pub struct FStringElements(Vec<FStringElement>);
impl FStringElements {
/// Returns an iterator over all the [`FStringLiteralElement`] nodes contained in this f-string.
pub fn literals(&self) -> impl Iterator<Item = &FStringLiteralElement> {
self.iter().filter_map(|element| element.as_literal())
}
/// Returns an iterator over all the [`FStringExpressionElement`] nodes contained in this f-string.
pub fn expressions(&self) -> impl Iterator<Item = &FStringExpressionElement> {
self.iter().filter_map(|element| element.as_expression())
}
}
impl From<Vec<FStringElement>> for FStringElements {
fn from(elements: Vec<FStringElement>) -> Self {
FStringElements(elements)
}
}
impl Deref for FStringElements {
type Target = Vec<FStringElement>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for FStringElements {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl fmt::Debug for FStringElements {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
pub enum FStringElement {
Literal(FStringLiteralElement),

View file

@ -739,7 +739,7 @@ pub fn walk_pattern_keyword<'a, V: Visitor<'a> + ?Sized>(
}
pub fn walk_f_string<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, f_string: &'a FString) {
for f_string_element in &f_string.elements {
for f_string_element in f_string.elements.iter() {
visitor.visit_f_string_element(f_string_element);
}
}
@ -756,7 +756,7 @@ pub fn walk_f_string_element<'a, V: Visitor<'a> + ?Sized>(
{
visitor.visit_expr(expression);
if let Some(format_spec) = format_spec {
for spec_element in &format_spec.elements {
for spec_element in format_spec.elements.iter() {
visitor.visit_f_string_element(spec_element);
}
}

View file

@ -746,7 +746,7 @@ pub fn walk_pattern_keyword<V: Transformer + ?Sized>(
}
pub fn walk_f_string<V: Transformer + ?Sized>(visitor: &V, f_string: &mut FString) {
for element in &mut f_string.elements {
for element in f_string.elements.iter_mut() {
visitor.visit_f_string_element(element);
}
}
@ -763,7 +763,7 @@ pub fn walk_f_string_element<V: Transformer + ?Sized>(
{
visitor.visit_expr(expression);
if let Some(format_spec) = format_spec {
for spec_element in &mut format_spec.elements {
for spec_element in format_spec.elements.iter_mut() {
visitor.visit_f_string_element(spec_element);
}
}