Skip to content

Refactor Idea: improve lowercase comparison in t.text() calls #87

@justahero

Description

@justahero

In a few places, e.g. in ReplaceEpilogue::find_rules, there is the following call sequence used.

t.text().to_string().to_lowercase()

The first call of text returns a SyntaxText. The second call to_string transforms it into a String which then is transformed into a lower case String to allow comparisons irrespective of case.

Should this pattern appear more frequent (due to increasing number of rules), it might pay off to use an extension trait (see here) to shorten this call sequence. An extension trait is a way to add new methods to existing external types. One rule the Rust compiler will enforce for compatibility reasons, is that it's not allowed to implement external traits on external types, e.g. to add impl PartialEq for SyntaxToken.

The following is a sketch, as there are different syntax token & node types involved.

pub trait SyntaxTokenExt {
    /// Checks if the token has the text ignoring case.
    fn lowercase(&self) -> String;
}

impl SyntaxTokenExt for rowan::cursor::SyntaxToken {
    fn lowercase(&self) -> String {
        self.text().to_lowercase()
    }
}

impl<L: Language> SyntaxTokenExt for rowan::api::SyntaxToken<L> {
    fn lowercase(&self) -> String {
        rowan::cursor::SyntaxToken::from(self.clone()).lowercase()
    }
}

impl SyntaxTokenExt for SyntaxElement {
    fn lowercase(&self) -> String {
        match self {
            rowan::NodeOrToken::Node(node) => node.text().to_string().to_lowercase(),
            rowan::NodeOrToken::Token(token) => token.lowercase(),
        }
    }
}

The result is to call t.lowercase() == "end" instead of t.text().to_string().to_lowercase() == "end". Then it's fairly easy to import the trait where needed and the method is available to be called.

It's only a suggestion, it's down to personal preference to use this type of extension or not, but it might be an option to improve readability in some places.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions