code: def add(self, rule, method, name, callback):
          
          if rule != '/':
              rule = rule.rstrip('/')
          method = method.upper()
  
          for i, e in enumerate(self.endpoints):
              r, n, callbacks = e
              if r == rule:
                  assert name == n and n is not None, (
                      "A same path should set a same name for reverse routing."
                  )
                  callbacks[method] = (callback, get_type_hints(callback))
                  self.endpoints[i] = (r, name, callbacks)
                  break
          else:
              e = (rule, name, {method: (callback, get_type_hints(callback))})
              self.endpoints.append(e)
docs: 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