Repository: jaytaph/gosub-browser
File: src/css3/parser.rs (Rust)

Code before:
            let curr_selector = self.selector();

            if let Some(prev_selector) = selector_list.last() {
                if curr_selector.is_combinator() && prev_selector.is_descendant_combinator() {
                    selector_list.pop();
                    selector_list.push(curr_selector);
                } else if curr_selector.is_descendant_combinator() && prev_selector.is_combinator()
                {
                    continue;
                } else {
                    selector_list.push(curr_selector);
                }
            } else {
                selector_list.push(curr_selector);
            }
        }

        if selector_list.is_last_child_descendant_combinator() {
            selector_list.pop();
        }

        println!("Selector List: {:#?}", selector_list);

        selector_list
    }

    ///```txt
    /// Selector
    ///     : IdSelector
    ///     | ClassSelector
    ///     | AttributeSelector
    ///     | TypeSelector
    ///     | NestingSelector
    ///     | Combinator
    ///     ;
    /// ```
    fn selector(&mut self) -> Selector {
        if self.is_next_token(TokenType::Hash) {
            return Selector::IdSelector(self.id_selector());
        }

        if self.is_next_token(TokenType::Dot) {
            return Selector::ClassSelector(self.class_selector());
        }

        if self.is_next_token(TokenType::LBracket) {
            return Selector::AttributeSelector(self.attribute_selector());
        }

        if self.is_next_token(TokenType::Ident) {
            return Selector::TypeSelector(self.type_selector());

Review comment (refactor):
This code snippet is slightly ambiguous and has a lot of nested `if` and `else` statements, which is not good. I will consider refactoring it and adding descriptive comments 

Code after:
        while !self.is_next_token(TokenType::LCurly) {
            let curr_selector = self.selector();

            // todo: refactor this nested if else statements
            if let Some(prev_selector) = selector_list.last() {
                if curr_selector.is_combinator() && prev_selector.is_descendant_combinator() {
                    selector_list.pop();
                    selector_list.push(curr_selector);
                } else if curr_selector.is_descendant_combinator() && prev_selector.is_combinator()
                {
                    continue;
                } else {
                    selector_list.push(curr_selector);
                }
            } else {
                selector_list.push(curr_selector);
            }
        }

        if selector_list.is_last_child_descendant_combinator() {
            selector_list.pop();
        }

        println!("Selector List: {:#?}", selector_list);

        selector_list
    }

    ///```txt
    /// Selector
    ///     : IdSelector
    ///     | ClassSelector
    ///     | AttributeSelector
    ///     | TypeSelector
    ///     | NestingSelector
    ///     | Combinator
    ///     ;
    /// ```
    fn selector(&mut self) -> Selector {
        if self.is_next_token(TokenType::Hash) {
            return Selector::IdSelector(self.id_selector());
        }

        if self.is_next_token(TokenType::Dot) {
            return Selector::ClassSelector(self.class_selector());
        }

        if self.is_next_token(TokenType::LBracket) {
            return Selector::AttributeSelector(self.attribute_selector());
        }