import re


def is_listener(struct):
    """
    Returns whether the struct name either starts with `on` or ends with
    `listener`.

    This function works with both snake_case and CamelCase patterns.
    """
    matches = re.match(r'(?:^[oO]n[_A-Z].*|.*(?:_l|L)istener$)', struct.name)
    return matches is not None