def add(self, rule, method, name, callback):
if rule != '<STR_LIT:/>':<EOL><INDENT>rule = rule.rstrip('<STR_LIT:/>')<EOL><DEDENT>method = method.upper()<EOL>for i, e in enumerate(self.endpoints):<EOL><INDENT>r, n, callbacks = e<EOL>if r == rule:<EOL><INDENT>assert name == n and n is not None, (<EOL>"<STR_LIT>"<EOL>)<EOL>callbacks[method] = (callback, get_type_hints(callback))<EOL>self.endpoints[i] = (r, name, callbacks)<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>e = (rule, name, {method: (callback, get_type_hints(callback))})<EOL>self.endpoints.append(e)<EOL><DEDENT>
Add a new rule or replace the target for an existing rule.

        >>> from kobin import Response
        >>> r = Router()
        >>> def view(user_id: int) -> Response:
        ...     return Response(f'You are {user_id}')
        ...
        >>> r.add('/users/{user_id}', 'GET', 'user-detail', view)
        >>> path, name, methods = r.endpoints[0]
        >>> path
        '/users/{user_id}'
        >>> name
        'user-detail'
        >>> callback, type_hints = methods['GET']
        >>> view == callback
        True
        >>> type_hints['user_id'] == int
        True