def add_url_rule(
            self,
            path: str,
            endpoint: Optional[str]=None,
            view_func: Optional[Callable]=None,
            methods: Optional[Iterable[str]]=None,
            defaults: Optional[dict]=None,
            host: Optional[str]=None,
            subdomain: Optional[str]=None,
            *,
            provide_automatic_options: Optional[bool]=None,
            is_websocket: bool=False,
            strict_slashes: bool=True,
    ) -> None:
        """Add a route/url rule to the application.

        This is designed to be used on the application directly. An
        example usage,

        .. code-block:: python

            def route():
                ...

            app.add_url_rule('/', route)

        Arguments:
            path: The path to route on, should start with a ``/``.
            func: Callable that returns a reponse.
            methods: List of HTTP verbs the function routes.
            endpoint: Optional endpoint name, if not present the
                function name is used.
            defaults: A dictionary of variables to provide automatically, use
                to provide a simpler default path for a route, e.g. to allow
                for ``/book`` rather than ``/book/0``,

                .. code-block:: python

                    @app.route('/book', defaults={'page': 0})
                    @app.route('/book/<int:page>')
                    def book(page):
                        ...

            host: The full host name for this route (should include subdomain
                if needed) - cannot be used with subdomain.
            subdomain: A subdomain for this specific route.
            provide_automatic_options: Optionally False to prevent
                OPTION handling.
            strict_slashes: Strictly match the trailing slash present in the
                path. Will redirect a leaf (no slash) to a branch (with slash).
        """
        endpoint = endpoint or _endpoint_from_view_func(view_func)
        handler = ensure_coroutine(view_func)
        if methods is None:
            methods = getattr(view_func, 'methods', ['GET'])

        methods = cast(Set[str], set(methods))
        required_methods = set(getattr(view_func, 'required_methods', set()))

        if provide_automatic_options is None:
            automatic_options = getattr(view_func, 'provide_automatic_options', None)
            if automatic_options is None:
                automatic_options = 'OPTIONS' not in methods
        else:
            automatic_options = provide_automatic_options

        if automatic_options:
            required_methods.add('OPTIONS')

        methods.update(required_methods)

        if not self.url_map.host_matching and (host is not None or subdomain is not None):
            raise RuntimeError('Cannot use host or subdomain without host matching enabled.')
        if host is not None and subdomain is not None:
            raise ValueError('Cannot set host and subdomain, please choose one or the other')

        if subdomain is not None:
            if self.config['SERVER_NAME'] is None:
                raise RuntimeError('SERVER_NAME config is required to use subdomain in a route.')
            host = f"{subdomain}.{self.config['SERVER_NAME']}"
        elif host is None and self.url_map.host_matching:
            host = self.config['SERVER_NAME']
            if host is None:
                raise RuntimeError(
                    'Cannot add a route with host matching enabled without either a specified '
                    'host or a config SERVER_NAME',
                )

        self.url_map.add(
            self.url_rule_class(
                path, methods, endpoint, host=host, provide_automatic_options=automatic_options,
                defaults=defaults, is_websocket=is_websocket, strict_slashes=strict_slashes,
            ),
        )
        if handler is not None:
            old_handler = self.view_functions.get(endpoint)
            if getattr(old_handler, '_quart_async_wrapper', False):
                old_handler = old_handler.__wrapped__  # type: ignore
            if old_handler is not None and old_handler != view_func:
                raise AssertionError(f"Handler is overwriting existing for endpoint {endpoint}")

        self.view_functions[endpoint] = handler
Add a route/url rule to the application.

        This is designed to be used on the application directly. An
        example usage,

        .. code-block:: python

            def route():
                ...

            app.add_url_rule('/', route)

        Arguments:
            path: The path to route on, should start with a ``/``.
            func: Callable that returns a reponse.
            methods: List of HTTP verbs the function routes.
            endpoint: Optional endpoint name, if not present the
                function name is used.
            defaults: A dictionary of variables to provide automatically, use
                to provide a simpler default path for a route, e.g. to allow
                for ``/book`` rather than ``/book/0``,

                .. code-block:: python

                    @app.route('/book', defaults={'page': 0})
                    @app.route('/book/<int:page>')
                    def book(page):
                        ...

            host: The full host name for this route (should include subdomain
                if needed) - cannot be used with subdomain.
            subdomain: A subdomain for this specific route.
            provide_automatic_options: Optionally False to prevent
                OPTION handling.
            strict_slashes: Strictly match the trailing slash present in the
                path. Will redirect a leaf (no slash) to a branch (with slash).