<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def rule_create(self, parent_group_id, direction=None, ethertype=None, ip_protocol=None, from_port=None, to_port=None, cidr=None, group_id=None, description=None):
 """Create a new security group rule. :param parent_group_id: security group id a rule is created to :param direction: ``ingress`` or ``egress`` :param ethertype: ``IPv4`` or ``IPv6`` :param ip_protocol: tcp, udp, icmp :param from_port: L4 port range min :param to_port: L4 port range max :param cidr: Remote IP CIDR :param group_id: ID of Source Security Group :returns: SecurityGroupRule object """

        if not cidr:
            cidr = None
        if isinstance(from_port, int) and from_port < 0:
            from_port = None
        if isinstance(to_port, int) and to_port < 0:
            to_port = None
        if isinstance(ip_protocol, int) and ip_protocol < 0:
            ip_protocol = None

        params = {'security_group_id': parent_group_id,
                  'direction': direction,
                  'ethertype': ethertype,
                  'protocol': ip_protocol,
                  'port_range_min': from_port,
                  'port_range_max': to_port,
                  'remote_ip_prefix': cidr,
                  'remote_group_id': group_id}
        if description is not None:
            params['description'] = description
        body = {'security_group_rule': params}
        try:
            rule = self.client.create_security_group_rule(body)
        except neutron_exc.OverQuotaClient:
            raise exceptions.Conflict(
                _('Security group rule quota exceeded.'))
        except neutron_exc.Conflict:
            raise exceptions.Conflict(
                _('Security group rule already exists.'))
        rule = rule.get('security_group_rule')
        sg_dict = self._sg_name_dict(parent_group_id, [rule])
        return SecurityGroupRule(rule, sg_dict)