[
  {
    "path": ".clippy.toml",
    "content": "allow-mixed-uninlined-format-args = false\ndisallowed-types = [\n    { path = \"tower::util::BoxCloneService\", reason = \"Use tower::util::BoxCloneSyncService instead\" },\n]\n"
  },
  {
    "path": ".github/DISCUSSION_TEMPLATE/q-a.yml",
    "content": "body:\n  - type: textarea\n    attributes:\n      label: Summary\n      description: 'Your question:'\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: axum version\n      description: 'Please look it up in `Cargo.lock`, or as described below'\n    validations:\n      required: true\n  - type: markdown\n    attributes:\n      value: |\n        > If you have `jq` installed, you can look up the version by running\n        >\n        > ```bash\n        > cargo metadata --format-version=1 | jq -r '.packages[] | select(.name == \"axum\") | .version'\n        > ```\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: 🐛 Bug Report\nabout: If something isn't working as expected 🤔.\n---\n\n<!--\nThank you for reporting an issue.\n\nPlease fill in as much of the template below as you're able.\n-->\n\n- [ ] I have looked for existing issues (including closed) about this\n\n## Bug Report\n\n### Version\n\n<!--\nList the versions of all `axum` crates you are using. The easiest way to get\nthis information is using `cargo tree`:\n\n`cargo tree | grep axum`\n-->\n\n### Platform\n\n<!---\nOutput of `uname -a` (UNIX), or version and 32 or 64-bit (Windows)\n-->\n\n### Crates\n\n<!--\nIf known, please specify the affected axum crates. Otherwise, delete this\nsection.\n-->\n\n### Description\n\n<!--\nEnter your issue details below this comment.\n\nOne way to structure the description:\n\n<short summary of the bug>\n\nI tried this code:\n\n<code sample that causes the bug>\n\nI expected to see this happen: <explanation>\n\nInstead, this happened: <explanation>\n-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "contact_links:\n  - name: 🙏 Q&A (GitHub Discussions)\n    url: https://github.com/tokio-rs/axum/discussions/categories/q-a\n    about: Q&A all around axum usage\n  - name: 💬 Tokio Discord\n    url: https://discord.gg/tokio\n    about: Community chat for Tokio (axum channel is under libs)\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: 💡 Feature Request\nabout: I have a suggestion (and may want to implement it 🙂)!\n---\n\n- [ ] I have looked for existing issues (including closed) about this\n\n## Feature Request\n\n### Motivation\n\n<!--\nPlease describe the use case(s) or other motivation for the new feature.\n-->\n\n### Proposal\n\n<!--\nHow should the new feature be implemented, and why? Add any considered\ndrawbacks.\n-->\n\n### Alternatives\n\n<!--\nAre there other ways to solve this problem that you've considered? What are\ntheir potential drawbacks? Why was the proposed solution chosen over these\nalternatives?\n-->\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\nThank you for your Pull Request. Please provide a description above and review\nthe requirements below.\n\nBug fixes and new features should include tests.\n\nContributors guide: https://github.com/tokio-rs/axum/blob/master/CONTRIBUTING.md\n-->\n\n## Motivation\n\n<!--\nExplain the context and why you're making that change. What is the problem\nyou're trying to solve? If a new feature is being added, describe the intended\nuse case that feature fulfills.\n-->\n\n## Solution\n\n<!--\nSummarize the solution and provide any necessary context needed to understand\nthe code change.\n-->\n"
  },
  {
    "path": ".github/workflows/CI.yml",
    "content": "name: CI\n\nenv:\n  CARGO_TERM_COLOR: always\n  MSRV: '1.80'\n\non:\n  push:\n    branches:\n      - main\n      - v0.*\n  pull_request: {}\n\njobs:\n  check:\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        workspace: [\".\", examples]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@beta\n        with:\n          components: clippy, rustfmt\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n          workspaces: ${{ matrix.workspace }}\n      - name: Check\n        run: cargo clippy --locked --manifest-path ${{ matrix.workspace }}/Cargo.toml --workspace --all-targets --all-features -- -D warnings\n      - name: rustfmt\n        run: cargo fmt --all --check --manifest-path ${{ matrix.workspace }}/Cargo.toml\n\n  check-docs:\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n      - name: cargo doc -p axum-core\n        run: cargo doc --package axum-core --all-features --no-deps\n      - name: cargo doc -p axum\n        run: cargo doc --package axum --all-features --no-deps\n      - name: cargo doc -p axum-extra\n        run: cargo doc --package axum-extra --all-features --no-deps\n    env:\n      RUSTDOCFLAGS: \"-D rustdoc::all -A rustdoc::private-doc-tests\"\n\n  cargo-hack:\n    runs-on: ubuntu-24.04\n    env:\n      # Fail the build if there are any warnings\n      RUSTFLAGS: \"-D warnings\"\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n      - uses: taiki-e/install-action@cargo-hack\n      - name: cargo hack check\n        run: cargo hack check --each-feature --no-dev-deps --all\n\n  external-types:\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: nightly-2025-10-18\n      - name: Install cargo-check-external-types\n        uses: taiki-e/cache-cargo-install-action@v2\n        with:\n          tool: cargo-check-external-types@0.4.0\n      - uses: taiki-e/install-action@cargo-hack\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n      - run: cargo hack --no-private --exclude axum-macros check-external-types --all-features\n\n  test-versions:\n    needs: check\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        rust: [stable, beta]\n        workspace: [\".\", examples]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ matrix.rust }}\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n          workspaces: ${{ matrix.workspace }}\n      - name: Run tests\n        run: cargo test --locked --workspace --all-features --all-targets --manifest-path ${{ matrix.workspace }}/Cargo.toml\n\n  # some examples don't support our MSRV so we only test axum itself on our MSRV\n  test-nightly:\n    needs: check\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - name: Get rust-toolchain version\n        id: rust-toolchain\n        run: echo \"version=$(cat axum-macros/rust-toolchain)\" >> $GITHUB_OUTPUT\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ steps.rust-toolchain.outputs.version }}\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n      - name: Run nightly tests\n        working-directory: axum-macros\n        run: cargo test\n\n  # some examples don't support our MSRV (such as async-graphql)\n  # so we only test axum itself on our MSRV\n  test-msrv:\n    needs: check\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - name: \"install Rust nightly\"\n        uses: dtolnay/rust-toolchain@nightly\n      - name: Select minimal version\n        run: cargo +nightly update -Z minimal-versions\n      - name: Fix up Cargo.lock - crc32fast\n        run: cargo +nightly update -p crc32fast --precise 1.1.1\n      - name: Fix up Cargo.lock - version_check\n        run : cargo +nightly update -p version_check@0.1.0 --precise 0.1.4\n      - name: Fix up Cargo.lock - lazy_static\n        run: cargo +nightly update -p lazy_static --precise 1.1.0\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ env.MSRV }}\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n      - name: Run tests\n        run: cargo +${{ env.MSRV }} test --locked --all-features\n\n  deny-check:\n    name: cargo-deny check\n    runs-on: ubuntu-24.04\n    continue-on-error: ${{ matrix.checks == 'advisories' }}\n    strategy:\n      matrix:\n        checks:\n          - advisories\n          - bans licenses sources\n    steps:\n      - uses: actions/checkout@v6\n      - uses: EmbarkStudios/cargo-deny-action@v2\n        with:\n          command: check ${{ matrix.checks }}\n          manifest-path: axum/Cargo.toml\n\n  armv5te-unknown-linux-musleabi:\n    needs: check\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          target: armv5te-unknown-linux-musleabi\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n      - name: Check\n        env:\n          # Clang has native cross-compilation support\n          CC: clang\n        run: cargo check --all-targets --all-features --target armv5te-unknown-linux-musleabi\n\n  wasm32-unknown-unknown:\n    needs: check\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          target: wasm32-unknown-unknown\n      - uses: Swatinem/rust-cache@v2\n        with:\n          save-if: ${{ github.ref == 'refs/heads/main' }}\n          workspaces: examples\n      - name: Check\n        run: >\n          cargo\n          check\n          --manifest-path ./examples/simple-router-wasm/Cargo.toml\n          --target wasm32-unknown-unknown\n\n  dependencies-are-sorted:\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - name: Install cargo-sort\n        uses: taiki-e/install-action@v2\n        with:\n          tool: cargo-sort@2.0.2\n      - name: Check dependency tables\n        run: cargo-sort --workspace --grouped --check\n      - name: Check examples dependency tables\n        run: cargo-sort --workspace --grouped --check\n        working-directory: examples\n\n  typos:\n    name: Spell Check with Typos\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - name: Check the spelling of the files in our repo\n        uses: crate-ci/typos@v1.29.4\n"
  },
  {
    "path": ".gitignore",
    "content": "target\n.DS_Store\n.vscode\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "axum's changelog has moved and now lives [here](https://github.com/tokio-rs/axum/blob/main/axum/CHANGELOG.md).\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to axum\n\n🎈 Thanks for your help improving the project! We are so happy to have\nyou!\n\nThere are opportunities to contribute to `axum` at any level. It doesn't\nmatter if you are just getting started with Rust or are the most weathered\nexpert, we can use your help.\n\n**No contribution is too small and all contributions are valued.**\n\nThis guide will help you get started. **Do not let this guide intimidate you**.\nIt should be considered a map to help you navigate the process.\n\nDon't know where to start? Check [issues labeled with \"E-help-wanted\"](https://github.com/tokio-rs/axum/issues?q=is%3Aopen+is%3Aissue+label%3AE-help-wanted) or [\"E-easy\"](https://github.com/tokio-rs/axum/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy).\n\nYou may also get help with contributing in the [`axum` Discord\nchannel][discord], please join us!\n\n[discord]: https://discord.gg/tokio\n\n## Conduct\n\nThe `axum` project adheres to the [Rust Code of Conduct][coc]. This\ndescribes the _minimum_ behavior expected from all contributors.\n\n[coc]: https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md\n\n## Contributing in Issues\n\nFor any issue, there are fundamentally three ways an individual can contribute:\n\n1. By opening the issue for discussion: For instance, if you believe that you\n   have uncovered a bug in a `axum` crate, creating a new issue in the\n   tokio-rs/axum [issue tracker][issues] is the way to report it.\n\n2. By helping to triage the issue: This can be done by providing\n   supporting details (a test case that demonstrates a bug), providing\n   suggestions on how to address the issue, or ensuring that the issue is tagged\n   correctly.\n\n3. By helping to resolve the issue: Typically this is done either in the form of\n   demonstrating that the issue reported is not a problem after all, or more\n   often, by opening a Pull Request that changes some bit of something in\n   axum in a concrete and reviewable manner.\n\n**Anybody can participate in any stage of contribution**. We urge you to\nparticipate in the discussion around bugs and participate in reviewing PRs.\n\n[issues]: https://github.com/tokio-rs/axum/issues\n\n### Asking for General Help\n\nIf you have reviewed existing documentation and still have questions or are\nhaving problems, you can open an issue asking for help.\n\nIn exchange for receiving help, we ask that you contribute back a documentation\nPR that helps others avoid the problems that you encountered.\n\n### Submitting a Bug Report\n\nWhen opening a new issue in the `axum` issue tracker, users will\nbe presented with a [basic template][template] that should be filled in. If you\nbelieve that you have uncovered a bug, please fill out this form, following the\ntemplate to the best of your ability. Do not worry if you cannot answer every\ndetail, just fill in what you can.\n\nThe two most important pieces of information we need in order to properly\nevaluate the report is a description of the behavior you are seeing and a simple\ntest case we can use to recreate the problem on our own. If we cannot recreate\nthe issue, it becomes harder for us to fix.\n\nSee [How to create a Minimal, Complete, and Verifiable example][mcve].\n\n[mcve]: https://stackoverflow.com/help/mcve\n[template]: .github/ISSUE_TEMPLATE/bug_report.md\n\n### Triaging a Bug Report\n\nOnce an issue has been opened, it is not uncommon for there to be discussion\naround it. Some contributors may have differing opinions about the issue,\nincluding whether the behavior being seen is a bug or a feature. This discussion\nis part of the process and should be kept focused, helpful, and professional.\n\nShort, clipped responses—that provide neither additional context nor supporting\ndetail—are not helpful or professional. To many, such responses are simply\nannoying and unfriendly.\n\nContributors are encouraged to help one another make forward progress as much as\npossible, empowering one another to solve issues collaboratively. If you choose\nto comment on an issue that you feel either is not a problem that needs to be\nfixed, or if you encounter information in an issue that you feel is incorrect,\nexplain why you feel that way with additional supporting context, and be willing\nto be convinced that you may be wrong. By doing so, we can often reach the\ncorrect outcome much faster.\n\n### Resolving a Bug Report\n\nIn the majority of cases, issues are resolved by opening a Pull Request. The\nprocess for opening and reviewing a Pull Request is similar to that of opening\nand triaging issues, but carries with it a necessary review and approval\nworkflow that ensures that the proposed changes meet the minimal quality.\n\n## Pull Requests\n\nPull Requests are the way concrete changes are made to the code, documentation,\nand dependencies in the `axum` repository.\n\nEven tiny pull requests (e.g., one character pull request fixing a typo in API\ndocumentation) are greatly appreciated. Before making a large change, it is\nusually a good idea to first open an issue describing the change to solicit\nfeedback and guidance. This will increase the likelihood of the PR getting\nmerged.\n\n### Tests\n\nIf the change being proposed alters code (as opposed to only documentation for\nexample), it is either adding new functionality to a crate or it is fixing\nexisting, broken functionality. In both of these cases, the pull request should\ninclude one or more tests to ensure that the crate does not regress in the future.\n\n#### Documentation tests\n\nIdeally, every API has at least one [documentation test] that demonstrates how to\nuse the API. Documentation tests are run with `cargo test --doc`. This ensures\nthat the example is correct and provides additional test coverage.\n\nThe trick to documentation tests is striking a balance between being succinct\nfor a reader to understand and actually testing the API.\n\nIn Rust documentation, lines that start with `/// #` are removed when the\ndocumentation is generated. They are only there to get the test to run.\n\n### Commits\n\nIt is a recommended best practice to keep your changes as logically grouped as\npossible within individual commits. There is no limit to the number of commits\nany single Pull Request may have, and many contributors find it easier to review\nchanges that are split across multiple commits.\n\nNote that multiple commits often get squashed when they are landed (see the\nnotes about [commit squashing]).\n\n#### Commit message guidelines\n\nA good commit message should describe what changed and why.\n\n1. The first line should:\n\n  * Contain a short description of the change (preferably 50 characters or less,\n    and no more than 72 characters)\n\n2. Keep the second line blank.\n3. Wrap all other lines at 72 columns (except for long URLs).\n4. If your patch fixes an open issue, you can add a reference to it at the end\n   of the log. Use the `Fixes: #` prefix and the issue number. For other\n   references use `Refs: #`. `Refs` may include multiple issues, separated by a\n   comma.\n\n   Examples:\n\n   - `Fixes: #1337`\n   - `Refs: #1234, #42`\n\n### Opening the Pull Request\n\nFrom within GitHub, opening a new Pull Request will present you with a\n[template] that should be filled out. Please try to do your best at filling out\nthe details, but feel free to skip parts if you're not sure what to put.\n\n[template]: .github/PULL_REQUEST_TEMPLATE.md\n\n### Discuss and update\n\nYou will probably get feedback or requests for changes to your Pull Request.\nThis is a big part of the submission process so don't be discouraged! Some\ncontributors may sign off on the Pull Request right away, others may have\nmore detailed comments or feedback. This is a necessary part of the process\nin order to evaluate whether the changes are correct and necessary.\n\n**Any community member can review a PR and you might get conflicting feedback**.\nKeep an eye out for comments from code owners to provide guidance on conflicting\nfeedback.\n\n**Once the PR is open, do not rebase the commits**. See [Commit Squashing] for\nmore details.\n\n### Commit Squashing\n\nIn most cases, **do not squash commits that you add to your Pull Request during\nthe review process**. When the commits in your Pull Request land, they may be\nsquashed into one commit per logical change. Metadata will be added to the\ncommit message (including links to the Pull Request, links to relevant issues,\nand the names of the reviewers). The commit history of your Pull Request,\nhowever, will stay intact on the Pull Request page.\n\n## Reviewing Pull Requests\n\n**Any Tokio, Hyperium, and Tower, axum community member is welcome to review any pull request**.\n\nAll contributors who choose to review and provide feedback on Pull Requests have\na responsibility to both the project and the individual making the contribution.\nReviews and feedback must be helpful, insightful, and geared towards improving\nthe contribution as opposed to simply blocking it. If there are reasons why you\nfeel the PR should not land, explain what those are. Do not expect to be able to\nblock a Pull Request from advancing simply because you say \"No\" without giving\nan explanation. Be open to having your mind changed. Be open to working with the\ncontributor to make the Pull Request better.\n\nReviews that are dismissive or disrespectful of the contributor or any other\nreviewers are strictly counter to the Code of Conduct.\n\nWhen reviewing a Pull Request, the primary goals are for the codebase to improve\nand for the person submitting the request to succeed. **Even if a Pull Request\ndoes not land, the submitters should come away from the experience feeling like\ntheir effort was not wasted or unappreciated**. Every Pull Request from a new\ncontributor is an opportunity to grow the community.\n\n### Review a bit at a time.\n\nDo not overwhelm new contributors.\n\nIt is tempting to micro-optimize and make everything about relative performance,\nperfect grammar, or exact style matches. Do not succumb to that temptation.\n\nFocus first on the most significant aspects of the change:\n\n1. Does this change make sense for axum?\n2. Does this change make axum better, even if only incrementally?\n3. Are there clear bugs or larger scale issues that need attending to?\n4. Is the commit message readable and correct? If it contains a breaking change\n   is it clear enough?\n\nNote that only **incremental** improvement is needed to land a PR. This means\nthat the PR does not need to be perfect, only better than the status quo. Follow\nup PRs may be opened to continue iterating.\n\nWhen changes are necessary, *request* them, do not *demand* them, and **do not\nassume that the submitter already knows how to add a test or run a benchmark**.\n\nSpecific performance optimization techniques, coding styles and conventions\nchange over time. The first impression you give to a new contributor never does.\n\nNits (requests for small changes that are not essential) are fine, but try to\navoid stalling the Pull Request. Most nits can typically be fixed by the axum\nCollaborator landing the Pull Request but they can also be an opportunity for\nthe contributor to learn a bit more about the project.\n\nIt is always good to clearly indicate nits when you comment: e.g.\n`Nit: change foo() to bar(). But this is not blocking.`\n\nIf your comments were addressed but were not folded automatically after new\ncommits or if they proved to be mistaken, please, [hide them][hiding-a-comment]\nwith the appropriate reason to keep the conversation flow concise and relevant.\n\n### Be aware of the person behind the code\n\nBe aware that *how* you communicate requests and reviews in your feedback can\nhave a significant impact on the success of the Pull Request. Yes, we may land a\nparticular change that makes `axum` better, but the individual might just\nnot want to have anything to do with `axum` ever again. The goal is not\njust having good code.\n\n### Abandoned or Stalled Pull Requests\n\nIf a Pull Request appears to be abandoned or stalled, it is polite to first\ncheck with the contributor to see if they intend to continue the work before\nchecking if they would mind if you took it over (especially if it just has nits\nleft). When doing so, it is courteous to give the original contributor credit\nfor the work they started, either by preserving their name and email address in\nthe commit log, or by using an `Author: ` meta-data tag in the commit.\n\n[hiding-a-comment]: https://help.github.com/articles/managing-disruptive-comments/#hiding-a-comment\n[documentation test]: https://doc.rust-lang.org/rustdoc/documentation-tests.html\n[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog/blob/master/CHANGELOG.md\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[workspace]\nmembers = [\"axum\", \"axum-*\"]\nresolver = \"2\"\n\n[workspace.package]\nrust-version = \"1.80\"\n\n[workspace.lints.rust]\nunsafe_code = \"forbid\"\n\nrust_2018_idioms = { level = \"warn\", priority = -1 }\nmissing_debug_implementations = \"warn\"\nmissing_docs = \"warn\"\nunreachable_pub = \"warn\"\n\n[workspace.lints.clippy]\ntype_complexity = \"allow\"\n\nawait_holding_lock = \"warn\"\ndbg_macro = \"warn\"\nempty_enums = \"warn\"\nenum_glob_use = \"warn\"\nequatable_if_let = \"warn\"\nexit = \"warn\"\nfilter_map_next = \"warn\"\nfn_params_excessive_bools = \"warn\"\nif_let_mutex = \"warn\"\nimplicit_clone = \"warn\"\nimprecise_flops = \"warn\"\ninefficient_to_string = \"warn\"\nlinkedlist = \"warn\"\nlossy_float_literal = \"warn\"\nmacro_use_imports = \"warn\"\nmanual_let_else = \"warn\"\nmatch_same_arms = \"warn\"\nmatch_wildcard_for_single_variants = \"warn\"\nmem_forget = \"warn\"\nmust_use_candidate = \"warn\"\nneedless_borrow = \"warn\"\nneedless_continue = \"warn\"\nneedless_pass_by_ref_mut = \"warn\"\nneedless_pass_by_value = \"warn\"\noption_option = \"warn\"\nredundant_clone = \"warn\"\nref_option = \"warn\"\nrest_pat_in_fully_bound_structs = \"warn\"\nreturn_self_not_must_use = \"warn\"\nsingle_match_else = \"warn\"\nstr_to_string = \"warn\"\nsuboptimal_flops = \"warn\"\ntodo = \"warn\"\ntrivially_copy_pass_by_ref = \"warn\"\nuninlined_format_args = \"warn\"\nunnested_or_patterns = \"warn\"\nunused_self = \"warn\"\nuse_self = \"warn\"\nverbose_file_reads = \"warn\"\n\n# configuration for https://github.com/crate-ci/typos\n[workspace.metadata.typos.default.extend-identifiers]\n# These have been fixed in the past, but are still present in the changelog.\nDefaultOnFailedUpdgrade = \"DefaultOnFailedUpdgrade\"\nOnFailedUpdgrade = \"OnFailedUpdgrade\"\n"
  },
  {
    "path": "ECOSYSTEM.md",
    "content": "# Community Projects\n\nIf your project isn't listed here and you would like it to be, please feel free to create a PR.\n\n## Community maintained axum ecosystem\n\n- [axum-server](https://crates.io/crates/axum-server): axum-server is a hyper server implementation designed to be used with axum.\n- [axum-typed-websockets](https://crates.io/crates/axum-typed-websockets): `axum::extract::ws` with type safe messages.\n- [tower-cookies](https://crates.io/crates/tower-cookies): Cookie manager middleware\n- [axum-flash](https://crates.io/crates/axum-flash): One-time notifications (aka flash messages) for axum.\n- [axum-msgpack](https://crates.io/crates/axum-msgpack): MessagePack Extractors for axum.\n- [axum-sqlx-tx](https://crates.io/crates/axum-sqlx-tx): Request-bound [SQLx](https://github.com/launchbadge/sqlx#readme) transactions with automatic commit/rollback based on response.\n- [aliri_axum](https://docs.rs/aliri_axum) and [aliri_tower](https://docs.rs/aliri_tower): JWT validation middleware and OAuth2 scopes enforcing extractors.\n- [ezsockets](https://github.com/gbaranski/ezsockets): Easy to use WebSocket library that integrates with axum.\n- [axum_session](https://github.com/AscendingCreations/AxumSessions): Database persistent sessions like pythons flask_sessionstore for axum.\n- [axum_session_auth](https://github.com/AscendingCreations/AxumSessionsAuth): Persistent session based user login with rights management for axum.\n- [axum-auth](https://crates.io/crates/axum-auth): High-level http auth extractors for axum.\n- [axum-keycloak-auth](https://github.com/lpotthast/axum-keycloak-auth): Protect axum routes with a JWT emitted by Keycloak.\n- [axum-tungstenite](https://github.com/davidpdrsn/axum-tungstenite): WebSocket connections for axum directly using tungstenite\n- [axum-jrpc](https://github.com/0xdeafbeef/axum-jrpc): Json-rpc extractor for axum\n- [axum-tracing-opentelemetry](https://crates.io/crates/axum-tracing-opentelemetry): Middlewares and tools to integrate axum + tracing + opentelemetry\n- [svelte-axum-project](https://github.com/jbertovic/svelte-axum-project): Template and example for Svelte frontend app with axum as backend\n- [axum-streams](https://github.com/abdolence/axum-streams-rs): Streaming HTTP body with different formats: JSON, CSV, Protobuf.\n- [axum-template](https://github.com/Altair-Bueno/axum-template): Layers, extractors and template engine wrappers for axum based Web MVC applications\n- [axum-template](https://github.com/janos-r/axum-template): GraphQL and REST API, SurrealDb, JWT auth, direct error handling, request logs\n- [axum-guard-logic](https://github.com/sjud/axum_guard_logic): Use AND/OR logic to extract types and check their values against `Service` inputs.\n- [axum-casbin-auth](https://github.com/casbin-rs/axum-casbin-auth): Casbin access control middleware for axum\n- [aide](https://docs.rs/aide): Code-first Open API documentation generator with [axum integration](https://docs.rs/aide/latest/aide/axum/index.html).\n- [axum-typed-routing](https://docs.rs/axum-typed-routing/latest/axum_typed_routing/): Statically typed routing macros with OpenAPI generation using aide.\n- [axum-jsonschema](https://docs.rs/axum-jsonschema/): A `Json<T>` extractor that does JSON schema validation of requests.\n- [axum-login](https://docs.rs/axum-login): Session-based user authentication for axum.\n- [axum-gate](https://docs.rs/axum-gate): JWT-based authentication and role-based authorization for axum (Cookie and Bearer, for monolithic and distributed applications).\n- [axum-csrf-sync-pattern](https://crates.io/crates/axum-csrf-sync-pattern): A middleware implementing CSRF STP for AJAX backends and API endpoints.\n- [axum-otel-metrics](https://github.com/ttys3/axum-otel-metrics/): A axum OpenTelemetry Metrics middleware with prometheus exporter supported.\n- [tower-otel](https://github.com/mattiapenati/tower-otel): OpenTelemetry layer for HTTP/gRPC services with optional axum integration.\n- [jwt-authorizer](https://crates.io/crates/jwt-authorizer): JWT authorization layer for axum (oidc discovery, validation options, claims extraction, etc.)\n- [axum-typed-multipart](https://crates.io/crates/axum_typed_multipart): Type safe wrapper for `axum::extract::Multipart`.\n- [tower-governor](https://crates.io/crates/tower_governor): A Tower service and layer that provides a rate-limiting backend by [governor](https://crates.io/crates/governor)\n- [axum-restful](https://github.com/gongzhengyang/axum-restful): A restful framework based on axum and sea-orm, inspired by django-rest-framework.\n- [springtime-web-axum](https://crates.io/crates/springtime-web-axum): A web framework built on Springtime and axum, leveraging dependency injection for easy app development.\n- [rust-axum-with-google-oauth](https://github.com/randommm/rust-axum-with-google-oauth): website template for Google OAuth authentication on axum, using SQLite with SQLx or MongoDB and MiniJinja.\n- [axum-htmx](https://github.com/robertwayne/axum-htmx): Htmx extractors and request guards for axum.\n- [axum-prometheus](https://github.com/ptrskay3/axum-prometheus): A middleware library to collect HTTP metrics for axum applications, compatible with all [metrics.rs](https://metrics.rs) exporters.\n- [axum-valid](https://github.com/gengteng/axum-valid): Extractors for data validation using validator, garde, and validify.\n- [tower-sessions](https://github.com/maxcountryman/tower-sessions): Sessions as a `tower` and `axum` middleware.\n- [socketioxide](https://github.com/totodore/socketioxide): An easy to use socket.io server implementation working as a `tower` layer/service.\n- [axum-serde](https://github.com/gengteng/axum-serde): Provides multiple serde-based extractors / responses, also offers a macro to easily customize serde-based extractors / responses.\n- [loco.rs](https://github.com/loco-rs/loco): A full stack Web and API productivity framework similar to Rails, based on axum.\n- [axum-test](https://crates.io/crates/axum-test): High level library for writing Cargo tests that run against axum.\n- [axum-messages](https://github.com/maxcountryman/axum-messages): One-time notification messages for axum.\n- [spring-rs](https://github.com/spring-rs/spring-rs): spring-rs is a microservice framework written in rust inspired by java's spring-boot, based on axum\n- [zino](https://github.com/zino-rs/zino): Zino is a next-generation framework for composable applications which provides full integrations with axum.\n- [axum-rails-cookie](https://github.com/endoze/axum-rails-cookie): Extract rails session cookies in axum based apps.\n- [axum-ws-broadcaster](https://github.com/Necoo33/axum-ws-broadcaster): A broadcasting liblary for both [axum-typed-websockets](https://crates.io/crates/axum-typed-websockets) and `axum::extract::ws`.\n- [axum-negotiate-layer](https://github.com/2ndDerivative/axum-negotiate-layer): Middleware/Layer for Kerberos/NTLM \"Negotiate\" authentication.\n- [axum-kit](https://github.com/4lkaid/axum-kit): Streamline the integration and usage of axum with SQLx and Redis.\n- [tower_allowed_hosts](https://crates.io/crates/tower_allowed_hosts): Allowed hosts middleware which limits request from only allowed hosts.\n- [baxe](https://github.com/zyphelabs/baxe): Simple macro for defining backend errors once and automatically generate standardized JSON error responses, saving time and reducing complexity\n- [axum-html-minifier](https://crates.io/crates/axum_html_minifier): This middleware minify the html body content of a axum response.\n- [static-serve](https://crates.io/crates/static-serve): A helper macro for compressing and embedding static assets in an axum webserver.\n- [datastar](https://crates.io/crates/datastar): Rust implementation of the Datastar SDK specification with Axum support\n- [axum-governor](https://crates.io/crates/axum-governor): An independent Axum middleware for rate limiting, powered by [lazy-limit](https://github.com/canmi21/lazy-limit) (not related to tower-governor).\n- [axum-conditional-requests](https://crates.io/crates/axum-conditional-requests): A library for handling client-side caching HTTP headers\n- [sigterm](https://github.com/canmi21/sigterm): Signal-aware async control and cancellation primitives for Tokio.\n- [tower-resilience](https://github.com/joshrotenberg/tower-resilience): Resilience middleware for tower: circuit breaker, bulkhead, retry, rate limiter, and more.\n\n## Project showcase\n\n- [webshelf](https://github.com/aiqubits/webshelf): 🤘 A convenient way to develop your web service with one click.\n- [HomeDisk](https://github.com/MedzikUser/HomeDisk): ☁️ Fast, lightweight and Open Source local cloud for your data.\n- [Houseflow](https://github.com/gbaranski/houseflow): House automation platform written in Rust.\n- [JWT Auth](https://github.com/Z4RX/axum_jwt_example): JWT auth service for educational purposes.\n- [ROAPI](https://github.com/roapi/roapi): Create full-fledged APIs for static datasets without writing a single line of code.\n- [notify.run](https://github.com/notify-run/notify-run-rs): HTTP-to-WebPush relay for sending desktop/mobile notifications to yourself, written in Rust.\n- [turbo.fish](https://turbo.fish/) ([repository](https://github.com/jplatte/turbo.fish)): Find out for yourself 😉\n- [Book Management](https://github.com/lz1998/axum-book-management): CRUD system of book-management with ORM and JWT for educational purposes.\n- [realworld-axum-sqlx](https://github.com/launchbadge/realworld-axum-sqlx): A Rust implementation of the [Realworld] demo app spec using axum and [SQLx].\n  See https://github.com/davidpdrsn/realworld-axum-sqlx for a fork with up to date dependencies.\n- [Rustapi](https://github.com/ndelvalle/rustapi): RESTful API template using MongoDB\n- [axum-postgres-template](https://github.com/koskeller/axum-postgres-template): Production-ready axum + PostgreSQL application template\n- [RUSTfulapi](https://github.com/robatipoor/rustfulapi): Reusable template for building REST Web Services in Rust. Uses axum and SeaORM.\n- [Jotsy](https://github.com/ohsayan/jotsy): Self-hosted notes app powered by Skytable, axum and Tokio\n- [Svix](https://www.svix.com) ([repository](https://github.com/svix/svix-webhooks)): Enterprise-ready webhook service\n- [emojied](https://emojied.net) ([repository](https://github.com/sekunho/emojied)): Shorten URLs to emojis!\n- [CLOMonitor](https://clomonitor.io) ([repository](https://github.com/cncf/clomonitor)): Checks open source projects repositories to verify they meet certain best practices.\n- [Pinging.net](https://www.pinging.net) ([repository](https://github.com/benhansenslc/pinging)): A new way to check and monitor your internet connection.\n- [wastebin](https://github.com/matze/wastebin): A minimalist pastebin service.\n- [sandbox_axum_observability](https://github.com/davidB/sandbox_axum_observability) A Sandbox/showcase project to experiment axum and observability (tracing, opentelemetry, jaeger, grafana tempo,...)\n- [axum_admin](https://github.com/lingdu1234/axum_admin): An admin panel built with **axum**, Sea-orm and Vue 3.\n- [rgit](https://git.inept.dev/~doyle/rgit.git/about): A blazingly fast Git repository browser, compatible with- and heavily inspired by cgit.\n- [Petclinic](https://github.com/danipardo/petclinic): A port of Spring Framework's Petclinic showcase project to axum\n- [axum-middleware-example](https://github.com/casbin-rs/axum-middleware-example): A authorization application using axum, Casbin and Diesel, with JWT support.\n- [circleci-hook](https://github.com/DavidS/circleci-hook): Translate CircleCI WebHooks to OpenTelemetry traces to improve your test insights. Add detail with otel-cli to capture individual commands. Use the TRACEPARENT integration to add details from your tests.\n- [lishuuro.org](https://github.com/uros-5/backend-lishuuro): Small chess variant server that uses axum for the backend.\n- [freedit](https://github.com/freedit-org/freedit): A forum powered by rust.\n- [axum-http-auth-example](https://github.com/i0n/axum-http-auth-example): axum http auth example using postgres and redis.\n- [Deaftone](https://github.com/Deaftone/Deaftone): Lightweight music server. With a clean and simple API\n- [dropit](https://github.com/scotow/dropit): Temporary file hosting.\n- [cobrust](https://github.com/scotow/cobrust): Multiplayer web based snake game.\n- [meta-cross](https://github.com/scotow/meta-cross): Tweaked version of Tic-Tac-Toe.\n- [httq](https://github.com/scotow/httq) HTTP to MQTT trivial proxy.\n- [Pods-Blitz](https://pods-blitz.org) Self-hosted podcast publisher. Uses the crates axum-login, password-auth, sqlx and handlebars (for HTML templates).\n- [ReductStore](https://github.com/reductstore/reductstore): A time series database for storing and managing large amounts of blob data\n- [randoku](https://github.com/stchris/randoku): A tiny web service which generates random numbers and shuffles lists randomly\n- [sero](https://github.com/clowzed/sero): Host static sites with custom subdomains as surge.sh does. But with full control and cool new features. (axum, sea-orm, postgresql)\n- [Hatsu](https://github.com/importantimport/hatsu): 🩵 Self-hosted & Fully-automated ActivityPub Bridge for Static Sites.\n- [Mini RPS](https://github.com/marcodpt/minirps): Mini reverse proxy server, HTTPS, CORS, static file hosting and template engine (minijinja).\n- [fx](https://github.com/rikhuijzer/fx): A (micro)blogging server that you can self-host.\n- [clean_axum_demo](https://github.com/sukjaelee/clean_axum_demo): A modern, clean-architecture Rust API server template built with Axum and SQLx. It incorporates domain-driven design, repository patterns, JWT authentication, file uploads, Swagger documentation, OpenTelemetry.\n- [qiluo-admin](https://github.com/chelunfu/qiluo_admin) | Axum + SeaORM + JWT + Scheduled + Tasks + SnowId + Redis + Memory + VUE3 | DB: MySQL, Postgres, SQLite\n- [openapi-rs](https://github.com/baerwang/openapi-rs/tree/main/examples/axum) | This project adds a middleware layer to axum using openapi-rs, enabling automatic request validation and processing based on OpenAPI 3.1 specifications. It helps ensure that the server behavior strictly follows the OpenAPI contract.\n- [axum-rest-api-example](https://github.com/sheroz/axum-rest-api-sample): REST API Web service in Rust using axum, JSON Web Tokens (JWT), SQLx, PostgreSQL, Redis, Docker, structured error handling, and end-to-end API tests.\n- [tower-mcp](https://github.com/joshrotenberg/tower-mcp): Tower-native Model Context Protocol (MCP) implementation\n\n[Realworld]: https://github.com/gothinkster/realworld\n[SQLx]: https://github.com/launchbadge/sqlx\n\n## Tutorials\n\n- [Rust on Nails](https://rust-on-nails.com/): A full stack architecture for Rust web applications\n- [axum-tutorial] ([website][axum-tutorial-website]): axum tutorial for beginners\n- [demo-rust-axum]: Demo of Rust and axum\n- [Introduction to axum (talk)]: Talk about axum from the Copenhagen Rust Meetup\n- [Getting Started with Axum]: axum tutorial, GET, POST endpoints and serving files\n- [Using Rust, Axum, PostgreSQL, and Tokio to build a Blog]\n- [Introduction to axum]: YouTube playlist\n- [Rust Axum Full Course]: YouTube video\n- [API Development with Rust](https://rust-api.dev/docs/front-matter/preface/): REST APIs based on axum\n- [axum-rest-api-postgres-redis-jwt-docker]: Getting started with REST API Web Services in Rust using Axum, PostgreSQL, Redis, and JWT\n\n[axum-tutorial]: https://github.com/programatik29/axum-tutorial\n[axum-tutorial-website]: https://programatik29.github.io/axum-tutorial/\n[demo-rust-axum]: https://github.com/joelparkerhenderson/demo-rust-axum\n[Introduction to axum (talk)]: https://www.youtube.com/watch?v=ETdmhh7OQpA\n[Getting Started with Axum]: https://carlosmv.hashnode.dev/getting-started-with-axum-rust\n[Using Rust, Axum, PostgreSQL, and Tokio to build a Blog]: https://spacedimp.com/blog/using-rust-axum-postgresql-and-tokio-to-build-a-blog/\n[Introduction to axum]: https://www.youtube.com/playlist?list=PLrmY5pVcnuE-_CP7XZ_44HN-mDrLQV4nS\n[Rust Axum Full Course]: https://www.youtube.com/watch?v=XZtlD_m59sM\n[axum-rest-api-postgres-redis-jwt-docker]: https://sheroz.com/pages/blog/rust-axum-rest-api-postgres-redis-jwt-docker.html\n[Building a SaaS with Rust & Next.js](https://joshmo.bearblog.dev/lets-build-a-saas-with-rust/) A tutorial for combining Next.js with Rust via axum to make a SaaS.\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019–2025 axum Contributors\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
  },
  {
    "path": "axum/CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n# Unreleased\n\n- **breaking:** Router fallbacks are now properly merged for nested routers ([#3158])\n- **breaking:** `#[from_request(via(Extractor))]` now uses the extractor's\n  rejection type instead of `axum::response::Response` ([#3261])\n- **breaking:** `axum::serve` now applies hyper's default `header_read_timeout` ([#3478])\n- **breaking:** `axum::serve` future output type has been adjusted to remove `io::Result`\n  (never returned `Err`) and be an uninhabited type if `with_graceful_shutdown` is not used\n  (because it was already never terminating if that method wasn't used) ([#3601])\n- **added:** New `ListenerExt::limit_connections` allows limiting concurrent `axum::serve` connections ([#3489])\n- **added:** `MethodRouter::method_filter` ([#3586])\n- **added:** `WebSocketUpgrade::{requested_protocols, set_selected_protocol}` for more\n  flexible subprotocol selection ([#3597])\n- **changed:** `serve` has an additional generic argument and can now work with any response body\n  type, not just `axum::body::Body` ([#3205])\n- **changed:** Update minimum rust version to 1.80 ([#3620])\n- **changed:** `Redirect` constructors now accept any `impl Into<String>` ([#3635])\n\n[#3158]: https://github.com/tokio-rs/axum/pull/3158\n[#3261]: https://github.com/tokio-rs/axum/pull/3261\n[#3205]: https://github.com/tokio-rs/axum/pull/3205\n[#3478]: https://github.com/tokio-rs/axum/pull/3478\n[#3601]: https://github.com/tokio-rs/axum/pull/3601\n[#3489]: https://github.com/tokio-rs/axum/pull/3489\n[#3586]: https://github.com/tokio-rs/axum/pull/3586\n[#3597]: https://github.com/tokio-rs/axum/pull/3597\n[#3620]: https://github.com/tokio-rs/axum/pull/3620\n\n# 0.8.8\n\n- Clarify documentation for `Router::route_layer` ([#3567])\n\n[#3567]: https://github.com/tokio-rs/axum/pull/3567\n\n# 0.8.7\n\n- Relax implicit `Send` / `Sync` bounds on `RouterAsService`, `RouterIntoService` ([#3555])\n- Make it easier to visually scan for default features ([#3550])\n- Fix some documentation typos\n\n[#3550]: https://github.com/tokio-rs/axum/pull/3550\n[#3555]: https://github.com/tokio-rs/axum/pull/3555\n\n# 0.8.6\n\nReleased without changes to fix docs.rs build.\n\n# 0.8.5\n\n- **fixed:** Reject JSON request bodies with trailing characters after the JSON document ([#3453])\n- **added:** Implement `OptionalFromRequest` for `Multipart` ([#3220])\n- **added:** Getter methods `Location::{status_code, location}`\n- **added:** Support for writing arbitrary binary data into server-sent events ([#3425])]\n- **added:** `middleware::ResponseAxumBodyLayer` for mapping response body to `axum::body::Body` ([#3469])\n- **added:** `impl FusedStream for WebSocket` ([#3443])\n- **changed:** The `sse` module and `Sse` type no longer depend on the `tokio` feature ([#3154])\n- **changed:** If the location given to one of `Redirect`s constructors is not a valid\n  header value, instead of panicking on construction, the `IntoResponse` impl now returns\n  an HTTP 500, just like `Json` does when serialization fails ([#3377])\n- **changed:** Update minimum rust version to 1.78 ([#3412])\n\n[#3154]: https://github.com/tokio-rs/axum/pull/3154\n[#3220]: https://github.com/tokio-rs/axum/pull/3220\n[#3377]: https://github.com/tokio-rs/axum/pull/3377\n[#3412]: https://github.com/tokio-rs/axum/pull/3412\n[#3425]: https://github.com/tokio-rs/axum/pull/3425\n[#3443]: https://github.com/tokio-rs/axum/pull/3443\n[#3453]: https://github.com/tokio-rs/axum/pull/3453\n[#3469]: https://github.com/tokio-rs/axum/pull/3469\n\n# 0.8.4\n\n- **added:** `Router::reset_fallback` ([#3320])\n- **added:** `WebSocketUpgrade::selected_protocol` ([#3248])\n- **fixed:** Panic location for overlapping method routes ([#3319])\n- **fixed:** Don't leak a tokio task when using `serve` without graceful shutdown ([#3129])\n\n[#3319]: https://github.com/tokio-rs/axum/pull/3319\n[#3320]: https://github.com/tokio-rs/axum/pull/3320\n[#3248]: https://github.com/tokio-rs/axum/pull/3248\n[#3129]: https://github.com/tokio-rs/axum/pull/3129\n\n# 0.8.3\n\n- **added:** Implement `From<Bytes>` for `Message` ([#3273])\n- **added:** Implement `OptionalFromRequest` for `Json` ([#3142])\n- **added:** Implement `OptionalFromRequest` for `Extension` ([#3157])\n- **added:** Allow setting the read buffer capacity of `WebSocketUpgrade` ([#3178])\n- **changed:** Improved code size / compile time of dependent crates ([#3285], [#3294])\n\n[#3273]: https://github.com/tokio-rs/axum/pull/3273\n[#3142]: https://github.com/tokio-rs/axum/pull/3142\n[#3157]: https://github.com/tokio-rs/axum/pull/3157\n[#3178]: https://github.com/tokio-rs/axum/pull/3178\n[#3285]: https://github.com/tokio-rs/axum/pull/3285\n[#3294]: https://github.com/tokio-rs/axum/pull/3294\n\n# 0.8.2\n\nYanked from crates.io due to unforeseen breaking change, see [#3190] for details.\n\n[#3190]: https://github.com/tokio-rs/axum/pull/3190\n\n# 0.8.1\n\n- **fixed:** Removed the warning about breaking changes from README\n\n# 0.8.0\n\n## since rc.1\n\n<details>\n\n- **breaking:** `axum::extract::ws::Message` now uses `Bytes` in place of `Vec<u8>`,\n  and a new `Utf8Bytes` type in place of `String`, for its variants ([#3078])\n- **breaking:** Remove `OptionalFromRequestParts` impl for `Query` ([#3088])\n- **changed:** Upgraded `tokio-tungstenite` to 0.26 ([#3078])\n- **changed:** Query/Form: Use `serde_path_to_error` to report fields that failed to parse ([#3081])\n\n[#3088]: https://github.com/tokio-rs/axum/pull/3088\n\n</details>\n\n## full changelog\n\n*Note: there are further relevant changes in [axum-core's changelog][core-changelog]*\n\n- **breaking:** Upgrade matchit to 0.8, changing the path parameter syntax from `/:single` and `/*many`\n  to `/{single}` and `/{*many}`; the old syntax produces a panic to avoid silent change in behavior ([#2645])\n- **breaking:** Require `Sync` for all handlers and services added to `Router`\n  and `MethodRouter` ([#2473])\n- **breaking:** The tuple and tuple_struct `Path` extractor deserializers now check that the number of parameters matches the tuple length exactly ([#2931])\n- **breaking:** Move `Host` extractor to `axum-extra` ([#2956])\n- **breaking:** Remove `WebSocket::close`.\n  Users should explicitly send close messages themselves. ([#2974])\n- **breaking:** Make `serve` generic over the listener and IO types ([#2941])\n- **breaking:** Remove `Serve::tcp_nodelay` and `WithGracefulShutdown::tcp_nodelay`.\n  See `serve::ListenerExt` for an API that let you set arbitrary TCP stream properties. ([#2941])\n- **breaking:** `Option<Path<T>>` no longer swallows all error conditions,\n  instead rejecting the request in many cases; see its documentation for details ([#2475])\n- **breaking:** `axum::extract::ws::Message` now uses `Bytes` in place of `Vec<u8>`,\n  and a new `Utf8Bytes` type in place of `String`, for its variants ([#3078])\n- **fixed:** Skip SSE incompatible chars of `serde_json::RawValue` in `Event::json_data` ([#2992])\n- **fixed:** Don't panic when array type is used for path segment ([#3039])\n- **fixed:** Avoid setting `content-length` before middleware.\n  This allows middleware to add bodies to requests without needing to manually set `content-length` ([#2897])\n- **change:** Update minimum rust version to 1.75 ([#2943])\n- **changed:** Upgraded `tokio-tungstenite` to 0.26 ([#3078])\n- **changed:** Query/Form: Use `serde_path_to_error` to report fields that failed to parse ([#3081])\n- **added:** Add `method_not_allowed_fallback` to set a fallback when a path matches but there is no handler for the given HTTP method ([#2903])\n- **added:** Add `NoContent` as a self-described shortcut for `StatusCode::NO_CONTENT` ([#2978])\n- **added:** Add support for WebSockets over HTTP/2.\n  They can be enabled by changing `get(ws_endpoint)` handlers to `any(ws_endpoint)` ([#2894])\n- **added:** Add `MethodFilter::CONNECT`, `routing::connect[_service]`\n  and `MethodRouter::connect[_service]` ([#2961])\n- **added:** Extend `FailedToDeserializePathParams::kind` enum with (`ErrorKind::DeserializeError`)\n  This new variant captures both `key`, `value`, and `message` from named path parameters parse errors,\n  instead of only deserialization error message in `ErrorKind::Message`. ([#2720])\n\n[#3078]: https://github.com/tokio-rs/axum/pull/3078\n[#3081]: https://github.com/tokio-rs/axum/pull/3081\n\n## rc.1\n\n*Note: there are further relevant changes in [axum-core's changelog][core-changelog]*\n\n- **breaking:** Move `Host` extractor to `axum-extra` ([#2956])\n- **breaking:** Remove `WebSocket::close`.\n  Users should explicitly send close messages themselves. ([#2974])\n- **breaking:** Make `serve` generic over the listener and IO types ([#2941])\n- **breaking:** Remove `Serve::tcp_nodelay` and `WithGracefulShutdown::tcp_nodelay`.\n  See `serve::ListenerExt` for an API that let you set arbitrary TCP stream properties. ([#2941])\n- **breaking:** `Option<Path<T>>` and `Option<Query<T>>` no longer swallow all error conditions,\n  instead rejecting the request in many cases; see their documentation for details ([#2475])\n- **fixed:** Skip SSE incompatible chars of `serde_json::RawValue` in `Event::json_data` ([#2992])\n- **fixed:** Don't panic when array type is used for path segment ([#3039])\n- **fixed:** Avoid setting `content-length` before middleware.\n  This allows middleware to add bodies to requests without needing to manually set `content-length` ([#2897])\n- **added:** Add `method_not_allowed_fallback` to set a fallback when a path matches but there is no handler for the given HTTP method ([#2903])\n- **added:** Add `NoContent` as a self-described shortcut for `StatusCode::NO_CONTENT` ([#2978])\n- **added:** Add support for WebSockets over HTTP/2.\n  They can be enabled by changing `get(ws_endpoint)` handlers to `any(ws_endpoint)` ([#2894])\n- **added:** Add `MethodFilter::CONNECT`, `routing::connect[_service]`\n  and `MethodRouter::connect[_service]` ([#2961])\n- **added:** Extend `FailedToDeserializePathParams::kind` enum with (`ErrorKind::DeserializeError`)\n  This new variant captures both `key`, `value`, and `message` from named path parameters parse errors,\n  instead of only deserialization error message in `ErrorKind::Message`. ([#2720])\n\n[core-changelog]: ../axum-core/CHANGELOG.md\n[#2475]: https://github.com/tokio-rs/axum/pull/2475\n[#2897]: https://github.com/tokio-rs/axum/pull/2897\n[#2903]: https://github.com/tokio-rs/axum/pull/2903\n[#2894]: https://github.com/tokio-rs/axum/pull/2894\n[#2956]: https://github.com/tokio-rs/axum/pull/2956\n[#2961]: https://github.com/tokio-rs/axum/pull/2961\n[#2974]: https://github.com/tokio-rs/axum/pull/2974\n[#2978]: https://github.com/tokio-rs/axum/pull/2978\n[#2992]: https://github.com/tokio-rs/axum/pull/2992\n[#2720]: https://github.com/tokio-rs/axum/pull/2720\n[#3039]: https://github.com/tokio-rs/axum/pull/3039\n[#2941]: https://github.com/tokio-rs/axum/pull/2941\n\n## alpha.1\n\n- **breaking:** Require `Sync` for all handlers and services added to `Router`\n  and `MethodRouter` ([#2473])\n- **breaking:** The tuple and tuple_struct `Path` extractor deserializers now check that the number of parameters matches the tuple length exactly ([#2931])\n- **breaking:** Upgrade matchit to 0.8, changing the path parameter syntax from `/:single` and `/*many`\n  to `/{single}` and `/{*many}`; the old syntax produces a panic to avoid silent change in behavior ([#2645])\n- **change:** Update minimum rust version to 1.75 ([#2943])\n\n[#2473]: https://github.com/tokio-rs/axum/pull/2473\n[#2645]: https://github.com/tokio-rs/axum/pull/2645\n[#2931]: https://github.com/tokio-rs/axum/pull/2931\n[#2943]: https://github.com/tokio-rs/axum/pull/2943\n\n# 0.7.9\n\n- **fixed:** Avoid setting content-length before middleware ([#3031])\n\n[#3031]:https://github.com/tokio-rs/axum/pull/3031\n\n# 0.7.8\n\n- **fixed:** Skip SSE incompatible chars of `serde_json::RawValue` in `Event::json_data` ([#2992])\n- **added:** Add `method_not_allowed_fallback` to set a fallback when a path matches but there is no handler for the given HTTP method ([#2903])\n- **added:** Add `MethodFilter::CONNECT`, `routing::connect[_service]`\n  and `MethodRouter::connect[_service]` ([#2961])\n- **added:** Add `NoContent` as a self-described shortcut for `StatusCode::NO_CONTENT` ([#2978])\n\n[#2903]: https://github.com/tokio-rs/axum/pull/2903\n[#2961]: https://github.com/tokio-rs/axum/pull/2961\n[#2978]: https://github.com/tokio-rs/axum/pull/2978\n[#2992]: https://github.com/tokio-rs/axum/pull/2992\n\n# 0.7.7\n\n- **change**: Remove manual tables of content from the documentation, since\n  rustdoc now generates tables of content in the sidebar ([#2921])\n\n[#2921]: https://github.com/tokio-rs/axum/pull/2921\n\n# 0.7.6\n\n- **change:** Avoid cloning `Arc` during deserialization of `Path`\n- **added:** `axum::serve::Serve::tcp_nodelay` and `axum::serve::WithGracefulShutdown::tcp_nodelay` ([#2653])\n- **added:** `Router::has_routes` function ([#2790])\n- **change:** Update tokio-tungstenite to 0.23 ([#2841])\n- **added:** `Serve::local_addr` and `WithGracefulShutdown::local_addr` functions ([#2881])\n\n[#2653]: https://github.com/tokio-rs/axum/pull/2653\n[#2790]: https://github.com/tokio-rs/axum/pull/2790\n[#2841]: https://github.com/tokio-rs/axum/pull/2841\n[#2881]: https://github.com/tokio-rs/axum/pull/2881\n\n# 0.7.5 (24. March, 2024)\n\n- **fixed:** Fixed layers being cloned when calling `axum::serve` directly with\n  a `Router` or `MethodRouter` ([#2586])\n- **fixed:** `h2` is no longer pulled as a dependency unless the `http2` feature\n  is enabled ([#2605])\n- **added:** Add `#[debug_middleware]` ([#1993], [#2725])\n\n[#1993]: https://github.com/tokio-rs/axum/pull/1993\n[#2725]: https://github.com/tokio-rs/axum/pull/2725\n[#2586]: https://github.com/tokio-rs/axum/pull/2586\n[#2605]: https://github.com/tokio-rs/axum/pull/2605\n\n# 0.7.4 (13. January, 2024)\n\n- **fixed:** Fix performance regression present since axum 0.7.0 ([#2483])\n- **fixed:** Improve `debug_handler` on tuple response types ([#2201])\n- **added:** Add `must_use` attribute to `Serve` and `WithGracefulShutdown` ([#2484])\n- **added:** Re-export `axum_core::body::BodyDataStream` from axum\n\n[#2201]: https://github.com/tokio-rs/axum/pull/2201\n[#2483]: https://github.com/tokio-rs/axum/pull/2483\n[#2484]: https://github.com/tokio-rs/axum/pull/2484\n\n# 0.7.3 (29. December, 2023)\n\n- **added:** `Body` implements `From<()>` now ([#2411])\n- **change:** Update version of multer used internally for multipart ([#2433])\n- **change:** Update tokio-tungstenite to 0.21 ([#2435])\n- **added:** Enable `tracing` feature by default ([#2460])\n- **added:** Support graceful shutdown on `serve` ([#2398])\n- **added:** `RouterIntoService` implements `Clone` ([#2456])\n\n[#2411]: https://github.com/tokio-rs/axum/pull/2411\n[#2433]: https://github.com/tokio-rs/axum/pull/2433\n[#2435]: https://github.com/tokio-rs/axum/pull/2435\n[#2460]: https://github.com/tokio-rs/axum/pull/2460\n[#2398]: https://github.com/tokio-rs/axum/pull/2398\n[#2456]: https://github.com/tokio-rs/axum/pull/2456\n\n# 0.7.2 (03. December, 2023)\n\n- **added:** Add `axum::body::to_bytes` ([#2373])\n- **fixed:** Gracefully handle accept errors in `serve` ([#2400])\n\n[#2373]: https://github.com/tokio-rs/axum/pull/2373\n[#2400]: https://github.com/tokio-rs/axum/pull/2400\n\n# 0.7.1 (27. November, 2023)\n\n- **fix**: Fix readme.\n\n# 0.7.0 (27. November, 2023)\n\n- **breaking:** Update public dependencies. axum now requires\n    - [hyper](https://crates.io/crates/hyper) 1.0\n    - [http](https://crates.io/crates/http) 1.0\n    - [http-body](https://crates.io/crates/http-body) 1.0\n- **breaking:** axum now requires [tower-http](https://crates.io/crates/tower-http) 0.5\n- **breaking:** Remove deprecated `WebSocketUpgrade::max_send_queue`\n- **breaking:** The following types/traits are no longer generic over the request body\n  (i.e. the `B` type param has been removed) ([#1751] and [#1789]):\n  - `FromRequestParts`\n  - `FromRequest`\n  - `HandlerService`\n  - `HandlerWithoutStateExt`\n  - `Handler`\n  - `LayeredFuture`\n  - `Layered`\n  - `MethodRouter`\n  - `Next`\n  - `RequestExt`\n  - `RouteFuture`\n  - `Route`\n  - `Router`\n- **breaking:** axum no longer re-exports `hyper::Body` as that type is removed\n  in hyper 1.0. Instead axum has its own body type at `axum::body::Body` ([#1751])\n- **breaking:** `extract::BodyStream` has been removed as `body::Body`\n  implements `Stream` and `FromRequest` directly ([#1751])\n- **breaking:** Change `sse::Event::json_data` to use `axum_core::Error` as its error type ([#1762])\n- **breaking:** Rename `DefaultOnFailedUpdgrade` to `DefaultOnFailedUpgrade` ([#1664])\n- **breaking:** Rename `OnFailedUpdgrade` to `OnFailedUpgrade` ([#1664])\n- **breaking:** `TypedHeader` has been moved to `axum-extra` as `axum_extra::TypedHeader` and requires enabling the `typed-header` feature on `axum-extra`. The `headers` feature has been removed from axum; what it provided under `axum::headers` is now found in `axum_extra::headers` by default. ([#1850])\n- **breaking:** Removed re-exports of `Empty` and `Full`. Use\n  `axum::body::Body::empty` and `axum::body::Body::from` respectively ([#1789])\n- **breaking:** The response returned by `IntoResponse::into_response` must use\n  `axum::body::Body` as the body type. `axum::response::Response` does this\n  ([#1789])\n- **breaking:** Removed the `BoxBody` type alias and its `box_body`\n  constructor. Use `axum::body::Body::new` instead ([#1789])\n- **breaking:** Remove `RawBody` extractor. `axum::body::Body` implements `FromRequest` directly ([#1789])\n- **breaking:** The following types from `http-body` no longer implement `IntoResponse`:\n  - `Full`, use `Body::from` instead\n  - `Empty`, use `Body::empty` instead\n  - `BoxBody`, use `Body::new` instead\n  - `UnsyncBoxBody`, use `Body::new` instead\n  - `MapData`, use `Body::new` instead\n  - `MapErr`, use `Body::new` instead\n- **added:** Add `axum::extract::Request` type alias where the body is `axum::body::Body` ([#1789])\n- **added:** Add `Router::as_service` and `Router::into_service` to workaround\n  type inference issues when calling `ServiceExt` methods on a `Router` ([#1835])\n- **breaking:** Removed `axum::Server` as it was removed in hyper 1.0. Instead\n  use `axum::serve(listener, service)` or hyper/hyper-util for more configuration options ([#1868])\n- **breaking:** Only inherit fallbacks for routers nested with `Router::nest`.\n  Routers nested with `Router::nest_service` will no longer inherit fallbacks ([#1956])\n- **fixed:** Don't remove the `Sec-WebSocket-Key` header in `WebSocketUpgrade` ([#1972])\n- **added:** Add `axum::extract::Query::try_from_uri` ([#2058])\n- **added:** Implement `IntoResponse` for `Box<str>` and `Box<[u8]>` ([#2035])\n- **breaking:** Simplify `MethodFilter`. It no longer uses bitflags ([#2073])\n- **fixed:** Fix bugs around merging routers with nested fallbacks ([#2096])\n- **fixed:** Fix `.source()` of composite rejections ([#2030])\n- **fixed:** Allow unreachable code in `#[debug_handler]` ([#2014])\n- **change:** axum's MSRV is now 1.66 ([#1882])\n- **added:** Implement `IntoResponse` for `(R,) where R: IntoResponse` ([#2143])\n- **changed:** For SSE, add space between field and value for compatibility ([#2149])\n- **added:** Add `NestedPath` extractor ([#1924])\n- **added:** Add `handle_error` function to existing `ServiceExt` trait ([#2235])\n- **breaking:** `impl<T> IntoResponse(Parts) for Extension<T>` now requires\n  `T: Clone`, as that is required by the http crate ([#1882])\n- **added:** Add `axum::Json::from_bytes` ([#2244])\n- **added:** Implement `FromRequestParts` for `http::request::Parts` ([#2328])\n- **added:** Implement `FromRequestParts` for `http::Extensions` ([#2328])\n- **fixed:** Clearly document applying `DefaultBodyLimit` to individual routes ([#2157])\n\n[#1664]: https://github.com/tokio-rs/axum/pull/1664\n[#1751]: https://github.com/tokio-rs/axum/pull/1751\n[#1762]: https://github.com/tokio-rs/axum/pull/1762\n[#1789]: https://github.com/tokio-rs/axum/pull/1789\n[#1835]: https://github.com/tokio-rs/axum/pull/1835\n[#1850]: https://github.com/tokio-rs/axum/pull/1850\n[#1868]: https://github.com/tokio-rs/axum/pull/1868\n[#1882]: https://github.com/tokio-rs/axum/pull/1882\n[#1924]: https://github.com/tokio-rs/axum/pull/1924\n[#1956]: https://github.com/tokio-rs/axum/pull/1956\n[#1972]: https://github.com/tokio-rs/axum/pull/1972\n[#2014]: https://github.com/tokio-rs/axum/pull/2014\n[#2021]: https://github.com/tokio-rs/axum/pull/2021\n[#2030]: https://github.com/tokio-rs/axum/pull/2030\n[#2058]: https://github.com/tokio-rs/axum/pull/2058\n[#2073]: https://github.com/tokio-rs/axum/pull/2073\n[#2096]: https://github.com/tokio-rs/axum/pull/2096\n[#2140]: https://github.com/tokio-rs/axum/pull/2140\n[#2143]: https://github.com/tokio-rs/axum/pull/2143\n[#2149]: https://github.com/tokio-rs/axum/pull/2149\n[#2157]: https://github.com/tokio-rs/axum/pull/2157\n[#2235]: https://github.com/tokio-rs/axum/pull/2235\n[#2244]: https://github.com/tokio-rs/axum/pull/2244\n[#2328]: https://github.com/tokio-rs/axum/pull/2328\n\n# 0.6.20 (03. August, 2023)\n\n- **added:** `WebSocketUpgrade::write_buffer_size` and `WebSocketUpgrade::max_write_buffer_size`\n- **changed:** Deprecate `WebSocketUpgrade::max_send_queue`\n- **change:** Update tokio-tungstenite to 0.20\n- **added:** Implement `Handler` for `T: IntoResponse` ([#2140])\n\n[#2140]: https://github.com/tokio-rs/axum/pull/2140\n\n# 0.6.19 (17. July, 2023)\n\n- **added:** Add `axum::extract::Query::try_from_uri` ([#2058])\n- **added:** Implement `IntoResponse` for `Box<str>` and `Box<[u8]>` ([#2035])\n- **fixed:** Fix bugs around merging routers with nested fallbacks ([#2096])\n- **fixed:** Fix `.source()` of composite rejections ([#2030])\n- **fixed:** Allow unreachable code in `#[debug_handler]` ([#2014])\n- **change:** Update tokio-tungstenite to 0.19 ([#2021])\n- **change:** axum's MSRV is now 1.63 ([#2021])\n\n[#2014]: https://github.com/tokio-rs/axum/pull/2014\n[#2021]: https://github.com/tokio-rs/axum/pull/2021\n[#2030]: https://github.com/tokio-rs/axum/pull/2030\n[#2035]: https://github.com/tokio-rs/axum/pull/2035\n[#2058]: https://github.com/tokio-rs/axum/pull/2058\n[#2096]: https://github.com/tokio-rs/axum/pull/2096\n\n# 0.6.18 (30. April, 2023)\n\n- **fixed:** Don't remove the `Sec-WebSocket-Key` header in `WebSocketUpgrade` ([#1972])\n\n[#1972]: https://github.com/tokio-rs/axum/pull/1972\n\n# 0.6.17 (25. April, 2023)\n\n- **fixed:** Fix fallbacks causing a panic on `CONNECT` requests ([#1958])\n\n[#1958]: https://github.com/tokio-rs/axum/pull/1958\n\n# 0.6.16 (18. April, 2023)\n\n- **fixed:** Don't allow extracting `MatchedPath` in fallbacks ([#1934])\n- **fixed:** Fix panic if `Router` with something nested at `/` was used as a fallback ([#1934])\n- **added:** Document that `Router::new().fallback(...)` isn't optimal ([#1940])\n\n[#1934]: https://github.com/tokio-rs/axum/pull/1934\n[#1940]: https://github.com/tokio-rs/axum/pull/1940\n\n# 0.6.15 (12. April, 2023)\n\n- **fixed:** Removed additional leftover debug messages ([#1927])\n\n[#1927]: https://github.com/tokio-rs/axum/pull/1927\n\n# 0.6.14 (11. April, 2023)\n\n- **fixed:** Removed leftover \"path_router hit\" debug message ([#1925])\n\n[#1925]: https://github.com/tokio-rs/axum/pull/1925\n\n# 0.6.13 (11. April, 2023)\n\n- **added:** Log rejections from built-in extractors with the\n  `axum::rejection=trace` target ([#1890])\n- **fixed:** Fixed performance regression with `Router::nest` introduced in\n  0.6.0. `nest` now flattens the routes which performs better ([#1711])\n- **fixed:** Extracting `MatchedPath` in nested handlers now gives the full\n  matched path, including the nested path ([#1711])\n- **added:** Implement `Deref` and `DerefMut` for built-in extractors ([#1922])\n\n[#1711]: https://github.com/tokio-rs/axum/pull/1711\n[#1890]: https://github.com/tokio-rs/axum/pull/1890\n[#1922]: https://github.com/tokio-rs/axum/pull/1922\n\n# 0.6.12 (22. March, 2023)\n\n- **added:** Implement `IntoResponse` for `MultipartError` ([#1861])\n- **fixed:** More clearly document what wildcards matches ([#1873])\n\n[#1861]: https://github.com/tokio-rs/axum/pull/1861\n[#1873]: https://github.com/tokio-rs/axum/pull/1873\n\n# 0.6.11 (13. March, 2023)\n\n- **fixed:** Don't require `S: Debug` for `impl Debug for Router<S>` ([#1836])\n- **fixed:** Clone state a bit less when handling requests ([#1837])\n- **fixed:** Unpin itoa dependency ([#1815])\n\n[#1815]: https://github.com/tokio-rs/axum/pull/1815\n[#1836]: https://github.com/tokio-rs/axum/pull/1836\n[#1837]: https://github.com/tokio-rs/axum/pull/1837\n\n# 0.6.10 (03. March, 2023)\n\n- **fixed:** Add `#[must_use]` attributes to types that do nothing unless used ([#1809])\n- **fixed:** Gracefully handle missing headers in the `TypedHeader` extractor ([#1810])\n- **fixed:** Fix routing issues when loading a `Router` via a dynamic library ([#1806])\n\n[#1806]: https://github.com/tokio-rs/axum/pull/1806\n[#1809]: https://github.com/tokio-rs/axum/pull/1809\n[#1810]: https://github.com/tokio-rs/axum/pull/1810\n\n# 0.6.9 (24. February, 2023)\n\n- **changed:** Update to tower-http 0.4. axum is still compatible with tower-http 0.3 ([#1783])\n\n[#1783]: https://github.com/tokio-rs/axum/pull/1783\n\n# 0.6.8 (24. February, 2023)\n\n- **fixed:** Fix `Allow` missing from routers with middleware ([#1773])\n- **added:** Add `KeepAlive::event` for customizing the event sent for SSE keep alive ([#1729])\n\n[#1729]: https://github.com/tokio-rs/axum/pull/1729\n[#1773]: https://github.com/tokio-rs/axum/pull/1773\n\n# 0.6.7 (17. February, 2023)\n\n- **added:** Add `FormRejection::FailedToDeserializeFormBody` which is returned\n  if the request body couldn't be deserialized into the target type, as opposed\n  to `FailedToDeserializeForm` which is only for query parameters ([#1683])\n- **added:** Add `MockConnectInfo` for setting `ConnectInfo` during tests ([#1767])\n\n[#1683]: https://github.com/tokio-rs/axum/pull/1683\n[#1767]: https://github.com/tokio-rs/axum/pull/1767\n\n# 0.6.6 (12. February, 2023)\n\n- **fixed:** Enable passing `MethodRouter` to `Router::fallback` ([#1730])\n\n[#1730]: https://github.com/tokio-rs/axum/pull/1730\n\n# 0.6.5 (11. February, 2023)\n\n- **fixed:** Fix `#[debug_handler]` sometimes giving wrong borrow related suggestions ([#1710])\n- Document gotchas related to using `impl IntoResponse` as the return type from handler functions ([#1736])\n\n[#1710]: https://github.com/tokio-rs/axum/pull/1710\n[#1736]: https://github.com/tokio-rs/axum/pull/1736\n\n# 0.6.4 (22. January, 2023)\n\n- Depend on axum-macros 0.3.2\n\n# 0.6.3 (20. January, 2023)\n\n- **added:** Implement `IntoResponse` for `&'static [u8; N]` and `[u8; N]` ([#1690])\n- **fixed:** Make `Path` support types using `serde::Deserializer::deserialize_any` ([#1693])\n- **added:** Add `RawPathParams` ([#1713])\n- **added:** Implement `Clone` and `Service` for `axum::middleware::Next` ([#1712])\n- **fixed:** Document required tokio features to run \"Hello, World!\" example ([#1715])\n\n[#1690]: https://github.com/tokio-rs/axum/pull/1690\n[#1693]: https://github.com/tokio-rs/axum/pull/1693\n[#1712]: https://github.com/tokio-rs/axum/pull/1712\n[#1713]: https://github.com/tokio-rs/axum/pull/1713\n[#1715]: https://github.com/tokio-rs/axum/pull/1715\n\n# 0.6.2 (9. January, 2023)\n\n- **added:** Add `body_text` and `status` methods to built-in rejections ([#1612])\n- **added:** Enable the `runtime` feature of `hyper` when using `tokio` ([#1671])\n\n[#1612]: https://github.com/tokio-rs/axum/pull/1612\n[#1671]: https://github.com/tokio-rs/axum/pull/1671\n\n# 0.6.1 (29. November, 2022)\n\n- **added:** Expand the docs for `Router::with_state` ([#1580])\n\n[#1580]: https://github.com/tokio-rs/axum/pull/1580\n\n# 0.6.0 (25. November, 2022)\n\n## Routing\n\n- **fixed:** Nested routers are now allowed to have fallbacks ([#1521]):\n\n  ```rust\n  let api_router = Router::new()\n      .route(\"/users\", get(|| { ... }))\n      .fallback(api_fallback);\n\n  let app = Router::new()\n      // this would panic in 0.5 but in 0.6 it just works\n      //\n      // requests starting with `/api` but not handled by `api_router`\n      // will go to `api_fallback`\n      .nest(\"/api\", api_router);\n  ```\n\n  The outer router's fallback will still apply if a nested router doesn't have\n  its own fallback:\n\n  ```rust\n  // this time without a fallback\n  let api_router = Router::new().route(\"/users\", get(|| { ... }));\n\n  let app = Router::new()\n      .nest(\"/api\", api_router)\n      // `api_router` will inherit this fallback\n      .fallback(app_fallback);\n  ```\n\n- **breaking:** The request `/foo/` no longer matches `/foo/*rest`. If you want\n  to match `/foo/` you have to add a route specifically for that ([#1086])\n\n  For example:\n\n  ```rust\n  use axum::{Router, routing::get, extract::Path};\n\n  let app = Router::new()\n      // this will match `/foo/bar/baz`\n      .route(\"/foo/*rest\", get(handler))\n      // this will match `/foo/`\n      .route(\"/foo/\", get(handler))\n      // if you want `/foo` to match you must also add an explicit route for it\n      .route(\"/foo\", get(handler));\n\n  async fn handler(\n      // use an `Option` because `/foo/` and `/foo` don't have any path params\n      params: Option<Path<String>>,\n  ) {}\n  ```\n\n- **breaking:** Path params for wildcard routes no longer include the prefix\n  `/`. e.g. `/foo.js` will match `/*filepath` with a value of `foo.js`, _not_\n  `/foo.js` ([#1086])\n\n  For example:\n\n  ```rust\n  use axum::{Router, routing::get, extract::Path};\n\n  let app = Router::new().route(\"/foo/*rest\", get(handler));\n\n  async fn handler(\n      Path(params): Path<String>,\n  ) {\n      // for the request `/foo/bar/baz` the value of `params` will be `bar/baz`\n      //\n      // on 0.5 it would be `/bar/baz`\n  }\n  ```\n\n- **fixed:** Routes like `/foo` and `/*rest` are no longer considered\n  overlapping. `/foo` will take priority ([#1086])\n\n  For example:\n\n  ```rust\n  use axum::{Router, routing::get};\n\n  let app = Router::new()\n      // this used to not be allowed but now just works\n      .route(\"/foo/*rest\", get(foo))\n      .route(\"/foo/bar\", get(bar));\n\n  async fn foo() {}\n\n  async fn bar() {}\n  ```\n\n- **breaking:** Automatic trailing slash redirects have been removed.\n  Previously if you added a route for `/foo`, axum would redirect calls to\n  `/foo/` to `/foo` (or vice versa for `/foo/`):\n\n  ```rust\n  use axum::{Router, routing::get};\n\n  let app = Router::new()\n      // a request to `GET /foo/` will now get `404 Not Found`\n      // whereas in 0.5 axum would redirect to `/foo`\n      //\n      // same goes the other way if you had the route `/foo/`\n      // axum will no longer redirect from `/foo` to `/foo/`\n      .route(\"/foo\", get(handler));\n\n  async fn handler() {}\n  ```\n\n  Either explicitly add routes for `/foo` and `/foo/` or use\n  `axum_extra::routing::RouterExt::route_with_tsr` if you want the old behavior\n  ([#1119])\n\n- **breaking:** `Router::fallback` now only accepts `Handler`s (similarly to\n  what `get`, `post`, etc. accept). Use the new `Router::fallback_service` for\n  setting any `Service` as the fallback ([#1155])\n\n  This fallback on 0.5:\n\n  ```rust\n  use axum::{Router, handler::Handler};\n\n  let app = Router::new().fallback(fallback.into_service());\n\n  async fn fallback() {}\n  ```\n\n  Becomes this in 0.6\n\n  ```rust\n  use axum::Router;\n\n  let app = Router::new().fallback(fallback);\n\n  async fn fallback() {}\n  ```\n\n- **breaking:** It is no longer supported to `nest` twice at the same path, i.e.\n  `.nest(\"/foo\", a).nest(\"/foo\", b)` will panic. Instead use `.nest(\"/foo\", a.merge(b))`\n- **breaking:** It is no longer supported to `nest` a router and add a route at\n  the same path, such as `.nest(\"/a\", _).route(\"/a\", _)`. Instead use\n  `.nest(\"/a/\", _).route(\"/a\", _)`.\n- **changed:** `Router::nest` now only accepts `Router`s, the general-purpose\n  `Service` nesting method has been renamed to `nest_service` ([#1368])\n- **breaking:** Allow `Error: Into<Infallible>` for `Route::{layer, route_layer}` ([#924])\n- **breaking:** `MethodRouter` now panics on overlapping routes ([#1102])\n- **breaking:** `Router::route` now only accepts `MethodRouter`s created with\n  `get`, `post`, etc. Use the new `Router::route_service` for routing to\n  any `Service`s ([#1155])\n- **breaking:** Adding a `.route_layer` onto a `Router` or `MethodRouter`\n  without any routes will now result in a panic. Previously, this just did\n  nothing. [#1327]\n- **breaking:** `RouterService` has been removed since `Router` now implements\n  `Service` when the state is `()`. Use `Router::with_state` to provide the\n  state and get a `Router<()>`. Note that `RouterService` only existed in the\n  pre-releases, not 0.5 ([#1552])\n\n## Extractors\n\n- **added:** Added new type safe `State` extractor. This can be used with\n  `Router::with_state` and gives compile errors for missing states, whereas\n  `Extension` would result in runtime errors ([#1155])\n\n  We recommend migrating from `Extension` to `State` for sharing application state since that is more type\n  safe and faster. That is done by using `Router::with_state` and `State`.\n\n  This setup in 0.5\n\n  ```rust\n  use axum::{routing::get, Extension, Router};\n\n  let app = Router::new()\n      .route(\"/\", get(handler))\n      .layer(Extension(AppState {}));\n\n  async fn handler(Extension(app_state): Extension<AppState>) {}\n\n  #[derive(Clone)]\n  struct AppState {}\n  ```\n\n  Becomes this in 0.6 using `State`:\n\n  ```rust\n  use axum::{routing::get, extract::State, Router};\n\n  let app = Router::new()\n      .route(\"/\", get(handler))\n      .with_state(AppState {});\n\n  async fn handler(State(app_state): State<AppState>) {}\n\n  #[derive(Clone)]\n  struct AppState {}\n  ```\n\n  If you have multiple extensions, you can use fields on `AppState` and implement\n  `FromRef`:\n\n  ```rust\n  use axum::{extract::{State, FromRef}, routing::get, Router};\n\n  let state = AppState {\n      client: HttpClient {},\n      database: Database {},\n  };\n\n  let app = Router::new().route(\"/\", get(handler)).with_state(state);\n\n  async fn handler(\n      State(client): State<HttpClient>,\n      State(database): State<Database>,\n  ) {}\n\n  // the derive requires enabling the \"macros\" feature\n  #[derive(Clone, FromRef)]\n  struct AppState {\n      client: HttpClient,\n      database: Database,\n  }\n\n  #[derive(Clone)]\n  struct HttpClient {}\n\n  #[derive(Clone)]\n  struct Database {}\n  ```\n\n- **breaking:** It is now only possible for one extractor per handler to consume\n  the request body. In 0.5 doing so would result in runtime errors but in 0.6 it\n  is a compile error ([#1272])\n\n  axum enforces this by only allowing the _last_ extractor to consume the\n  request.\n\n  For example:\n\n  ```rust\n  use axum::{Json, http::HeaderMap};\n\n  // This won't compile on 0.6 because both `Json` and `String` need to consume\n  // the request body. You can use either `Json` or `String`, but not both.\n  async fn handler_1(\n      json: Json<serde_json::Value>,\n      string: String,\n  ) {}\n\n  // This won't work either since `Json` is not the last extractor.\n  async fn handler_2(\n      json: Json<serde_json::Value>,\n      headers: HeaderMap,\n  ) {}\n\n  // This works!\n  async fn handler_3(\n      headers: HeaderMap,\n      json: Json<serde_json::Value>,\n  ) {}\n  ```\n\n  This is done by reworking the `FromRequest` trait and introducing a new\n  `FromRequestParts` trait.\n\n  If your extractor needs to consume the request body then you should implement\n  `FromRequest`, otherwise implement `FromRequestParts`.\n\n  This extractor in 0.5:\n\n  ```rust\n  struct MyExtractor { /* ... */ }\n\n  impl<B> FromRequest<B> for MyExtractor\n  where\n      B: Send,\n  {\n      type Rejection = StatusCode;\n\n      async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {\n          // ...\n      }\n  }\n  ```\n\n  Becomes this in 0.6:\n\n  ```rust\n  use axum::{\n      extract::{FromRequest, FromRequestParts},\n      http::{StatusCode, Request, request::Parts},\n  };\n\n  struct MyExtractor { /* ... */ }\n\n  // implement `FromRequestParts` if you don't need to consume the request body\n  impl<S> FromRequestParts<S> for MyExtractor\n  where\n      S: Send + Sync,\n  {\n      type Rejection = StatusCode;\n\n      async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n          // ...\n      }\n  }\n\n  // implement `FromRequest` if you do need to consume the request body\n  impl<S, B> FromRequest<S, B> for MyExtractor\n  where\n      S: Send + Sync,\n      B: Send + 'static,\n  {\n      type Rejection = StatusCode;\n\n      async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {\n          // ...\n      }\n  }\n  ```\n\n  For an example of how to write an extractor that accepts different\n  `Content-Types` see the [`parse-body-based-on-content-type`] example.\n\n- **added:** `FromRequest` and `FromRequestParts` derive macro re-exports from\n  [`axum-macros`] behind the `macros` feature ([#1352])\n- **added:** Add `RequestExt` and `RequestPartsExt` which adds convenience\n  methods for running extractors to `http::Request` and `http::request::Parts` ([#1301])\n- **added**: `JsonRejection` now displays the path at which a deserialization\n  error occurred ([#1371])\n- **added:** Add `extract::RawForm` for accessing raw urlencoded query bytes or request body ([#1487])\n- **fixed:** Used `400 Bad Request` for `FailedToDeserializeQueryString`\n  rejections, instead of `422 Unprocessable Entity` ([#1387])\n- **changed**: The inner error of a `JsonRejection` is now\n  `serde_path_to_error::Error<serde_json::Error>`.  Previously it was\n  `serde_json::Error` ([#1371])\n- **changed:** The default body limit now applies to the `Multipart` extractor ([#1420])\n- **breaking:** `ContentLengthLimit` has been removed. Use `DefaultBodyLimit` instead ([#1400])\n- **breaking:** `RequestParts` has been removed as part of the `FromRequest`\n  rework ([#1272])\n- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272])\n- **breaking:** The following types or traits have a new `S` type param\n  which represents the state ([#1155]):\n  - `Router`, defaults to `()`\n  - `MethodRouter`, defaults to `()`\n  - `FromRequest`, no default\n  - `Handler`, no default\n- **breaking:** `MatchedPath` can now no longer be extracted in middleware for\n  nested routes. In previous versions it returned invalid data when extracted\n  from a middleware applied to a nested router. `MatchedPath` can still be\n  extracted from handlers and middleware that aren't on nested routers ([#1462])\n- **breaking:** Rename `FormRejection::FailedToDeserializeQueryString` to\n  `FormRejection::FailedToDeserializeForm` ([#1496])\n\n## Middleware\n\n- **added:** Support running extractors on `middleware::from_fn` functions ([#1088])\n- **added**: Add `middleware::from_fn_with_state` to enable running extractors that require\n  state ([#1342])\n- **added:** Add `middleware::from_extractor_with_state` ([#1396])\n- **added:** Add `map_request`, `map_request_with_state` for transforming the\n  request with an async function ([#1408])\n- **added:** Add `map_response`, `map_response_with_state` for transforming the\n  response with an async function ([#1414])\n- **added:** Support any middleware response that implements `IntoResponse` ([#1152])\n- **breaking:** Remove `extractor_middleware` which was previously deprecated.\n  Use `axum::middleware::from_extractor` instead ([#1077])\n- **breaking:** Require middleware added with `Handler::layer` to have\n  `Infallible` as the error type ([#1152])\n\n## Misc\n\n- **added:** Support compiling to WASM. See the `simple-router-wasm` example\n  for more details ([#1382])\n- **added:** Add `ServiceExt` with methods for turning any `Service` into a\n  `MakeService` similarly to `Router::into_make_service` ([#1302])\n- **added:** String and binary `From` impls have been added to `extract::ws::Message`\n  to be more inline with `tungstenite` ([#1421])\n- **added:** Add `#[derive(axum::extract::FromRef)]` ([#1430])\n- **added:** Add `accept_unmasked_frames` setting in WebSocketUpgrade ([#1529])\n- **added:** Add `WebSocketUpgrade::on_failed_upgrade` to customize what to do\n  when upgrading a connection fails ([#1539])\n- **fixed:** Annotate panicking functions with `#[track_caller]` so the error\n  message points to where the user added the invalid route, rather than\n  somewhere internally in axum ([#1248])\n- **changed:** axum's MSRV is now 1.60 ([#1239])\n- **changed:** For methods that accept some `S: Service`, the bounds have been\n  relaxed so the response type must implement `IntoResponse` rather than being a\n  literal `Response`\n- **breaking:** New `tokio` default feature needed for WASM support. If you\n  don't need WASM support but have `default_features = false` for other reasons\n  you likely need to re-enable the `tokio` feature ([#1382])\n- **breaking:** `handler::{WithState, IntoService}` are merged into one type,\n  named `HandlerService` ([#1418])\n\n[#924]: https://github.com/tokio-rs/axum/pull/924\n[#1077]: https://github.com/tokio-rs/axum/pull/1077\n[#1086]: https://github.com/tokio-rs/axum/pull/1086\n[#1088]: https://github.com/tokio-rs/axum/pull/1088\n[#1102]: https://github.com/tokio-rs/axum/pull/1102\n[#1119]: https://github.com/tokio-rs/axum/pull/1119\n[#1152]: https://github.com/tokio-rs/axum/pull/1152\n[#1155]: https://github.com/tokio-rs/axum/pull/1155\n[#1239]: https://github.com/tokio-rs/axum/pull/1239\n[#1248]: https://github.com/tokio-rs/axum/pull/1248\n[#1272]: https://github.com/tokio-rs/axum/pull/1272\n[#1301]: https://github.com/tokio-rs/axum/pull/1301\n[#1302]: https://github.com/tokio-rs/axum/pull/1302\n[#1327]: https://github.com/tokio-rs/axum/pull/1327\n[#1342]: https://github.com/tokio-rs/axum/pull/1342\n[#1346]: https://github.com/tokio-rs/axum/pull/1346\n[#1352]: https://github.com/tokio-rs/axum/pull/1352\n[#1368]: https://github.com/tokio-rs/axum/pull/1368\n[#1371]: https://github.com/tokio-rs/axum/pull/1371\n[#1382]: https://github.com/tokio-rs/axum/pull/1382\n[#1387]: https://github.com/tokio-rs/axum/pull/1387\n[#1389]: https://github.com/tokio-rs/axum/pull/1389\n[#1396]: https://github.com/tokio-rs/axum/pull/1396\n[#1397]: https://github.com/tokio-rs/axum/pull/1397\n[#1400]: https://github.com/tokio-rs/axum/pull/1400\n[#1408]: https://github.com/tokio-rs/axum/pull/1408\n[#1414]: https://github.com/tokio-rs/axum/pull/1414\n[#1418]: https://github.com/tokio-rs/axum/pull/1418\n[#1420]: https://github.com/tokio-rs/axum/pull/1420\n[#1421]: https://github.com/tokio-rs/axum/pull/1421\n[#1430]: https://github.com/tokio-rs/axum/pull/1430\n[#1462]: https://github.com/tokio-rs/axum/pull/1462\n[#1487]: https://github.com/tokio-rs/axum/pull/1487\n[#1496]: https://github.com/tokio-rs/axum/pull/1496\n[#1521]: https://github.com/tokio-rs/axum/pull/1521\n[#1529]: https://github.com/tokio-rs/axum/pull/1529\n[#1532]: https://github.com/tokio-rs/axum/pull/1532\n[#1539]: https://github.com/tokio-rs/axum/pull/1539\n[#1552]: https://github.com/tokio-rs/axum/pull/1552\n[`axum-macros`]: https://docs.rs/axum-macros/latest/axum_macros/\n[`parse-body-based-on-content-type`]: https://github.com/tokio-rs/axum/blob/main/examples/parse-body-based-on-content-type/src/main.rs\n\n<details>\n<summary>0.6.0 Pre-Releases</summary>\n\n# 0.6.0-rc.5 (18. November, 2022)\n\n- **breaking:** `Router::with_state` is no longer a constructor. It is instead\n  used to convert the router into a `RouterService` ([#1532])\n\n  This nested router on 0.6.0-rc.4\n\n  ```rust\n  Router::with_state(state).route(...);\n  ```\n\n  Becomes this in 0.6.0-rc.5\n\n  ```rust\n  Router::new().route(...).with_state(state);\n  ```\n\n- **breaking:** `Router::inherit_state` has been removed. Use\n  `Router::with_state` instead ([#1532])\n- **breaking:** `Router::nest` and `Router::merge` now only supports nesting\n  routers that use the same state type as the router they're being merged into.\n  Use `FromRef` for substates ([#1532])\n\n- **added:** Add `accept_unmasked_frames` setting in WebSocketUpgrade ([#1529])\n- **fixed:** Nested routers will now inherit fallbacks from outer routers ([#1521])\n- **added:** Add `WebSocketUpgrade::on_failed_upgrade` to customize what to do\n  when upgrading a connection fails ([#1539])\n\n[#1521]: https://github.com/tokio-rs/axum/pull/1521\n[#1529]: https://github.com/tokio-rs/axum/pull/1529\n[#1532]: https://github.com/tokio-rs/axum/pull/1532\n[#1539]: https://github.com/tokio-rs/axum/pull/1539\n\n# 0.6.0-rc.4 (9. November, 2022)\n\n- **changed**: The inner error of a `JsonRejection` is now\n  `serde_path_to_error::Error<serde_json::Error>`.  Previously it was\n  `serde_json::Error` ([#1371])\n- **added**: `JsonRejection` now displays the path at which a deserialization\n  error occurred ([#1371])\n- **fixed:** Support streaming/chunked requests in `ContentLengthLimit` ([#1389])\n- **fixed:** Used `400 Bad Request` for `FailedToDeserializeQueryString`\n  rejections, instead of `422 Unprocessable Entity` ([#1387])\n- **added:** Add `middleware::from_extractor_with_state` ([#1396])\n- **added:** Add `DefaultBodyLimit::max` for changing the default body limit ([#1397])\n- **added:** Add `map_request`, `map_request_with_state` for transforming the\n  request with an async function ([#1408])\n- **added:** Add `map_response`, `map_response_with_state` for transforming the\n  response with an async function ([#1414])\n- **breaking:** `ContentLengthLimit` has been removed. Use `DefaultBodyLimit` instead ([#1400])\n- **changed:** `Router` no longer implements `Service`, call `.into_service()`\n  on it to obtain a `RouterService` that does ([#1368])\n- **added:** Add `Router::inherit_state`, which creates a `Router` with an\n  arbitrary state type without actually supplying the state; such a `Router`\n  can't be turned into a service directly (`.into_service()` will panic), but\n  can be nested or merged into a `Router` with the same state type ([#1368])\n- **changed:** `Router::nest` now only accepts `Router`s, the general-purpose\n  `Service` nesting method has been renamed to `nest_service` ([#1368])\n- **added:** Support compiling to WASM. See the `simple-router-wasm` example\n  for more details ([#1382])\n- **breaking:** New `tokio` default feature needed for WASM support. If you\n  don't need WASM support but have `default_features = false` for other reasons\n  you likely need to re-enable the `tokio` feature ([#1382])\n- **breaking:** `handler::{WithState, IntoService}` are merged into one type,\n  named `HandlerService` ([#1418])\n- **changed:** The default body limit now applies to the `Multipart` extractor ([#1420])\n- **added:** String and binary `From` impls have been added to `extract::ws::Message`\n  to be more inline with `tungstenite` ([#1421])\n- **added:** Add `#[derive(axum::extract::FromRef)]` ([#1430])\n- **added:** `FromRequest` and `FromRequestParts` derive macro re-exports from\n  [`axum-macros`] behind the `macros` feature ([#1352])\n- **breaking:** `MatchedPath` can now no longer be extracted in middleware for\n  nested routes ([#1462])\n- **added:** Add `extract::RawForm` for accessing raw urlencoded query bytes or request body ([#1487])\n- **breaking:** Rename `FormRejection::FailedToDeserializeQueryString` to\n  `FormRejection::FailedToDeserializeForm` ([#1496])\n\n[#1352]: https://github.com/tokio-rs/axum/pull/1352\n[#1368]: https://github.com/tokio-rs/axum/pull/1368\n[#1371]: https://github.com/tokio-rs/axum/pull/1371\n[#1382]: https://github.com/tokio-rs/axum/pull/1382\n[#1387]: https://github.com/tokio-rs/axum/pull/1387\n[#1389]: https://github.com/tokio-rs/axum/pull/1389\n[#1396]: https://github.com/tokio-rs/axum/pull/1396\n[#1397]: https://github.com/tokio-rs/axum/pull/1397\n[#1400]: https://github.com/tokio-rs/axum/pull/1400\n[#1408]: https://github.com/tokio-rs/axum/pull/1408\n[#1414]: https://github.com/tokio-rs/axum/pull/1414\n[#1418]: https://github.com/tokio-rs/axum/pull/1418\n[#1420]: https://github.com/tokio-rs/axum/pull/1420\n[#1421]: https://github.com/tokio-rs/axum/pull/1421\n[#1430]: https://github.com/tokio-rs/axum/pull/1430\n[#1462]: https://github.com/tokio-rs/axum/pull/1462\n[#1487]: https://github.com/tokio-rs/axum/pull/1487\n[#1496]: https://github.com/tokio-rs/axum/pull/1496\n\n# 0.6.0-rc.3 (8. November, 2022)\n\nYanked, as it didn't compile in release mode.\n\n# 0.6.0-rc.2 (10. September, 2022)\n\n## Security\n\n- **breaking:** Added default limit to how much data `Bytes::from_request` will\n  consume. Previously it would attempt to consume the entire request body\n  without checking its length. This meant if a malicious peer sent an large (or\n  infinite) request body your server might run out of memory and crash.\n\n  The default limit is at 2 MB and can be disabled by adding the new\n  `DefaultBodyLimit::disable()` middleware. See its documentation for more\n  details.\n\n  This also applies to these extractors which used `Bytes::from_request`\n  internally:\n  - `Form`\n  - `Json`\n  - `String`\n\n  ([#1346])\n\n## Routing\n\n- **breaking:** Adding a `.route_layer` onto a `Router` or `MethodRouter`\n  without any routes will now result in a panic. Previously, this just did\n  nothing. [#1327]\n\n\n[`axum-macros`]: https://docs.rs/axum-macros/latest/axum_macros/\n\n## Middleware\n\n- **added**: Add `middleware::from_fn_with_state` and\n  `middleware::from_fn_with_state_arc` to enable running extractors that require\n  state ([#1342])\n\n[#1327]: https://github.com/tokio-rs/axum/pull/1327\n[#1342]: https://github.com/tokio-rs/axum/pull/1342\n[#1346]: https://github.com/tokio-rs/axum/pull/1346\n\n# 0.6.0-rc.1 (23. August, 2022)\n\n## Routing\n\n- **breaking:** Nested `Router`s will no longer delegate to the outer `Router`'s\n  fallback. Instead you must explicitly set a fallback on the inner `Router` ([#1086])\n\n  This nested router on 0.5:\n\n  ```rust\n  use axum::{Router, handler::Handler};\n\n  let api_routes = Router::new();\n\n  let app = Router::new()\n      .nest(\"/api\", api_routes)\n      .fallback(fallback.into_service());\n\n  async fn fallback() {}\n  ```\n\n  Becomes this in 0.6:\n\n  ```rust\n  use axum::Router;\n\n  let api_routes = Router::new()\n      // we have to explicitly set the fallback here\n      // since nested routers no longer delegate to the outer\n      // router's fallback\n      .fallback(fallback);\n\n  let app = Router::new()\n      .nest(\"/api\", api_routes)\n      .fallback(fallback);\n\n  async fn fallback() {}\n  ```\n\n- **breaking:** The request `/foo/` no longer matches `/foo/*rest`. If you want\n  to match `/foo/` you have to add a route specifically for that ([#1086])\n\n  For example:\n\n  ```rust\n  use axum::{Router, routing::get, extract::Path};\n\n  let app = Router::new()\n      // this will match `/foo/bar/baz`\n      .route(\"/foo/*rest\", get(handler))\n      // this will match `/foo/`\n      .route(\"/foo/\", get(handler))\n      // if you want `/foo` to match you must also add an explicit route for it\n      .route(\"/foo\", get(handler));\n\n  async fn handler(\n      // use an `Option` because `/foo/` and `/foo` don't have any path params\n      params: Option<Path<String>>,\n  ) {}\n  ```\n\n- **breaking:** Path params for wildcard routes no longer include the prefix\n  `/`. e.g. `/foo.js` will match `/*filepath` with a value of `foo.js`, _not_\n  `/foo.js` ([#1086])\n\n  For example:\n\n  ```rust\n  use axum::{Router, routing::get, extract::Path};\n\n  let app = Router::new().route(\"/foo/*rest\", get(handler));\n\n  async fn handler(\n      Path(params): Path<String>,\n  ) {\n      // for the request `/foo/bar/baz` the value of `params` will be `bar/baz`\n      //\n      // on 0.5 it would be `/bar/baz`\n  }\n  ```\n\n- **fixed:** Routes like `/foo` and `/*rest` are no longer considered\n  overlapping. `/foo` will take priority ([#1086])\n\n  For example:\n\n  ```rust\n  use axum::{Router, routing::get};\n\n  let app = Router::new()\n      // this used to not be allowed but now just works\n      .route(\"/foo/*rest\", get(foo))\n      .route(\"/foo/bar\", get(bar));\n\n  async fn foo() {}\n\n  async fn bar() {}\n  ```\n\n- **breaking:** Trailing slash redirects have been removed. Previously if you\n  added a route for `/foo`, axum would redirect calls to `/foo/` to `/foo` (or\n  vice versa for `/foo/`). That is no longer supported and such requests will\n  now be sent to the fallback. Consider using\n  `axum_extra::routing::RouterExt::route_with_tsr` if you want the old behavior\n  ([#1119])\n\n  For example:\n\n  ```rust\n  use axum::{Router, routing::get};\n\n  let app = Router::new()\n      // a request to `GET /foo/` will now get `404 Not Found`\n      // whereas in 0.5 axum would redirect to `/foo`\n      //\n      // same goes the other way if you had the route `/foo/`\n      // axum will no longer redirect from `/foo` to `/foo/`\n      .route(\"/foo\", get(handler));\n\n  async fn handler() {}\n  ```\n\n- **breaking:** `Router::fallback` now only accepts `Handler`s (similarly to\n  what `get`, `post`, etc accept). Use the new `Router::fallback_service` for\n  setting any `Service` as the fallback ([#1155])\n\n  This fallback on 0.5:\n\n  ```rust\n  use axum::{Router, handler::Handler};\n\n  let app = Router::new().fallback(fallback.into_service());\n\n  async fn fallback() {}\n  ```\n\n  Becomes this in 0.6\n\n  ```rust\n  use axum::Router;\n\n  let app = Router::new().fallback(fallback);\n\n  async fn fallback() {}\n  ```\n\n- **breaking:** Allow `Error: Into<Infallible>` for `Route::{layer, route_layer}` ([#924])\n- **breaking:** `MethodRouter` now panics on overlapping routes ([#1102])\n- **breaking:** `Router::route` now only accepts `MethodRouter`s created with\n  `get`, `post`, etc. Use the new `Router::route_service` for routing to\n  any `Service`s ([#1155])\n\n## Extractors\n\n- **added:** Added new type safe `State` extractor. This can be used with\n  `Router::with_state` and gives compile errors for missing states, whereas\n  `Extension` would result in runtime errors ([#1155])\n\n  We recommend migrating from `Extension` to `State` since that is more type\n  safe and faster. That is done by using `Router::with_state` and `State`.\n\n  This setup in 0.5\n\n  ```rust\n  use axum::{routing::get, Extension, Router};\n\n  let app = Router::new()\n      .route(\"/\", get(handler))\n      .layer(Extension(AppState {}));\n\n  async fn handler(Extension(app_state): Extension<AppState>) {}\n\n  #[derive(Clone)]\n  struct AppState {}\n  ```\n\n  Becomes this in 0.6 using `State`:\n\n  ```rust\n  use axum::{routing::get, extract::State, Router};\n\n  let app = Router::with_state(AppState {})\n      .route(\"/\", get(handler));\n\n  async fn handler(State(app_state): State<AppState>) {}\n\n  #[derive(Clone)]\n  struct AppState {}\n  ```\n\n  If you have multiple extensions you can use fields on `AppState` and implement\n  `FromRef`:\n\n  ```rust\n  use axum::{extract::{State, FromRef}, routing::get, Router};\n\n  let state = AppState {\n      client: HttpClient {},\n      database: Database {},\n  };\n\n  let app = Router::with_state(state).route(\"/\", get(handler));\n\n  async fn handler(\n      State(client): State<HttpClient>,\n      State(database): State<Database>,\n  ) {}\n\n  #[derive(Clone)]\n  struct AppState {\n      client: HttpClient,\n      database: Database,\n  }\n\n  #[derive(Clone)]\n  struct HttpClient {}\n\n  impl FromRef<AppState> for HttpClient {\n      fn from_ref(state: &AppState) -> Self {\n          state.client.clone()\n      }\n  }\n\n  #[derive(Clone)]\n  struct Database {}\n\n  impl FromRef<AppState> for Database {\n      fn from_ref(state: &AppState) -> Self {\n          state.database.clone()\n      }\n  }\n  ```\n- **breaking:** It is now only possible for one extractor per handler to consume\n  the request body. In 0.5 doing so would result in runtime errors but in 0.6 it\n  is a compile error ([#1272])\n\n  axum enforces this by only allowing the _last_ extractor to consume the\n  request.\n\n  For example:\n\n  ```rust\n  use axum::{Json, http::HeaderMap};\n\n  // This won't compile on 0.6 because both `Json` and `String` need to consume\n  // the request body. You can use either `Json` or `String`, but not both.\n  async fn handler_1(\n      json: Json<serde_json::Value>,\n      string: String,\n  ) {}\n\n  // This won't work either since `Json` is not the last extractor.\n  async fn handler_2(\n      json: Json<serde_json::Value>,\n      headers: HeaderMap,\n  ) {}\n\n  // This works!\n  async fn handler_3(\n      headers: HeaderMap,\n      json: Json<serde_json::Value>,\n  ) {}\n  ```\n\n  This is done by reworking the `FromRequest` trait and introducing a new\n  `FromRequestParts` trait.\n\n  If your extractor needs to consume the request body then you should implement\n  `FromRequest`, otherwise implement `FromRequestParts`.\n\n  This extractor in 0.5:\n\n  ```rust\n  struct MyExtractor { /* ... */ }\n\n  impl<B> FromRequest<B> for MyExtractor\n  where\n      B: Send,\n  {\n      type Rejection = StatusCode;\n\n      async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {\n          // ...\n      }\n  }\n  ```\n\n  Becomes this in 0.6:\n\n  ```rust\n  use axum::{\n      extract::{FromRequest, FromRequestParts},\n      http::{StatusCode, Request, request::Parts},\n  };\n\n  struct MyExtractor { /* ... */ }\n\n  // implement `FromRequestParts` if you don't need to consume the request body\n  impl<S> FromRequestParts<S> for MyExtractor\n  where\n      S: Send + Sync,\n  {\n      type Rejection = StatusCode;\n\n      async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n          // ...\n      }\n  }\n\n  // implement `FromRequest` if you do need to consume the request body\n  impl<S, B> FromRequest<S, B> for MyExtractor\n  where\n      S: Send + Sync,\n      B: Send + 'static,\n  {\n      type Rejection = StatusCode;\n\n      async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {\n          // ...\n      }\n  }\n  ```\n\n- **breaking:** `RequestParts` has been removed as part of the `FromRequest`\n  rework ([#1272])\n- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272])\n- **breaking:** The following types or traits have a new `S` type param\n  which represents the state ([#1155]):\n  - `Router`, defaults to `()`\n  - `MethodRouter`, defaults to `()`\n  - `FromRequest`, no default\n  - `Handler`, no default\n- **added:** Add `RequestExt` and `RequestPartsExt` which adds convenience\n  methods for running extractors to `http::Request` and `http::request::Parts` ([#1301])\n\n## Middleware\n\n- **breaking:** Remove `extractor_middleware` which was previously deprecated.\n  Use `axum::middleware::from_extractor` instead ([#1077])\n- **added:** Support running extractors on `middleware::from_fn` functions ([#1088])\n- **added:** Support any middleware response that implements `IntoResponse` ([#1152])\n- **breaking:** Require middleware added with `Handler::layer` to have\n  `Infallible` as the error type ([#1152])\n\n## Misc\n\n- **changed:** axum's MSRV is now 1.60 ([#1239])\n- **changed:** For methods that accept some `S: Service`, the bounds have been\n  relaxed so the response type must implement `IntoResponse` rather than being a\n  literal `Response`\n- **fixed:** Annotate panicking functions with `#[track_caller]` so the error\n  message points to where the user added the invalid route, rather than\n  somewhere internally in axum ([#1248])\n- **added:** Add `ServiceExt` with methods for turning any `Service` into a\n  `MakeService` similarly to `Router::into_make_service` ([#1302])\n\n[#1077]: https://github.com/tokio-rs/axum/pull/1077\n[#1086]: https://github.com/tokio-rs/axum/pull/1086\n[#1088]: https://github.com/tokio-rs/axum/pull/1088\n[#1102]: https://github.com/tokio-rs/axum/pull/1102\n[#1119]: https://github.com/tokio-rs/axum/pull/1119\n[#1152]: https://github.com/tokio-rs/axum/pull/1152\n[#1155]: https://github.com/tokio-rs/axum/pull/1155\n[#1239]: https://github.com/tokio-rs/axum/pull/1239\n[#1248]: https://github.com/tokio-rs/axum/pull/1248\n[#1272]: https://github.com/tokio-rs/axum/pull/1272\n[#1301]: https://github.com/tokio-rs/axum/pull/1301\n[#1302]: https://github.com/tokio-rs/axum/pull/1302\n[#924]: https://github.com/tokio-rs/axum/pull/924\n\n</details>\n\n# 0.5.16 (10. September, 2022)\n\n## Security\n\n- **breaking:** Added default limit to how much data `Bytes::from_request` will\n  consume. Previously it would attempt to consume the entire request body\n  without checking its length. This meant if a malicious peer sent an large (or\n  infinite) request body your server might run out of memory and crash.\n\n  The default limit is at 2 MB and can be disabled by adding the new\n  `DefaultBodyLimit::disable()` middleware. See its documentation for more\n  details.\n\n  This also applies to these extractors which used `Bytes::from_request`\n  internally:\n  - `Form`\n  - `Json`\n  - `String`\n\n  ([#1346])\n\n[#1346]: https://github.com/tokio-rs/axum/pull/1346\n\n# 0.5.15 (9. August, 2022)\n\n- **fixed:** Don't expose internal type names in `QueryRejection` response. ([#1171])\n- **fixed:** Improve performance of JSON serialization ([#1178])\n- **fixed:** Improve build times by generating less IR ([#1192])\n\n[#1171]: https://github.com/tokio-rs/axum/pull/1171\n[#1178]: https://github.com/tokio-rs/axum/pull/1178\n[#1192]: https://github.com/tokio-rs/axum/pull/1192\n\n# 0.5.14 (25. July, 2022)\n\nYanked, as it contained an accidental breaking change.\n\n# 0.5.13 (15. July, 2022)\n\n- **fixed:** If `WebSocketUpgrade` cannot upgrade the connection it will return a\n  `WebSocketUpgradeRejection::ConnectionNotUpgradable` rejection ([#1135])\n- **changed:** `WebSocketUpgradeRejection` has a new variant `ConnectionNotUpgradable`\n  variant ([#1135])\n\n[#1135]: https://github.com/tokio-rs/axum/pull/1135\n\n# 0.5.12 (10. July, 2022)\n\n- **added:** Added `debug_handler` which is an attribute macro that improves\n  type errors when applied to handler function. It is re-exported from\n  `axum-macros` ([#1144])\n\n[#1144]: https://github.com/tokio-rs/axum/pull/1144\n\n# 0.5.11 (02. July, 2022)\n\n- **added:** Implement `TryFrom<http::Method>` for `MethodFilter` and use new\n  `NoMatchingMethodFilter` error in case of failure ([#1130])\n- **added:** Document how to run extractors from middleware ([#1140])\n\n[#1130]: https://github.com/tokio-rs/axum/pull/1130\n[#1140]: https://github.com/tokio-rs/axum/pull/1140\n\n# 0.5.10 (28. June, 2022)\n\n- **fixed:** Make `Router` cheaper to clone ([#1123])\n- **fixed:** Fix possible panic when doing trailing slash redirect ([#1124])\n\n[#1123]: https://github.com/tokio-rs/axum/pull/1123\n[#1124]: https://github.com/tokio-rs/axum/pull/1124\n\n# 0.5.9 (20. June, 2022)\n\n- **fixed:** Fix compile error when the `headers` is enabled and the `form`\n  feature is disabled ([#1107])\n\n[#1107]: https://github.com/tokio-rs/axum/pull/1107\n\n# 0.5.8 (18. June, 2022)\n\n- **added:** Support resolving host name via `Forwarded` header in `Host`\n  extractor ([#1078])\n- **added:** Implement `IntoResponse` for `Form` ([#1095])\n- **changed:** axum's MSRV is now 1.56 ([#1098])\n\n[#1078]: https://github.com/tokio-rs/axum/pull/1078\n[#1095]: https://github.com/tokio-rs/axum/pull/1095\n[#1098]: https://github.com/tokio-rs/axum/pull/1098\n\n# 0.5.7 (08. June, 2022)\n\n- **added:** Implement `Default` for `Extension` ([#1043])\n- **fixed:** Support deserializing `Vec<(String, String)>` in `extract::Path<_>` to get vector of\n  key/value pairs ([#1059])\n- **added:** Add `extract::ws::close_code` which contains constants for close codes ([#1067])\n- **fixed:** Use `impl IntoResponse` less in docs ([#1049])\n\n[#1043]: https://github.com/tokio-rs/axum/pull/1043\n[#1049]: https://github.com/tokio-rs/axum/pull/1049\n[#1059]: https://github.com/tokio-rs/axum/pull/1059\n[#1067]: https://github.com/tokio-rs/axum/pull/1067\n\n# 0.5.6 (15. May, 2022)\n\n- **added:** Add `WebSocket::protocol` to return the selected WebSocket subprotocol, if there is one. ([#1022])\n- **fixed:** Improve error message for `PathRejection::WrongNumberOfParameters` to hint at using\n  `Path<(String, String)>` or `Path<SomeStruct>` ([#1023])\n- **fixed:** `PathRejection::WrongNumberOfParameters` now uses `500 Internal Server Error` since\n  it's a programmer error and not a client error ([#1023])\n- **fixed:** Fix `InvalidFormContentType` mentioning the wrong content type\n\n[#1022]: https://github.com/tokio-rs/axum/pull/1022\n[#1023]: https://github.com/tokio-rs/axum/pull/1023\n\n# 0.5.5 (10. May, 2022)\n\n- **fixed:** Correctly handle `GET`, `HEAD`, and `OPTIONS` requests in `ContentLengthLimit`.\n  Request with these methods are now accepted if they _do not_ have a `Content-Length` header, and\n  the request body will not be checked. If they do have a `Content-Length` header they'll be\n  rejected. This allows `ContentLengthLimit` to be used as middleware around several routes,\n  including `GET` routes ([#989])\n- **added:** Add `MethodRouter::{into_make_service, into_make_service_with_connect_info}` ([#1010])\n\n[#989]: https://github.com/tokio-rs/axum/pull/989\n[#1010]: https://github.com/tokio-rs/axum/pull/1010\n\n# 0.5.4 (26. April, 2022)\n\n- **added:** Add `response::ErrorResponse` and `response::Result` for\n  `IntoResponse`-based error handling ([#921])\n- **added:** Add `middleware::from_extractor` and deprecate `extract::extractor_middleware` ([#957])\n- **changed:** Update to tower-http 0.3 ([#965])\n\n[#921]: https://github.com/tokio-rs/axum/pull/921\n[#957]: https://github.com/tokio-rs/axum/pull/957\n[#965]: https://github.com/tokio-rs/axum/pull/965\n\n# 0.5.3 (19. April, 2022)\n\n- **added:** Add `AppendHeaders` for appending headers to a response rather than overriding them ([#927])\n- **added:** Add `axum::extract::multipart::Field::chunk` method for streaming a single chunk from\n  the field ([#901])\n- **fixed:** Fix trailing slash redirection with query parameters ([#936])\n\n[#901]: https://github.com/tokio-rs/axum/pull/901\n[#927]: https://github.com/tokio-rs/axum/pull/927\n[#936]: https://github.com/tokio-rs/axum/pull/936\n\n# 0.5.2 (19. April, 2022)\n\nYanked, as it contained an accidental breaking change.\n\n# 0.5.1 (03. April, 2022)\n\n- **added:** Add `RequestParts::extract` which allows applying an extractor as a method call ([#897])\n\n[#897]: https://github.com/tokio-rs/axum/pull/897\n\n# 0.5.0 (31. March, 2022)\n\n- **added:** Document sharing state between handler and middleware ([#783])\n- **added:** `Extension<_>` can now be used in tuples for building responses, and will set an\n  extension on the response ([#797])\n- **added:** `extract::Host` for extracting the hostname of a request ([#827])\n- **added:** Add `IntoResponseParts` trait which allows defining custom response\n  types for adding headers or extensions to responses ([#797])\n- **added:** `TypedHeader` implements the new `IntoResponseParts` trait so they\n  can be returned from handlers as parts of a response ([#797])\n- **changed:** `Router::merge` now accepts `Into<Router>` ([#819])\n- **breaking:** `sse::Event` now accepts types implementing `AsRef<str>` instead of `Into<String>`\n  as field values.\n- **breaking:** `sse::Event` now panics if a setter method is called twice instead of silently\n  overwriting old values.\n- **breaking:** Require `Output = ()` on `WebSocketStream::on_upgrade` ([#644])\n- **breaking:** Make `TypedHeaderRejectionReason` `#[non_exhaustive]` ([#665])\n- **breaking:** Using `HeaderMap` as an extractor will no longer remove the headers and thus\n  they'll still be accessible to other extractors, such as `axum::extract::Json`. Instead\n  `HeaderMap` will clone the headers. You should prefer to use `TypedHeader` to extract only the\n  headers you need ([#698])\n\n  This includes these breaking changes:\n    - `RequestParts::take_headers` has been removed.\n    - `RequestParts::headers` returns `&HeaderMap`.\n    - `RequestParts::headers_mut` returns `&mut HeaderMap`.\n    - `HeadersAlreadyExtracted` has been removed.\n    - The `HeadersAlreadyExtracted` variant has been removed from these rejections:\n        - `RequestAlreadyExtracted`\n        - `RequestPartsAlreadyExtracted`\n        - `JsonRejection`\n        - `FormRejection`\n        - `ContentLengthLimitRejection`\n        - `WebSocketUpgradeRejection`\n    - `<HeaderMap as FromRequest<_>>::Rejection` has been changed to `std::convert::Infallible`.\n- **breaking:** `axum::http::Extensions` is no longer an extractor (ie it\n  doesn't implement `FromRequest`). The `axum::extract::Extension` extractor is\n  _not_ impacted by this and works the same. This change makes it harder to\n  accidentally remove all extensions which would result in confusing errors\n  elsewhere ([#699])\n  This includes these breaking changes:\n    - `RequestParts::take_extensions` has been removed.\n    - `RequestParts::extensions` returns `&Extensions`.\n    - `RequestParts::extensions_mut` returns `&mut Extensions`.\n    - `RequestAlreadyExtracted` has been removed.\n    - `<Request as FromRequest>::Rejection` is now `BodyAlreadyExtracted`.\n    - `<http::request::Parts as FromRequest>::Rejection` is now `Infallible`.\n    - `ExtensionsAlreadyExtracted` has been removed.\n    - The `ExtensionsAlreadyExtracted` removed variant has been removed from these rejections:\n        - `ExtensionRejection`\n        - `PathRejection`\n        - `MatchedPathRejection`\n        - `WebSocketUpgradeRejection`\n- **breaking:** `Redirect::found` has been removed ([#800])\n- **breaking:** `AddExtensionLayer` has been removed. Use `Extension` instead. It now implements\n  `tower::Layer` ([#807])\n- **breaking:** `AddExtension` has been moved from the root module to `middleware`\n- **breaking:** `.nest(\"/foo/\", Router::new().route(\"/bar\", _))` now does the right thing and\n  results in a route at `/foo/bar` instead of `/foo//bar` ([#824])\n- **breaking:** Routes are now required to start with `/`. Previously routes such as `:foo` would\n  be accepted but most likely result in bugs ([#823])\n- **breaking:** `Headers` has been removed. Arrays of tuples directly implement\n  `IntoResponseParts` so `([(\"x-foo\", \"foo\")], response)` now works ([#797])\n- **breaking:** `InvalidJsonBody` has been replaced with `JsonDataError` to clearly signal that the\n  request body was syntactically valid JSON but couldn't be deserialized into the target type\n- **breaking:** `Handler` is no longer an `#[async_trait]` but instead has an\n  associated `Future` type. That allows users to build their own `Handler` types\n  without paying the cost of `#[async_trait]` ([#879])\n- **changed:** New `JsonSyntaxError` variant added to `JsonRejection`. This is returned when the\n  request body contains syntactically invalid JSON\n- **fixed:** Correctly set the `Content-Length` header for response to `HEAD`\n  requests ([#734])\n- **fixed:** Fix wrong `content-length` for `HEAD` requests to endpoints that returns chunked\n  responses ([#755])\n- **fixed:** Fixed several routing bugs related to nested \"opaque\" tower services (i.e.\n  non-`Router` services) ([#841] and [#842])\n- **changed:** Update to tokio-tungstenite 0.17 ([#791])\n- **breaking:** `Redirect::{to, temporary, permanent}` now accept `&str` instead\n  of `Uri` ([#889])\n- **breaking:** Remove second type parameter from `Router::into_make_service_with_connect_info`\n  and `Handler::into_make_service_with_connect_info` to support `MakeService`s\n  that accept multiple targets ([#892])\n\n[#644]: https://github.com/tokio-rs/axum/pull/644\n[#665]: https://github.com/tokio-rs/axum/pull/665\n[#698]: https://github.com/tokio-rs/axum/pull/698\n[#699]: https://github.com/tokio-rs/axum/pull/699\n[#734]: https://github.com/tokio-rs/axum/pull/734\n[#755]: https://github.com/tokio-rs/axum/pull/755\n[#783]: https://github.com/tokio-rs/axum/pull/783\n[#791]: https://github.com/tokio-rs/axum/pull/791\n[#797]: https://github.com/tokio-rs/axum/pull/797\n[#800]: https://github.com/tokio-rs/axum/pull/800\n[#807]: https://github.com/tokio-rs/axum/pull/807\n[#819]: https://github.com/tokio-rs/axum/pull/819\n[#823]: https://github.com/tokio-rs/axum/pull/823\n[#824]: https://github.com/tokio-rs/axum/pull/824\n[#827]: https://github.com/tokio-rs/axum/pull/827\n[#841]: https://github.com/tokio-rs/axum/pull/841\n[#842]: https://github.com/tokio-rs/axum/pull/842\n[#879]: https://github.com/tokio-rs/axum/pull/879\n[#889]: https://github.com/tokio-rs/axum/pull/889\n[#892]: https://github.com/tokio-rs/axum/pull/892\n\n# 0.4.8 (2. March, 2022)\n\n- Use correct path for `AddExtensionLayer` and `AddExtension::layer` deprecation\n  notes ([#812])\n\n[#812]: https://github.com/tokio-rs/axum/pull/812\n\n# 0.4.7 (1. March, 2022)\n\n- **added:** Implement `tower::Layer` for `Extension` ([#801])\n- **changed:** Deprecate `AddExtensionLayer`. Use `Extension` instead ([#805])\n\n[#801]: https://github.com/tokio-rs/axum/pull/801\n[#805]: https://github.com/tokio-rs/axum/pull/805\n\n# 0.4.6 (22. February, 2022)\n\n- **added:** `middleware::from_fn` for creating middleware from async functions.\n  This previously lived in axum-extra but has been moved to axum ([#719])\n- **fixed:** Set `Allow` header when responding with `405 Method Not Allowed` ([#733])\n\n[#719]: https://github.com/tokio-rs/axum/pull/719\n[#733]: https://github.com/tokio-rs/axum/pull/733\n\n# 0.4.5 (31. January, 2022)\n\n- Reference [axum-macros] instead of [axum-debug]. The latter has been superseded by\n  axum-macros and is deprecated ([#738])\n\n[#738]: https://github.com/tokio-rs/axum/pull/738\n[axum-debug]: https://docs.rs/axum-debug\n[axum-macros]: https://docs.rs/axum-macros\n\n# 0.4.4 (13. January, 2022)\n\n- **fixed:** Fix using incorrect path prefix when nesting `Router`s at `/` ([#691])\n- **fixed:** Make `nest(\"\", service)` work and mean the same as `nest(\"/\", service)` ([#691])\n- **fixed:** Replace response code `301` with `308` for trailing slash redirects. Also deprecates\n  `Redirect::found` (`302`) in favor of `Redirect::temporary` (`307`) or `Redirect::to` (`303`).\n  This is to prevent clients from changing non-`GET` requests to `GET` requests ([#682])\n\n[#691]: https://github.com/tokio-rs/axum/pull/691\n[#682]: https://github.com/tokio-rs/axum/pull/682\n\n# 0.4.3 (21. December, 2021)\n\n- **added:** `axum::AddExtension::layer` ([#607])\n- **added:** Re-export the headers crate when the headers feature is active ([#630])\n- **fixed:** `sse::Event` will no longer drop the leading space of data, event ID and name values\n  that have it ([#600])\n- **fixed:** `sse::Event` is more strict about what field values it supports, disallowing any SSE\n  events that break the specification (such as field values containing carriage returns) ([#599])\n- **fixed:** Improve documentation of `sse::Event` ([#601])\n- **fixed:** Make `Path` fail with `ExtensionsAlreadyExtracted` if another extractor (such as\n  `Request`) has previously taken the request extensions. Thus `PathRejection` now contains a\n  variant with `ExtensionsAlreadyExtracted`. This is not a breaking change since `PathRejection` is\n  marked as `#[non_exhaustive]` ([#619])\n- **fixed:** Fix misleading error message for `PathRejection` if extensions had\n  previously been extracted ([#619])\n- **fixed:** Use `AtomicU32` internally, rather than `AtomicU64`, to improve portability ([#616])\n\n[#599]: https://github.com/tokio-rs/axum/pull/599\n[#600]: https://github.com/tokio-rs/axum/pull/600\n[#601]: https://github.com/tokio-rs/axum/pull/601\n[#607]: https://github.com/tokio-rs/axum/pull/607\n[#616]: https://github.com/tokio-rs/axum/pull/616\n[#619]: https://github.com/tokio-rs/axum/pull/619\n[#619]: https://github.com/tokio-rs/axum/pull/619\n[#630]: https://github.com/tokio-rs/axum/pull/630\n\n# 0.4.2 (06. December, 2021)\n\n- **fix:** Depend on the correct version of `axum-core` ([#592])\n\n[#592]: https://github.com/tokio-rs/axum/pull/592\n\n# 0.4.1 (06. December, 2021)\n\n- **added:** `axum::response::Response` now exists as a shorthand for writing `Response<BoxBody>` ([#590])\n\n[#590]: https://github.com/tokio-rs/axum/pull/590\n\n# 0.4.0 (02. December, 2021)\n\n- **breaking:** New `MethodRouter` that works similarly to `Router`:\n  - Route to handlers and services with the same type\n  - Add middleware to some routes more easily with `MethodRouter::layer` and\n    `MethodRouter::route_layer`.\n  - Merge method routers with `MethodRouter::merge`\n  - Customize response for unsupported methods with `MethodRouter::fallback`\n- **breaking:** The default for the type parameter in `FromRequest` and\n  `RequestParts` has been removed. Use `FromRequest<Body>` and\n  `RequestParts<Body>` to get the previous behavior ([#564])\n- **added:** `FromRequest` and `IntoResponse` are now defined in a new called\n  `axum-core`. This crate is intended for library authors to depend on, rather\n  than `axum` itself, if possible. `axum-core` has a smaller API and will thus\n  receive fewer breaking changes. `FromRequest` and `IntoResponse` are\n  re-exported from `axum` in the same location so nothing is changed for `axum`\n  users ([#564])\n- **breaking:** The previously deprecated `axum::body::box_body` function has\n  been removed. Use `axum::body::boxed` instead.\n- **fixed:** Adding the same route with different methods now works ie\n  `.route(\"/\", get(_)).route(\"/\", post(_))`.\n- **breaking:** `routing::handler_method_router` and\n  `routing::service_method_router` has been removed in favor of\n  `routing::{get, get_service, ..., MethodRouter}`.\n- **breaking:** `HandleErrorExt` has been removed in favor of\n  `MethodRouter::handle_error`.\n- **breaking:** `HandleErrorLayer` now requires the handler function to be\n  `async` ([#534])\n- **added:** `HandleErrorLayer` now supports running extractors.\n- **breaking:** The `Handler<B, T>` trait is now defined as `Handler<T, B =\n  Body>`. That is the type parameters have been swapped and `B` defaults to\n  `axum::body::Body` ([#527])\n- **breaking:** `Router::merge` will panic if both routers have fallbacks.\n  Previously the left side fallback would be silently discarded ([#529])\n- **breaking:** `Router::nest` will panic if the nested router has a fallback.\n  Previously it would be silently discarded ([#529])\n- Update WebSockets to use tokio-tungstenite 0.16 ([#525])\n- **added:** Default to return `charset=utf-8` for text content type. ([#554])\n- **breaking:** The `Body` and `BodyError` associated types on the\n  `IntoResponse` trait have been removed - instead, `.into_response()` will now\n  always return `Response<BoxBody>` ([#571])\n- **breaking:** `PathParamsRejection` has been renamed to `PathRejection` and its\n  variants renamed to `FailedToDeserializePathParams` and `MissingPathParams`. This\n  makes it more consistent with the rest of axum ([#574])\n- **added:** `Path`'s rejection type now provides data about exactly which part of\n  the path couldn't be deserialized ([#574])\n\n[#525]: https://github.com/tokio-rs/axum/pull/525\n[#527]: https://github.com/tokio-rs/axum/pull/527\n[#529]: https://github.com/tokio-rs/axum/pull/529\n[#534]: https://github.com/tokio-rs/axum/pull/534\n[#554]: https://github.com/tokio-rs/axum/pull/554\n[#564]: https://github.com/tokio-rs/axum/pull/564\n[#571]: https://github.com/tokio-rs/axum/pull/571\n[#574]: https://github.com/tokio-rs/axum/pull/574\n\n# 0.3.4 (13. November, 2021)\n\n- **changed:** `box_body` has been renamed to `boxed`. `box_body` still exists\n  but is deprecated ([#530])\n\n[#530]: https://github.com/tokio-rs/axum/pull/530\n\n# 0.3.3 (13. November, 2021)\n\n- Implement `FromRequest` for [`http::request::Parts`] so it can be used an\n  extractor ([#489])\n- Implement `IntoResponse` for `http::response::Parts` ([#490])\n\n[#489]: https://github.com/tokio-rs/axum/pull/489\n[#490]: https://github.com/tokio-rs/axum/pull/490\n[`http::request::Parts`]: https://docs.rs/http/latest/http/request/struct.Parts.html\n\n# 0.3.2 (08. November, 2021)\n\n- **added:** Add `Router::route_layer` for applying middleware that\n  will only run on requests that match a route. This is useful for middleware\n  that return early, such as authorization ([#474])\n\n[#474]: https://github.com/tokio-rs/axum/pull/474\n\n# 0.3.1 (06. November, 2021)\n\n- **fixed:** Implement `Clone` for `IntoMakeServiceWithConnectInfo` ([#471])\n\n[#471]: https://github.com/tokio-rs/axum/pull/471\n\n# 0.3.0 (02. November, 2021)\n\n- Overall:\n  - **fixed:** All known compile time issues are resolved, including those with\n    `boxed` and those introduced by Rust 1.56 ([#404])\n  - **breaking:** The router's type is now always `Router` regardless of how many routes or\n    middleware are applied ([#404])\n\n    This means router types are all always nameable:\n\n    ```rust\n    fn my_routes() -> Router {\n        Router::new().route(\n            \"/users\",\n            post(|| async { \"Hello, World!\" }),\n        )\n    }\n    ```\n  - **breaking:** Added feature flags for HTTP1 and JSON. This enables removing a\n    few dependencies if your app only uses HTTP2 or doesn't use JSON. This is only a\n    breaking change if you depend on axum with `default_features = false`. ([#286])\n  - **breaking:** `Route::boxed` and `BoxRoute` have been removed as they're no longer\n    necessary ([#404])\n  - **breaking:** `Nested`, `Or` types are now private. They no longer had to be\n    public because `Router` is internally boxed ([#404])\n  - **breaking:** Remove `routing::Layered` as it didn't actually do anything and\n    thus wasn't necessary\n  - **breaking:** Vendor `AddExtensionLayer` and `AddExtension` to reduce public\n    dependencies\n  - **breaking:** `body::BoxBody` is now a type alias for\n    `http_body::combinators::UnsyncBoxBody` and thus is no longer `Sync`. This\n    is because bodies are streams and requiring streams to be `Sync` is\n    unnecessary.\n  - **added:** Implement `IntoResponse` for `http_body::combinators::UnsyncBoxBody`.\n  - **added:** Add `Handler::into_make_service` for serving a handler without a\n    `Router`.\n  - **added:** Add `Handler::into_make_service_with_connect_info` for serving a\n    handler without a `Router`, and storing info about the incoming connection.\n  - **breaking:** axum's minimum supported rust version is now 1.56\n- Routing:\n  - Big internal refactoring of routing leading to several improvements ([#363])\n    - **added:** Wildcard routes like `.route(\"/api/users/*rest\", service)` are now supported.\n    - **fixed:** The order routes are added in no longer matters.\n    - **fixed:** Adding a conflicting route will now cause a panic instead of silently making\n      a route unreachable.\n    - **fixed:** Route matching is faster as number of routes increases.\n    - **breaking:** Handlers for multiple HTTP methods must be added in the same\n      `Router::route` call. So `.route(\"/\", get(get_handler).post(post_handler))` and\n      _not_ `.route(\"/\", get(get_handler)).route(\"/\", post(post_handler))`.\n  - **fixed:** Correctly handle trailing slashes in routes:\n    - If a route with a trailing slash exists and a request without a trailing\n      slash is received, axum will send a 301 redirection to the route with the\n      trailing slash.\n    - Or vice versa if a route without a trailing slash exists and a request\n      with a trailing slash is received.\n    - This can be overridden by explicitly defining two routes: One with and one\n      without a trailing slash.\n  - **breaking:** Method routing for handlers has been moved from `axum::handler`\n    to `axum::routing`. So `axum::handler::get` now lives at `axum::routing::get`\n    ([#405])\n  - **breaking:** Method routing for services has been moved from `axum::service`\n    to `axum::routing::service_method_routing`. So `axum::service::get` now lives at\n    `axum::routing::service_method_routing::get`, etc. ([#405])\n  - **breaking:** `Router::or` renamed to `Router::merge` and will now panic on\n    overlapping routes. It now only accepts `Router`s and not general `Service`s.\n    Use `Router::fallback` for adding fallback routes ([#408])\n  - **added:** `Router::fallback` for adding handlers for request that didn't\n    match any routes. `Router::fallback` must be use instead of `nest(\"/\", _)` ([#408])\n  - **breaking:** `EmptyRouter` has been renamed to `MethodNotAllowed` as it's only\n    used in method routers and not in path routers (`Router`)\n  - **breaking:** Remove support for routing based on the `CONNECT` method. An\n    example of combining axum with and HTTP proxy can be found [here][proxy] ([#428])\n- Extractors:\n  - **fixed:** Expand accepted content types for JSON requests ([#378])\n  - **fixed:** Support deserializing `i128` and `u128` in `extract::Path`\n  - **breaking:** Automatically do percent decoding in `extract::Path`\n    ([#272])\n  - **breaking:** Change `Connected::connect_info` to return `Self` and remove\n    the associated type `ConnectInfo` ([#396])\n  - **added:** Add `extract::MatchedPath` for accessing path in router that\n    matched the request ([#412])\n- Error handling:\n  - **breaking:** Simplify error handling model ([#402]):\n    - All services part of the router are now required to be infallible.\n    - Error handling utilities have been moved to an `error_handling` module.\n    - `Router::check_infallible` has been removed since routers are always\n      infallible with the error handling changes.\n    - Error handling closures must now handle all errors and thus always return\n      something that implements `IntoResponse`.\n\n    With these changes handling errors from fallible middleware is done like so:\n\n    ```rust,no_run\n    use axum::{\n        routing::get,\n        http::StatusCode,\n        error_handling::HandleErrorLayer,\n        response::IntoResponse,\n        Router, BoxError,\n    };\n    use tower::ServiceBuilder;\n    use std::time::Duration;\n\n    let middleware_stack = ServiceBuilder::new()\n        // Handle errors from middleware\n        //\n        // This middleware most be added above any fallible\n        // ones if you're using `ServiceBuilder`, due to how ordering works\n        .layer(HandleErrorLayer::new(handle_error))\n        // Return an error after 30 seconds\n        .timeout(Duration::from_secs(30));\n\n    let app = Router::new()\n        .route(\"/\", get(|| async { /* ... */ }))\n        .layer(middleware_stack);\n\n    fn handle_error(_error: BoxError) -> impl IntoResponse {\n        StatusCode::REQUEST_TIMEOUT\n    }\n    ```\n\n    And handling errors from fallible leaf services is done like so:\n\n    ```rust\n    use axum::{\n        Router, service,\n        body::Body,\n        routing::service_method_routing::get,\n        response::IntoResponse,\n        http::{Request, Response},\n        error_handling::HandleErrorExt, // for `.handle_error`\n    };\n    use std::{io, convert::Infallible};\n    use tower::service_fn;\n\n    let app = Router::new()\n        .route(\n            \"/\",\n            get(service_fn(|_req: Request<Body>| async {\n                let contents = tokio::fs::read_to_string(\"some_file\").await?;\n                Ok::<_, io::Error>(Response::new(Body::from(contents)))\n            }))\n            .handle_error(handle_io_error),\n        );\n\n    fn handle_io_error(error: io::Error) -> impl IntoResponse {\n        // ...\n    }\n    ```\n- Misc:\n  - `InvalidWebsocketVersionHeader` has been renamed to `InvalidWebSocketVersionHeader` ([#416])\n  - `WebsocketKeyHeaderMissing` has been renamed to `WebSocketKeyHeaderMissing` ([#416])\n\n[#339]: https://github.com/tokio-rs/axum/pull/339\n[#286]: https://github.com/tokio-rs/axum/pull/286\n[#272]: https://github.com/tokio-rs/axum/pull/272\n[#378]: https://github.com/tokio-rs/axum/pull/378\n[#363]: https://github.com/tokio-rs/axum/pull/363\n[#396]: https://github.com/tokio-rs/axum/pull/396\n[#402]: https://github.com/tokio-rs/axum/pull/402\n[#404]: https://github.com/tokio-rs/axum/pull/404\n[#405]: https://github.com/tokio-rs/axum/pull/405\n[#408]: https://github.com/tokio-rs/axum/pull/408\n[#412]: https://github.com/tokio-rs/axum/pull/412\n[#416]: https://github.com/tokio-rs/axum/pull/416\n[#428]: https://github.com/tokio-rs/axum/pull/428\n[proxy]: https://github.com/tokio-rs/axum/blob/main/examples/http-proxy/src/main.rs\n\n# 0.2.8 (07. October, 2021)\n\n- Document debugging handler type errors with \"axum-debug\" ([#372])\n\n[#372]: https://github.com/tokio-rs/axum/pull/372\n\n# 0.2.7 (06. October, 2021)\n\n- Bump minimum version of async-trait ([#370])\n\n[#370]: https://github.com/tokio-rs/axum/pull/370\n\n# 0.2.6 (02. October, 2021)\n\n- Clarify that `handler::any` and `service::any` only accepts standard HTTP\n  methods ([#337])\n- Document how to customize error responses from extractors ([#359])\n\n[#337]: https://github.com/tokio-rs/axum/pull/337\n[#359]: https://github.com/tokio-rs/axum/pull/359\n\n# 0.2.5 (18. September, 2021)\n\n- Add accessors for `TypedHeaderRejection` fields ([#317])\n- Improve docs for extractors ([#327])\n\n[#317]: https://github.com/tokio-rs/axum/pull/317\n[#327]: https://github.com/tokio-rs/axum/pull/327\n\n# 0.2.4 (10. September, 2021)\n\n- Document using `StreamExt::split` with `WebSocket` ([#291])\n- Document adding middleware to multiple groups of routes ([#293])\n\n[#291]: https://github.com/tokio-rs/axum/pull/291\n[#293]: https://github.com/tokio-rs/axum/pull/293\n\n# 0.2.3 (26. August, 2021)\n\n- **fixed:** Fix accidental breaking change introduced by internal refactor.\n  `BoxRoute` used to be `Sync` but was accidental made `!Sync` ([#273](https://github.com/tokio-rs/axum/pull/273))\n\n# 0.2.2 (26. August, 2021)\n\n- **fixed:** Fix URI captures matching empty segments. This means requests with\n  URI `/` will no longer be matched by `/:key` ([#264](https://github.com/tokio-rs/axum/pull/264))\n- **fixed:** Remove needless trait bounds from `Router::boxed` ([#269](https://github.com/tokio-rs/axum/pull/269))\n\n# 0.2.1 (24. August, 2021)\n\n- **added:** Add `Redirect::to` constructor ([#255](https://github.com/tokio-rs/axum/pull/255))\n- **added:** Document how to implement `IntoResponse` for custom error type ([#258](https://github.com/tokio-rs/axum/pull/258))\n\n# 0.2.0 (23. August, 2021)\n\n- Overall:\n  - **fixed:** Overall compile time improvements. If you're having issues with compile time\n    please file an issue! ([#184](https://github.com/tokio-rs/axum/pull/184)) ([#198](https://github.com/tokio-rs/axum/pull/198)) ([#220](https://github.com/tokio-rs/axum/pull/220))\n  - **changed:** Remove `prelude`. Explicit imports are now required ([#195](https://github.com/tokio-rs/axum/pull/195))\n- Routing:\n  - **added:** Add dedicated `Router` to replace the `RoutingDsl` trait ([#214](https://github.com/tokio-rs/axum/pull/214))\n  - **added:** Add `Router::or` for combining routes ([#108](https://github.com/tokio-rs/axum/pull/108))\n  - **fixed:** Support matching different HTTP methods for the same route that aren't defined\n    together. So `Router::new().route(\"/\", get(...)).route(\"/\", post(...))` now\n    accepts both `GET` and `POST`. Previously only `POST` would be accepted ([#224](https://github.com/tokio-rs/axum/pull/224))\n  - **fixed:** `get` routes will now also be called for `HEAD` requests but will always have\n    the response body removed ([#129](https://github.com/tokio-rs/axum/pull/129))\n  - **changed:** Replace `axum::route(...)` with `axum::Router::new().route(...)`. This means\n    there is now only one way to create a new router. Same goes for\n    `axum::routing::nest`. ([#215](https://github.com/tokio-rs/axum/pull/215))\n  - **changed:** Implement `routing::MethodFilter` via [`bitflags`](https://crates.io/crates/bitflags) ([#158](https://github.com/tokio-rs/axum/pull/158))\n  - **changed:** Move `handle_error` from `ServiceExt` to `service::OnMethod` ([#160](https://github.com/tokio-rs/axum/pull/160))\n\n  With these changes this app using 0.1:\n\n  ```rust\n  use axum::{extract::Extension, prelude::*, routing::BoxRoute, AddExtensionLayer};\n\n  let app = route(\"/\", get(|| async { \"hi\" }))\n      .nest(\"/api\", api_routes())\n      .layer(AddExtensionLayer::new(state));\n\n  fn api_routes() -> BoxRoute<Body> {\n      route(\n          \"/users\",\n          post(|Extension(state): Extension<State>| async { \"hi from nested\" }),\n      )\n      .boxed()\n  }\n  ```\n\n  Becomes this in 0.2:\n\n  ```rust\n  use axum::{\n      extract::Extension,\n      handler::{get, post},\n      routing::BoxRoute,\n      Router,\n  };\n\n  let app = Router::new()\n      .route(\"/\", get(|| async { \"hi\" }))\n      .nest(\"/api\", api_routes());\n\n  fn api_routes() -> Router<BoxRoute> {\n      Router::new()\n          .route(\n              \"/users\",\n              post(|Extension(state): Extension<State>| async { \"hi from nested\" }),\n          )\n          .boxed()\n  }\n  ```\n- Extractors:\n  - **added:** Make `FromRequest` default to being generic over `body::Body` ([#146](https://github.com/tokio-rs/axum/pull/146))\n  - **added:** Implement `std::error::Error` for all rejections ([#153](https://github.com/tokio-rs/axum/pull/153))\n  - **added:** Add `OriginalUri` for extracting original request URI in nested services ([#197](https://github.com/tokio-rs/axum/pull/197))\n  - **added:** Implement `FromRequest` for `http::Extensions` ([#169](https://github.com/tokio-rs/axum/pull/169))\n  - **added:** Make `RequestParts::{new, try_into_request}` public so extractors can be used outside axum ([#194](https://github.com/tokio-rs/axum/pull/194))\n  - **added:** Implement `FromRequest` for `axum::body::Body` ([#241](https://github.com/tokio-rs/axum/pull/241))\n  - **changed:** Removed `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#154](https://github.com/tokio-rs/axum/pull/154))\n  - **changed:** `extractor_middleware` now requires `RequestBody: Default` ([#167](https://github.com/tokio-rs/axum/pull/167))\n  - **changed:** Convert `RequestAlreadyExtracted` to an enum with each possible error variant ([#167](https://github.com/tokio-rs/axum/pull/167))\n  - **changed:** `extract::BodyStream` is no longer generic over the request body ([#234](https://github.com/tokio-rs/axum/pull/234))\n  - **changed:** `extract::Body` has been renamed to `extract::RawBody` to avoid conflicting with `body::Body` ([#233](https://github.com/tokio-rs/axum/pull/233))\n  - **changed:** `RequestParts` changes ([#153](https://github.com/tokio-rs/axum/pull/153))\n      - `method` new returns an `&http::Method`\n      - `method_mut` new returns an `&mut http::Method`\n      - `take_method` has been removed\n      - `uri` new returns an `&http::Uri`\n      - `uri_mut` new returns an `&mut http::Uri`\n      - `take_uri` has been removed\n  - **changed:** Remove several rejection types that were no longer used ([#153](https://github.com/tokio-rs/axum/pull/153)) ([#154](https://github.com/tokio-rs/axum/pull/154))\n- Responses:\n  - **added:** Add `Headers` for easily customizing headers on a response ([#193](https://github.com/tokio-rs/axum/pull/193))\n  - **added:** Add `Redirect` response ([#192](https://github.com/tokio-rs/axum/pull/192))\n  - **added:** Add `body::StreamBody` for easily responding with a stream of byte chunks ([#237](https://github.com/tokio-rs/axum/pull/237))\n  - **changed:** Add associated `Body` and `BodyError` types to `IntoResponse`. This is\n    required for returning responses with bodies other than `hyper::Body` from\n    handlers. See the docs for advice on how to implement `IntoResponse` ([#86](https://github.com/tokio-rs/axum/pull/86))\n  - **changed:** `tower::util::Either` no longer implements `IntoResponse` ([#229](https://github.com/tokio-rs/axum/pull/229))\n\n  This `IntoResponse` from 0.1:\n  ```rust\n  use axum::{http::Response, prelude::*, response::IntoResponse};\n\n  struct MyResponse;\n\n  impl IntoResponse for MyResponse {\n      fn into_response(self) -> Response<Body> {\n          Response::new(Body::empty())\n      }\n  }\n  ```\n\n  Becomes this in 0.2:\n  ```rust\n  use axum::{body::Body, http::Response, response::IntoResponse};\n\n  struct MyResponse;\n\n  impl IntoResponse for MyResponse {\n      type Body = Body;\n      type BodyError = <Self::Body as axum::body::HttpBody>::Error;\n\n      fn into_response(self) -> Response<Self::Body> {\n          Response::new(Body::empty())\n      }\n  }\n  ```\n- SSE:\n  - **added:** Add `response::sse::Sse`. This implements SSE using a response rather than a service ([#98](https://github.com/tokio-rs/axum/pull/98))\n  - **changed:** Remove `axum::sse`. It has been replaced by `axum::response::sse` ([#98](https://github.com/tokio-rs/axum/pull/98))\n\n  Handler using SSE in 0.1:\n  ```rust\n  use axum::{\n      prelude::*,\n      sse::{sse, Event},\n  };\n  use std::convert::Infallible;\n\n  let app = route(\n      \"/\",\n      sse(|| async {\n          let stream = futures::stream::iter(vec![Ok::<_, Infallible>(\n              Event::default().data(\"hi there!\"),\n          )]);\n          Ok::<_, Infallible>(stream)\n      }),\n  );\n  ```\n\n  Becomes this in 0.2:\n\n  ```rust\n  use axum::{\n      handler::get,\n      response::sse::{Event, Sse},\n      Router,\n  };\n  use std::convert::Infallible;\n\n  let app = Router::new().route(\n      \"/\",\n      get(|| async {\n          let stream = futures::stream::iter(vec![Ok::<_, Infallible>(\n              Event::default().data(\"hi there!\"),\n          )]);\n          Sse::new(stream)\n      }),\n  );\n  ```\n- WebSockets:\n  - **changed:** Change WebSocket API to use an extractor plus a response ([#121](https://github.com/tokio-rs/axum/pull/121))\n  - **changed:** Make WebSocket `Message` an enum ([#116](https://github.com/tokio-rs/axum/pull/116))\n  - **changed:** `WebSocket` now uses `Error` as its error type ([#150](https://github.com/tokio-rs/axum/pull/150))\n\n  Handler using WebSockets in 0.1:\n\n  ```rust\n  use axum::{\n      prelude::*,\n      ws::{ws, WebSocket},\n  };\n\n  let app = route(\n      \"/\",\n      ws(|socket: WebSocket| async move {\n          // do stuff with socket\n      }),\n  );\n  ```\n\n  Becomes this in 0.2:\n\n  ```rust\n  use axum::{\n      extract::ws::{WebSocket, WebSocketUpgrade},\n      handler::get,\n      Router,\n  };\n\n  let app = Router::new().route(\n      \"/\",\n      get(|ws: WebSocketUpgrade| async move {\n          ws.on_upgrade(|socket: WebSocket| async move {\n              // do stuff with socket\n          })\n      }),\n  );\n  ```\n- Misc\n  - **added:** Add default feature `tower-log` which exposes `tower`'s `log` feature. ([#218](https://github.com/tokio-rs/axum/pull/218))\n  - **changed:** Replace `body::BoxStdError` with `axum::Error`, which supports downcasting ([#150](https://github.com/tokio-rs/axum/pull/150))\n  - **changed:** `EmptyRouter` now requires the response body to implement `Send + Sync + 'static'` ([#108](https://github.com/tokio-rs/axum/pull/108))\n  - **changed:** `Router::check_infallible` now returns a `CheckInfallible` service. This\n    is to improve compile times ([#198](https://github.com/tokio-rs/axum/pull/198))\n  - **changed:** `Router::into_make_service` now returns `routing::IntoMakeService` rather than\n    `tower::make::Shared` ([#229](https://github.com/tokio-rs/axum/pull/229))\n  - **changed:** All usage of `tower::BoxError` has been replaced with `axum::BoxError` ([#229](https://github.com/tokio-rs/axum/pull/229))\n  - **changed:** Several response future types have been moved into dedicated\n    `future` modules ([#133](https://github.com/tokio-rs/axum/pull/133))\n  - **changed:** `EmptyRouter`, `ExtractorMiddleware`, `ExtractorMiddlewareLayer`,\n    and `QueryStringMissing` no longer implement `Copy` ([#132](https://github.com/tokio-rs/axum/pull/132))\n  - **changed:** `service::OnMethod`, `handler::OnMethod`, and `routing::Nested` have new response future types ([#157](https://github.com/tokio-rs/axum/pull/157))\n\n# 0.1.3 (06. August, 2021)\n\n- Fix stripping prefix when nesting services at `/` ([#91](https://github.com/tokio-rs/axum/pull/91))\n- Add support for WebSocket protocol negotiation ([#83](https://github.com/tokio-rs/axum/pull/83))\n- Use `pin-project-lite` instead of `pin-project` ([#95](https://github.com/tokio-rs/axum/pull/95))\n- Re-export `http` crate and `hyper::Server` ([#110](https://github.com/tokio-rs/axum/pull/110))\n- Fix `Query` and `Form` extractors giving bad request error when query string is empty. ([#117](https://github.com/tokio-rs/axum/pull/117))\n- Add `Path` extractor. ([#124](https://github.com/tokio-rs/axum/pull/124))\n- Fixed the implementation of `IntoResponse` of `(HeaderMap, T)` and `(StatusCode, HeaderMap, T)` would ignore headers from `T` ([#137](https://github.com/tokio-rs/axum/pull/137))\n- Deprecate `extract::UrlParams` and `extract::UrlParamsMap`. Use `extract::Path` instead ([#138](https://github.com/tokio-rs/axum/pull/138))\n\n# 0.1.2 (01. August, 2021)\n\n- Implement `Stream` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52))\n- Implement `Sink` for `WebSocket` ([#52](https://github.com/tokio-rs/axum/pull/52))\n- Implement `Deref` most extractors ([#56](https://github.com/tokio-rs/axum/pull/56))\n- Return `405 Method Not Allowed` for unsupported method for route ([#63](https://github.com/tokio-rs/axum/pull/63))\n- Add extractor for remote connection info ([#55](https://github.com/tokio-rs/axum/pull/55))\n- Improve error message of `MissingExtension` rejections ([#72](https://github.com/tokio-rs/axum/pull/72))\n- Improve documentation for routing ([#71](https://github.com/tokio-rs/axum/pull/71))\n- Clarify required response body type when routing to `tower::Service`s ([#69](https://github.com/tokio-rs/axum/pull/69))\n- Add `axum::body::box_body` to converting an `http_body::Body` to `axum::body::BoxBody` ([#69](https://github.com/tokio-rs/axum/pull/69))\n- Add `axum::sse` for Server-Sent Events ([#75](https://github.com/tokio-rs/axum/pull/75))\n- Mention required dependencies in docs ([#77](https://github.com/tokio-rs/axum/pull/77))\n- Fix WebSockets failing on Firefox ([#76](https://github.com/tokio-rs/axum/pull/76))\n\n# 0.1.1 (30. July, 2021)\n\n- Misc readme fixes.\n\n# 0.1.0 (30. July, 2021)\n\n- Initial release.\n"
  },
  {
    "path": "axum/Cargo.toml",
    "content": "[package]\nname = \"axum\"\nversion = \"0.8.8\" # remember to bump the version that axum-extra depends on\ncategories = [\"asynchronous\", \"network-programming\", \"web-programming::http-server\"]\ndescription = \"HTTP routing and request handling library that focuses on ergonomics and modularity\"\nedition = \"2021\"\nrust-version = { workspace = true }\nhomepage = \"https://github.com/tokio-rs/axum\"\nkeywords = [\"http\", \"web\", \"routing\"]\nlicense = \"MIT\"\nreadme = \"README.md\"\nrepository = \"https://github.com/tokio-rs/axum\"\n\n[package.metadata.docs.rs]\nall-features = true\n\n[package.metadata.playground]\nfeatures = [\"http1\", \"http2\", \"json\", \"multipart\", \"ws\"]\n\n[package.metadata.cargo_check_external_types]\nallowed_external_types = [\n    # our crates\n    \"axum_core::*\",\n    \"axum_macros::*\",\n    # not 1.0\n    \"futures_core::*\",\n    \"futures_sink::*\",\n    \"futures_util::*\",\n    \"tower_layer::*\",\n    \"tower_service::*\",\n    # >=1.0\n    \"bytes::*\",\n    \"http\",\n    \"http::*\",\n    \"http_body::*\",\n    \"serde_core::*\",\n    \"tokio::*\",\n]\n\n[features]\ndefault = [\n    \"form\",\n    \"http1\",\n    \"json\",\n    \"matched-path\",\n    \"original-uri\",\n    \"query\",\n    \"tokio\",\n    \"tower-log\",\n    \"tracing\",\n]\nform = [\n    \"dep:form_urlencoded\",\n    \"dep:serde_html_form\",\n    \"dep:serde_path_to_error\",\n    \"serde_html_form/ser\",\n    \"serde_html_form/de\",\n]\nhttp1 = [\"dep:hyper\", \"hyper?/http1\", \"hyper-util?/http1\"]\nhttp2 = [\"dep:hyper\", \"hyper?/http2\", \"hyper-util?/http2\"]\njson = [\"dep:serde_json\", \"dep:serde_path_to_error\"]\nmacros = [\"dep:axum-macros\"]\nmatched-path = []\nmultipart = [\"dep:multer\"]\noriginal-uri = []\nquery = [\n    \"dep:form_urlencoded\",\n    \"dep:serde_html_form\",\n    \"dep:serde_path_to_error\",\n    \"serde_html_form/de\",\n]\ntokio = [\n    \"dep:hyper-util\",\n    \"dep:tokio\",\n    \"tokio/net\",\n    \"tokio/rt\",\n    \"tower/make\",\n    \"tokio/macros\",\n]\ntower-log = [\"tower/log\"]\ntracing = [\"dep:tracing\", \"axum-core/tracing\"]\nws = [\n    \"dep:hyper\",\n    \"dep:futures-sink\",\n    \"tokio\",\n    \"dep:tokio-tungstenite\",\n    \"dep:sha1\",\n    \"dep:base64\",\n]\n\n__private_docs = [\n    # We re-export some docs from axum-core via #[doc(inline)],\n    # but they need the same sort of treatment as below to be complete\n    \"axum-core/__private_docs\",\n    # Enables upstream things linked to in docs\n    \"tower/full\",\n    \"dep:serde\",\n    \"dep:tower-http\",\n]\n\n# This feature is used to enable private test helper usage\n# in `axum-core` and `axum-extra`.\n__private = [\"tokio\", \"http1\", \"dep:reqwest\"]\n\n[dependencies]\naxum-core = { path = \"../axum-core\", version = \"0.5.6\" }\nbytes = \"1.7\"\nfutures-core = \"0.3\"\nfutures-util = { version = \"0.3\", default-features = false, features = [\"alloc\"] }\nhttp = \"1.0.0\"\nhttp-body = \"1.0.0\"\nhttp-body-util = \"0.1.0\"\nitoa = \"1.0.5\"\nmatchit = \"=0.8.4\"\nmemchr = \"2.4.1\"\nmime = \"0.3.16\"\npercent-encoding = \"2.1\"\npin-project-lite = \"0.2.7\"\nserde_core = \"1.0.221\"\nsync_wrapper = \"1.0.0\"\ntower = { version = \"0.5.2\", default-features = false, features = [\"util\"] }\ntower-layer = \"0.3.2\"\ntower-service = \"0.3\"\n\n# optional dependencies\naxum-macros = { path = \"../axum-macros\", version = \"0.5.0\", optional = true }\nbase64 = { version = \"0.22.1\", optional = true }\nform_urlencoded = { version = \"1.1.0\", optional = true }\nfutures-sink = { version = \"0.3\", optional = true }\nhyper = { version = \"1.4.0\", optional = true }\nhyper-util = { version = \"0.1.4\", features = [\"tokio\", \"server\", \"service\"], optional = true }\nmulter = { version = \"3.0.0\", optional = true }\nreqwest = { version = \"0.12\", optional = true, default-features = false, features = [\"json\", \"stream\", \"multipart\"] }\nserde_html_form = { version = \"0.4.0\", optional = true, default-features = false, features = [\"std\"] }\nserde_json = { version = \"1.0.29\", features = [\"raw_value\"], optional = true }\nserde_path_to_error = { version = \"0.1.8\", optional = true }\nsha1 = { version = \"0.10\", optional = true }\ntokio = { package = \"tokio\", version = \"1.44\", features = [\"time\"], optional = true }\ntokio-tungstenite = { version = \"0.29.0\", optional = true }\ntracing = { version = \"0.1\", default-features = false, optional = true }\n\n# doc dependencies\nserde = { version = \"1.0.211\", optional = true }\n\n[dependencies.tower-http]\nversion = \"0.6.8\"\noptional = true\nfeatures = [\n    # all tower-http features except (de)?compression-zstd which doesn't\n    # build on `--target armv5te-unknown-linux-musleabi`\n    \"add-extension\",\n    \"auth\",\n    \"catch-panic\",\n    \"compression-br\",\n    \"compression-deflate\",\n    \"compression-gzip\",\n    \"cors\",\n    \"decompression-br\",\n    \"decompression-deflate\",\n    \"decompression-gzip\",\n    \"follow-redirect\",\n    \"fs\",\n    \"limit\",\n    \"map-request-body\",\n    \"map-response-body\",\n    \"metrics\",\n    \"normalize-path\",\n    \"propagate-header\",\n    \"redirect\",\n    \"request-id\",\n    \"sensitive-headers\",\n    \"set-header\",\n    \"set-status\",\n    \"timeout\",\n    \"trace\",\n    \"util\",\n    \"validate-request\",\n]\n\n[dev-dependencies]\nanyhow = \"1.0\"\naxum-extra = { path = \"../axum-extra\", features = [\"typed-header\"] }\naxum-macros = { path = \"../axum-macros\", features = [\"__private\"] }\nhyper = { version = \"1.1.0\", features = [\"client\"] }\nquickcheck = \"1.0\"\nquickcheck_macros = \"1.0\"\nreqwest = { version = \"0.12\", default-features = false, features = [\"json\", \"stream\", \"multipart\"] }\nserde = { version = \"1.0.221\", features = [\"derive\"] }\nserde_json = { version = \"1.0.29\", features = [\"raw_value\"] }\ntime = { version = \"0.3\", features = [\"serde-human-readable\"] }\ntokio = { package = \"tokio\", version = \"1.44.2\", features = [\"macros\", \"rt\", \"rt-multi-thread\", \"net\", \"test-util\"] }\ntokio-stream = \"0.1\"\ntokio-tungstenite = \"0.29.0\"\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3.20\", features = [\"json\"] }\nuuid = { version = \"1.0\", features = [\"serde\", \"v4\"] }\n\n[dev-dependencies.tower]\npackage = \"tower\"\nversion = \"0.5.2\"\nfeatures = [\n    \"util\",\n    \"timeout\",\n    \"limit\",\n    \"load-shed\",\n    \"steer\",\n    \"filter\",\n]\n\n[dev-dependencies.tower-http]\nversion = \"0.6.8\"\nfeatures = [\n    # all tower-http features except (de)?compression-zstd which doesn't\n    # build on `--target armv5te-unknown-linux-musleabi`\n    \"add-extension\",\n    \"auth\",\n    \"catch-panic\",\n    \"compression-br\",\n    \"compression-deflate\",\n    \"compression-gzip\",\n    \"cors\",\n    \"decompression-br\",\n    \"decompression-deflate\",\n    \"decompression-gzip\",\n    \"follow-redirect\",\n    \"fs\",\n    \"limit\",\n    \"map-request-body\",\n    \"map-response-body\",\n    \"metrics\",\n    \"normalize-path\",\n    \"propagate-header\",\n    \"redirect\",\n    \"request-id\",\n    \"sensitive-headers\",\n    \"set-header\",\n    \"set-status\",\n    \"timeout\",\n    \"trace\",\n    \"util\",\n    \"validate-request\",\n]\n\n[lints]\nworkspace = true\n\n[[bench]]\nname = \"benches\"\nharness = false\n"
  },
  {
    "path": "axum/README.md",
    "content": "# axum\n\n`axum` is an HTTP routing and request-handling library that focuses on ergonomics and modularity.\n\n[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum/actions/workflows/CI.yml)\n[![Crates.io](https://img.shields.io/crates/v/axum)](https://crates.io/crates/axum)\n[![Documentation](https://docs.rs/axum/badge.svg)][docs]\n\nMore information about this crate can be found in the [crate documentation][docs].\n\n## High level features\n\n- Route requests to handlers with a macro free API.\n- Declaratively parse requests using extractors.\n- Simple and predictable error handling model.\n- Generate responses with minimal boilerplate.\n- Take full advantage of the [`tower`] and [`tower-http`] ecosystem of\n  middleware, services, and utilities.\n\nIn particular the last point is what sets `axum` apart from other libraries / frameworks.\n`axum` doesn't have its own middleware system but instead uses\n[`tower::Service`]. This means `axum` gets timeouts, tracing, compression,\nauthorization, and more, for free. It also enables you to share middleware with\napplications written using [`hyper`] or [`tonic`].\n\n## ⚠ Breaking changes ⚠\n\nWe are currently working towards axum 0.9 so the `main` branch contains breaking\nchanges. See the [`0.8.x`] branch for what's released to crates.io.\n\n[`0.8.x`]: https://github.com/tokio-rs/axum/tree/v0.8.x\n\n## Usage example\n\n```rust\nuse axum::{\n    routing::{get, post},\n    http::StatusCode,\n    Json, Router,\n};\nuse serde::{Deserialize, Serialize};\n\n#[tokio::main]\nasync fn main() {\n    // initialize tracing\n    tracing_subscriber::fmt::init();\n\n    // build our application with a route\n    let app = Router::new()\n        // `GET /` goes to `root`\n        .route(\"/\", get(root))\n        // `POST /users` goes to `create_user`\n        .route(\"/users\", post(create_user));\n\n    // run our app with hyper, listening globally on port 3000\n    let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    axum::serve(listener, app).await;\n}\n\n// basic handler that responds with a static string\nasync fn root() -> &'static str {\n    \"Hello, World!\"\n}\n\nasync fn create_user(\n    // this argument tells axum to parse the request body\n    // as JSON into a `CreateUser` type\n    Json(payload): Json<CreateUser>,\n) -> (StatusCode, Json<User>) {\n    // insert your application logic here\n    let user = User {\n        id: 1337,\n        username: payload.username,\n    };\n\n    // this will be converted into a JSON response\n    // with a status code of `201 Created`\n    (StatusCode::CREATED, Json(user))\n}\n\n// the input to our `create_user` handler\n#[derive(Deserialize)]\nstruct CreateUser {\n    username: String,\n}\n\n// the output to our `create_user` handler\n#[derive(Serialize)]\nstruct User {\n    id: u64,\n    username: String,\n}\n```\n\nYou can find this [example][readme-example] as well as other example projects in\nthe [example directory][examples].\n\nSee the [crate documentation][docs] for way more examples.\n\n## Performance\n\n`axum` is a relatively thin layer on top of [`hyper`] and adds very little\noverhead. So `axum`'s performance is comparable to [`hyper`]. You can find\nbenchmarks [here](https://github.com/programatik29/rust-web-benchmarks) and\n[here](https://web-frameworks-benchmark.netlify.app/result?l=rust).\n\n## Safety\n\nThis crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in\n100% safe Rust.\n\n## Minimum supported Rust version\n\naxum's MSRV is 1.80.\n\n## Examples\n\nThe [examples] folder contains various examples of how to use `axum`. The\n[docs] also provide lots of code snippets and examples. For full-fledged examples, check out community-maintained [showcases] or [tutorials].\n\n## Getting Help\n\nIn the `axum`'s repo we also have a [number of examples][examples] showing how\nto put everything together. Community-maintained [showcases] and [tutorials] also demonstrate how to use `axum` for real-world applications. You're also welcome to ask in the [Discord channel][chat] or open a [discussion] with your question.\n\n## Community projects\n\nSee [here][ecosystem] for a list of community maintained crates and projects\nbuilt with `axum`.\n\n## Contributing\n\n🎈 Thanks for your help improving the project! We are so happy to have\nyou! We have a [contributing guide][contributing] to help you get involved in the\n`axum` project.\n\n## License\n\nThis project is licensed under the [MIT license][license].\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `axum` by you, shall be licensed as MIT, without any\nadditional terms or conditions.\n\n[readme-example]: https://github.com/tokio-rs/axum/tree/main/examples/readme\n[examples]: https://github.com/tokio-rs/axum/tree/main/examples\n[docs]: https://docs.rs/axum\n[`tower`]: https://crates.io/crates/tower\n[`hyper`]: https://crates.io/crates/hyper\n[`tower-http`]: https://crates.io/crates/tower-http\n[`tonic`]: https://crates.io/crates/tonic\n[contributing]: https://github.com/tokio-rs/axum/blob/main/CONTRIBUTING.md\n[chat]: https://discord.gg/tokio\n[discussion]: https://github.com/tokio-rs/axum/discussions/new?category=q-a\n[`tower::Service`]: https://docs.rs/tower/latest/tower/trait.Service.html\n[ecosystem]: https://github.com/tokio-rs/axum/blob/main/ECOSYSTEM.md\n[showcases]: https://github.com/tokio-rs/axum/blob/main/ECOSYSTEM.md#project-showcase\n[tutorials]: https://github.com/tokio-rs/axum/blob/main/ECOSYSTEM.md#tutorials\n[license]: https://github.com/tokio-rs/axum/blob/main/axum/LICENSE\n"
  },
  {
    "path": "axum/benches/benches.rs",
    "content": "#![allow(missing_docs)]\n\nuse axum::{\n    extract::State,\n    routing::{get, post},\n    Extension, Json, Router,\n};\nuse serde::{Deserialize, Serialize};\nuse std::{\n    future::IntoFuture,\n    io::BufRead,\n    process::{Command, Stdio},\n};\n\nfn main() {\n    if on_ci() {\n        install_rewrk();\n    } else {\n        ensure_rewrk_is_installed();\n    }\n\n    benchmark(\"minimal\").run(Router::new);\n\n    benchmark(\"basic\")\n        .path(\"/a/b/c\")\n        .run(|| Router::new().route(\"/a/b/c\", get(|| async { \"Hello, World!\" })));\n\n    benchmark(\"basic-merge\").path(\"/a/b/c\").run(|| {\n        let inner = Router::new().route(\"/a/b/c\", get(|| async { \"Hello, World!\" }));\n        Router::new().merge(inner)\n    });\n\n    benchmark(\"basic-nest\").path(\"/a/b/c\").run(|| {\n        let c = Router::new().route(\"/c\", get(|| async { \"Hello, World!\" }));\n        let b = Router::new().nest(\"/b\", c);\n        Router::new().nest(\"/a\", b)\n    });\n\n    benchmark(\"routing\").path(\"/foo/bar/baz\").run(|| {\n        let mut app = Router::new();\n        for a in 0..10 {\n            for b in 0..10 {\n                for c in 0..10 {\n                    app = app.route(&format!(\"/foo-{a}/bar-{b}/baz-{c}\"), get(|| async {}));\n                }\n            }\n        }\n        app.route(\"/foo/bar/baz\", get(|| async {}))\n    });\n\n    benchmark(\"receive-json\")\n        .method(\"post\")\n        .headers(&[(\"content-type\", \"application/json\")])\n        .body(r#\"{\"n\": 123, \"s\": \"hi there\", \"b\": false}\"#)\n        .run(|| Router::new().route(\"/\", post(|_: Json<Payload>| async {})));\n\n    benchmark(\"send-json\").run(|| {\n        Router::new().route(\n            \"/\",\n            get(|| async {\n                Json(Payload {\n                    n: 123,\n                    s: \"hi there\".to_owned(),\n                    b: false,\n                })\n            }),\n        )\n    });\n\n    let state = AppState {\n        _string: \"aaaaaaaaaaaaaaaaaa\".to_owned(),\n        _vec: Vec::from([\n            \"aaaaaaaaaaaaaaaaaa\".to_owned(),\n            \"bbbbbbbbbbbbbbbbbb\".to_owned(),\n            \"cccccccccccccccccc\".to_owned(),\n        ]),\n    };\n\n    benchmark(\"extension\").run(|| {\n        Router::new()\n            .route(\"/\", get(|_: Extension<AppState>| async {}))\n            .layer(Extension(state.clone()))\n    });\n\n    benchmark(\"state\").run(|| {\n        Router::new()\n            .route(\"/\", get(|_: State<AppState>| async {}))\n            .with_state(state.clone())\n    });\n}\n\n#[derive(Clone)]\nstruct AppState {\n    _string: String,\n    _vec: Vec<String>,\n}\n\n#[derive(Deserialize, Serialize)]\nstruct Payload {\n    n: u32,\n    s: String,\n    b: bool,\n}\n\nfn benchmark(name: &'static str) -> BenchmarkBuilder {\n    BenchmarkBuilder {\n        name,\n        path: None,\n        method: None,\n        headers: None,\n        body: None,\n    }\n}\n\nstruct BenchmarkBuilder {\n    name: &'static str,\n    path: Option<&'static str>,\n    method: Option<&'static str>,\n    headers: Option<&'static [(&'static str, &'static str)]>,\n    body: Option<&'static str>,\n}\n\nmacro_rules! config_method {\n    ($name:ident, $ty:ty) => {\n        fn $name(mut self, $name: $ty) -> Self {\n            self.$name = Some($name);\n            self\n        }\n    };\n}\n\nimpl BenchmarkBuilder {\n    config_method!(path, &'static str);\n    config_method!(method, &'static str);\n    config_method!(headers, &'static [(&'static str, &'static str)]);\n    config_method!(body, &'static str);\n\n    fn run<F>(self, f: F)\n    where\n        F: FnOnce() -> Router<()>,\n    {\n        // support only running some benchmarks with\n        // ```\n        // cargo bench -- routing send-json\n        // ```\n        let args = std::env::args().collect::<Vec<_>>();\n        if args.len() != 1 {\n            let names = &args[1..args.len() - 1];\n            if !names.is_empty() && !names.contains(&self.name.to_owned()) {\n                return;\n            }\n        }\n\n        let app = f();\n\n        let rt = tokio::runtime::Builder::new_multi_thread()\n            .enable_all()\n            .build()\n            .unwrap();\n\n        let listener = rt\n            .block_on(tokio::net::TcpListener::bind(\"0.0.0.0:0\"))\n            .unwrap();\n        let addr = listener.local_addr().unwrap();\n\n        #[allow(unreachable_code)] // buggy lint, fixed in nightly\n        std::thread::spawn(move || {\n            rt.block_on(axum::serve(listener, app).into_future());\n        });\n\n        let mut cmd = Command::new(\"rewrk\");\n        cmd.stdout(Stdio::piped());\n\n        cmd.arg(\"--host\");\n        cmd.arg(format!(\"http://{addr}{}\", self.path.unwrap_or(\"\")));\n\n        cmd.args([\"--connections\", \"10\"]);\n        cmd.args([\"--threads\", \"10\"]);\n\n        if on_ci() {\n            // don't slow down CI by running the benchmarks for too long\n            // but do run them for a bit\n            cmd.args([\"--duration\", \"1s\"]);\n        } else {\n            cmd.args([\"--duration\", \"10s\"]);\n        }\n\n        if let Some(method) = self.method {\n            cmd.args([\"--method\", method]);\n        }\n\n        for (key, value) in self.headers.into_iter().flatten() {\n            cmd.arg(\"--header\");\n            cmd.arg(format!(\"{key}: {value}\"));\n        }\n\n        if let Some(body) = self.body {\n            cmd.args([\"--body\", body]);\n        }\n\n        eprintln!(\"Running {:?} benchmark\", self.name);\n\n        // indent output from `rewrk` so it's easier to read when running multiple benchmarks\n        let mut child = cmd.spawn().unwrap();\n        let stdout = child.stdout.take().unwrap();\n        let stdout = std::io::BufReader::new(stdout);\n        for line in stdout.lines() {\n            let line = line.unwrap();\n            println!(\"  {line}\");\n        }\n\n        let status = child.wait().unwrap();\n\n        if !status.success() {\n            eprintln!(\"`rewrk` command failed\");\n            std::process::exit(status.code().unwrap());\n        }\n    }\n}\n\nfn install_rewrk() {\n    println!(\"installing rewrk\");\n    let mut cmd = Command::new(\"cargo\");\n    cmd.args([\n        \"install\",\n        \"rewrk\",\n        \"--git\",\n        \"https://github.com/ChillFish8/rewrk.git\",\n    ]);\n    let status = cmd\n        .status()\n        .unwrap_or_else(|_| panic!(\"failed to install rewrk\"));\n    if !status.success() {\n        panic!(\"failed to install rewrk\");\n    }\n}\n\nfn ensure_rewrk_is_installed() {\n    let mut cmd = Command::new(\"rewrk\");\n    cmd.arg(\"--help\");\n    cmd.stdout(Stdio::null());\n    cmd.stderr(Stdio::null());\n    cmd.status().unwrap_or_else(|_| {\n        panic!(\"rewrk is not installed. See https://github.com/lnx-search/rewrk\")\n    });\n}\n\nfn on_ci() -> bool {\n    std::env::var(\"GITHUB_ACTIONS\").is_ok()\n}\n"
  },
  {
    "path": "axum/src/body/mod.rs",
    "content": "//! HTTP body utilities.\n\n#[doc(no_inline)]\npub use http_body::Body as HttpBody;\n\n#[doc(no_inline)]\npub use bytes::Bytes;\n\n#[doc(inline)]\npub use axum_core::body::{Body, BodyDataStream};\n\nuse http_body_util::{BodyExt, Limited};\n\n/// Converts [`Body`] into [`Bytes`] and limits the maximum size of the body.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::body::{to_bytes, Body};\n///\n/// # async fn foo() -> Result<(), axum_core::Error> {\n/// let body = Body::from(vec![1, 2, 3]);\n/// // Use `usize::MAX` if you don't care about the maximum size.\n/// let bytes = to_bytes(body, usize::MAX).await?;\n/// assert_eq!(&bytes[..], &[1, 2, 3]);\n/// # Ok(())\n/// # }\n/// ```\n///\n/// You can detect if the limit was hit by checking the source of the error:\n///\n/// ```rust\n/// use axum::body::{to_bytes, Body};\n/// use http_body_util::LengthLimitError;\n///\n/// # #[tokio::main]\n/// # async fn main() {\n/// let body = Body::from(vec![1, 2, 3]);\n/// match to_bytes(body, 1).await {\n///     Ok(_bytes) => panic!(\"should have hit the limit\"),\n///     Err(err) => {\n///         let source = std::error::Error::source(&err).unwrap();\n///         assert!(source.is::<LengthLimitError>());\n///     }\n/// }\n/// # }\n/// ```\npub async fn to_bytes(body: Body, limit: usize) -> Result<Bytes, axum_core::Error> {\n    Limited::new(body, limit)\n        .collect()\n        .await\n        .map(|col| col.to_bytes())\n        .map_err(axum_core::Error::new)\n}\n"
  },
  {
    "path": "axum/src/boxed.rs",
    "content": "use std::{convert::Infallible, fmt};\n\nuse crate::extract::Request;\nuse tower::Service;\n\nuse crate::{\n    handler::Handler,\n    routing::{future::RouteFuture, Route},\n    Router,\n};\n\npub(crate) struct BoxedIntoRoute<S, E>(Box<dyn ErasedIntoRoute<S, E>>);\n\nimpl<S> BoxedIntoRoute<S, Infallible>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    pub(crate) fn from_handler<H, T>(handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        Self(Box::new(MakeErasedHandler {\n            handler,\n            into_route: |handler, state| Route::new(Handler::with_state(handler, state)),\n        }))\n    }\n}\n\nimpl<S, E> BoxedIntoRoute<S, E> {\n    pub(crate) fn map<F, E2>(self, f: F) -> BoxedIntoRoute<S, E2>\n    where\n        S: 'static,\n        E: 'static,\n        F: FnOnce(Route<E>) -> Route<E2> + Clone + Send + Sync + 'static,\n        E2: 'static,\n    {\n        BoxedIntoRoute(Box::new(Map {\n            inner: self.0,\n            layer: Box::new(f),\n        }))\n    }\n\n    pub(crate) fn into_route(self, state: S) -> Route<E> {\n        self.0.into_route(state)\n    }\n}\n\nimpl<S, E> Clone for BoxedIntoRoute<S, E> {\n    fn clone(&self) -> Self {\n        Self(self.0.clone_box())\n    }\n}\n\nimpl<S, E> fmt::Debug for BoxedIntoRoute<S, E> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_tuple(\"BoxedIntoRoute\").finish()\n    }\n}\n\npub(crate) trait ErasedIntoRoute<S, E>: Send + Sync {\n    fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, E>>;\n\n    fn into_route(self: Box<Self>, state: S) -> Route<E>;\n\n    #[allow(dead_code)]\n    fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<E>;\n}\n\npub(crate) struct MakeErasedHandler<H, S> {\n    pub(crate) handler: H,\n    pub(crate) into_route: fn(H, S) -> Route,\n}\n\nimpl<H, S> ErasedIntoRoute<S, Infallible> for MakeErasedHandler<H, S>\nwhere\n    H: Clone + Send + Sync + 'static,\n    S: 'static,\n{\n    fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, Infallible>> {\n        Box::new(self.clone())\n    }\n\n    fn into_route(self: Box<Self>, state: S) -> Route {\n        (self.into_route)(self.handler, state)\n    }\n\n    fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<Infallible> {\n        self.into_route(state).call(request)\n    }\n}\n\nimpl<H, S> Clone for MakeErasedHandler<H, S>\nwhere\n    H: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            handler: self.handler.clone(),\n            into_route: self.into_route,\n        }\n    }\n}\n\n#[allow(dead_code)]\npub(crate) struct MakeErasedRouter<S> {\n    pub(crate) router: Router<S>,\n    pub(crate) into_route: fn(Router<S>, S) -> Route,\n}\n\nimpl<S> ErasedIntoRoute<S, Infallible> for MakeErasedRouter<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, Infallible>> {\n        Box::new(self.clone())\n    }\n\n    fn into_route(self: Box<Self>, state: S) -> Route {\n        (self.into_route)(self.router, state)\n    }\n\n    fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<Infallible> {\n        self.router.call_with_state(request, state)\n    }\n}\n\nimpl<S> Clone for MakeErasedRouter<S>\nwhere\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            router: self.router.clone(),\n            into_route: self.into_route,\n        }\n    }\n}\n\npub(crate) struct Map<S, E, E2> {\n    pub(crate) inner: Box<dyn ErasedIntoRoute<S, E>>,\n    pub(crate) layer: Box<dyn LayerFn<E, E2>>,\n}\n\nimpl<S, E, E2> ErasedIntoRoute<S, E2> for Map<S, E, E2>\nwhere\n    S: 'static,\n    E: 'static,\n    E2: 'static,\n{\n    fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, E2>> {\n        Box::new(Self {\n            inner: self.inner.clone_box(),\n            layer: self.layer.clone_box(),\n        })\n    }\n\n    fn into_route(self: Box<Self>, state: S) -> Route<E2> {\n        (self.layer)(self.inner.into_route(state))\n    }\n\n    fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<E2> {\n        (self.layer)(self.inner.into_route(state)).call(request)\n    }\n}\n\npub(crate) trait LayerFn<E, E2>: FnOnce(Route<E>) -> Route<E2> + Send + Sync {\n    fn clone_box(&self) -> Box<dyn LayerFn<E, E2>>;\n}\n\nimpl<F, E, E2> LayerFn<E, E2> for F\nwhere\n    F: FnOnce(Route<E>) -> Route<E2> + Clone + Send + Sync + 'static,\n{\n    fn clone_box(&self) -> Box<dyn LayerFn<E, E2>> {\n        Box::new(self.clone())\n    }\n}\n"
  },
  {
    "path": "axum/src/docs/debugging_handler_type_errors.md",
    "content": "## Debugging handler type errors\n\nFor a function to be used as a handler it must implement the [`Handler`] trait.\naxum provides blanket implementations for functions that:\n\n- Are `async fn`s.\n- Take no more than 16 arguments that all implement `Send`.\n  - All except the last argument implement [`FromRequestParts`].\n  - The last argument implements [`FromRequest`].\n- Returns something that implements [`IntoResponse`].\n- If a closure is used it must implement `Clone + Send` and be\n`'static`.\n- Returns a future that is `Send`. The most common way to accidentally make a\nfuture `!Send` is to hold a `!Send` type across an await.\n\nUnfortunately Rust gives poor error messages if you try to use a function\nthat doesn't quite match what's required by [`Handler`].\n\nYou might get an error like this:\n\n```not_rust\nerror[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied\n   --> src/main.rs:13:44\n    |\n13  |     let app = Router::new().route(\"/\", get(handler));\n    |                                            ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}`\n    |\n   ::: axum/src/handler/mod.rs:116:8\n    |\n116 |     H: Handler<T, B>,\n    |        ------------- required by this bound in `axum::routing::get`\n```\n\nThis error doesn't tell you _why_ your function doesn't implement\n[`Handler`]. It's possible to improve the error with the [`debug_handler`]\nproc-macro from the [axum-macros] crate.\n\n[axum-macros]: https://docs.rs/axum-macros\n[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html\n"
  },
  {
    "path": "axum/src/docs/error_handling.md",
    "content": "Error handling model and utilities\n\n# axum's error handling model\n\naxum is based on [`tower::Service`] which bundles errors through its associated\n`Error` type. If you have a [`Service`] that produces an error and that error\nmakes it all the way up to hyper, the connection will be terminated _without_\nsending a response. This is generally not desirable so axum makes sure you\nalways produce a response by relying on the type system.\n\naxum does this by requiring all services have [`Infallible`] as their error\ntype. `Infallible` is the error type for errors that can never happen.\n\nThis means if you define a handler like:\n\n```rust\nuse axum::http::StatusCode;\n\nasync fn handler() -> Result<String, StatusCode> {\n    # todo!()\n    // ...\n}\n```\n\nWhile it looks like it might fail with a `StatusCode` this actually isn't an\n\"error\". If this handler returns `Err(some_status_code)` that will still be\nconverted into a [`Response`] and sent back to the client. This is done\nthrough `StatusCode`'s [`IntoResponse`] implementation.\n\nIt doesn't matter whether you return `Err(StatusCode::NOT_FOUND)` or\n`Err(StatusCode::INTERNAL_SERVER_ERROR)`. These are not considered errors in\naxum.\n\nInstead of a direct `StatusCode`, it makes sense to use intermediate error type\nthat can ultimately be converted to `Response`. This allows using `?` operator\nin handlers. See those examples:\n\n* [`anyhow-error-response`][anyhow] for generic boxed errors\n* [`error-handling`][error-handling] for application-specific detailed errors\n\n[anyhow]: https://github.com/tokio-rs/axum/blob/main/examples/anyhow-error-response/src/main.rs\n[error-handling]: https://github.com/tokio-rs/axum/blob/main/examples/error-handling/src/main.rs\n\nThis also applies to extractors. If an extractor doesn't match the request the\nrequest will be rejected and a response will be returned without calling your\nhandler. See [`extract`](crate::extract) to learn more about handling extractor\nfailures.\n\n# Routing to fallible services\n\nYou generally don't have to think about errors if you're only using async\nfunctions as handlers. However if you're embedding general `Service`s or\napplying middleware, which might produce errors you have to tell axum how to\nconvert those errors into responses.\n\n```rust\nuse axum::{\n    Router,\n    body::Body,\n    http::{Request, Response, StatusCode},\n    error_handling::HandleError,\n};\n\nasync fn thing_that_might_fail() -> Result<(), anyhow::Error> {\n    # Ok(())\n    // ...\n}\n\n// this service might fail with `anyhow::Error`\nlet some_fallible_service = tower::service_fn(|_req| async {\n    thing_that_might_fail().await?;\n    Ok::<_, anyhow::Error>(Response::new(Body::empty()))\n});\n\nlet app = Router::new().route_service(\n    \"/\",\n    // we cannot route to `some_fallible_service` directly since it might fail.\n    // we have to use `handle_error` which converts its errors into responses\n    // and changes its error type from `anyhow::Error` to `Infallible`.\n    HandleError::new(some_fallible_service, handle_anyhow_error),\n);\n\n// handle errors by converting them into something that implements\n// `IntoResponse`\nasync fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) {\n    (\n        StatusCode::INTERNAL_SERVER_ERROR,\n        format!(\"Something went wrong: {err}\"),\n    )\n}\n# let _: Router = app;\n```\n\n# Applying fallible middleware\n\nSimilarly axum requires you to handle errors from middleware. That is done with\n[`HandleErrorLayer`]:\n\n```rust\nuse axum::{\n    Router,\n    BoxError,\n    routing::get,\n    http::StatusCode,\n    error_handling::HandleErrorLayer,\n};\nuse std::time::Duration;\nuse tower::ServiceBuilder;\n\nlet app = Router::new()\n    .route(\"/\", get(|| async {}))\n    .layer(\n        ServiceBuilder::new()\n            // `timeout` will produce an error if the handler takes\n            // too long so we must handle those\n            .layer(HandleErrorLayer::new(handle_timeout_error))\n            .timeout(Duration::from_secs(30))\n    );\n\nasync fn handle_timeout_error(err: BoxError) -> (StatusCode, String) {\n    if err.is::<tower::timeout::error::Elapsed>() {\n        (\n            StatusCode::REQUEST_TIMEOUT,\n            \"Request took too long\".to_string(),\n        )\n    } else {\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            format!(\"Unhandled internal error: {err}\"),\n        )\n    }\n}\n# let _: Router = app;\n```\n\n# Running extractors for error handling\n\n`HandleErrorLayer` also supports running extractors:\n\n```rust\nuse axum::{\n    Router,\n    BoxError,\n    routing::get,\n    http::{StatusCode, Method, Uri},\n    error_handling::HandleErrorLayer,\n};\nuse std::time::Duration;\nuse tower::ServiceBuilder;\n\nlet app = Router::new()\n    .route(\"/\", get(|| async {}))\n    .layer(\n        ServiceBuilder::new()\n            // `timeout` will produce an error if the handler takes\n            // too long so we must handle those\n            .layer(HandleErrorLayer::new(handle_timeout_error))\n            .timeout(Duration::from_secs(30))\n    );\n\nasync fn handle_timeout_error(\n    // `Method` and `Uri` are extractors so they can be used here\n    method: Method,\n    uri: Uri,\n    // the last argument must be the error itself\n    err: BoxError,\n) -> (StatusCode, String) {\n    (\n        StatusCode::INTERNAL_SERVER_ERROR,\n        format!(\"`{method} {uri}` failed with {err}\"),\n    )\n}\n# let _: Router = app;\n```\n\n[`tower::Service`]: `tower::Service`\n[`Infallible`]: std::convert::Infallible\n[`Response`]: crate::response::Response\n[`IntoResponse`]: crate::response::IntoResponse\n"
  },
  {
    "path": "axum/src/docs/extract.md",
    "content": "Types and traits for extracting data from requests.\n\n# Intro\n\nA handler function is an async function that takes any number of\n\"extractors\" as arguments. An extractor is a type that implements\n[`FromRequest`] or [`FromRequestParts`].\n\nFor example, [`Json`] is an extractor that consumes the request body and\ndeserializes it as JSON into some target type:\n\n```rust,no_run\nuse axum::{\n    extract::Json,\n    routing::post,\n    handler::Handler,\n    Router,\n};\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\nstruct CreateUser {\n    email: String,\n    password: String,\n}\n\nasync fn create_user(Json(payload): Json<CreateUser>) {\n    // ...\n}\n\nlet app = Router::new().route(\"/users\", post(create_user));\n# let _: Router = app;\n```\n\n# Common extractors\n\nSome commonly used extractors are:\n\n```rust,no_run\nuse axum::{\n    extract::{Request, Json, Path, Extension, Query},\n    routing::post,\n    http::header::HeaderMap,\n    body::{Bytes, Body},\n    Router,\n};\nuse serde_json::Value;\nuse std::collections::HashMap;\n\n// `Path` gives you the path parameters and deserializes them. See its docs for\n// more details\nasync fn path(Path(user_id): Path<u32>) {}\n\n// `Query` gives you the query parameters and deserializes them.\nasync fn query(Query(params): Query<HashMap<String, String>>) {}\n\n// `HeaderMap` gives you all the headers\nasync fn headers(headers: HeaderMap) {}\n\n// `String` consumes the request body and ensures it is valid utf-8\nasync fn string(body: String) {}\n\n// `Bytes` gives you the raw request body\nasync fn bytes(body: Bytes) {}\n\n// We've already seen `Json` for parsing the request body as json\nasync fn json(Json(payload): Json<Value>) {}\n\n// `Request` gives you the whole request for maximum control\nasync fn request(request: Request) {}\n\n// `Extension` extracts data from \"request extensions\"\n// This is commonly used to share state with handlers\nasync fn extension(Extension(state): Extension<State>) {}\n\n#[derive(Clone)]\nstruct State { /* ... */ }\n\nlet app = Router::new()\n    .route(\"/path/{user_id}\", post(path))\n    .route(\"/query\", post(query))\n    .route(\"/string\", post(string))\n    .route(\"/bytes\", post(bytes))\n    .route(\"/json\", post(json))\n    .route(\"/request\", post(request))\n    .route(\"/extension\", post(extension));\n# let _: Router = app;\n```\n\n# Applying multiple extractors\n\nYou can also apply multiple extractors:\n\n```rust,no_run\nuse axum::{\n    extract::{Path, Query},\n    routing::get,\n    Router,\n};\nuse uuid::Uuid;\nuse serde::Deserialize;\n\nlet app = Router::new().route(\"/users/{id}/things\", get(get_user_things));\n\n#[derive(Deserialize)]\nstruct Pagination {\n    page: usize,\n    per_page: usize,\n}\n\nasync fn get_user_things(\n    Path(user_id): Path<Uuid>,\n    Query(pagination): Query<Pagination>,\n) {\n    // ...\n}\n# let _: Router = app;\n```\n\n# The order of extractors\n\nExtractors always run in the order of the function parameters that is from\nleft to right.\n\nThe request body is an asynchronous stream that can only be consumed once.\nTherefore you can only have one extractor that consumes the request body. axum\nenforces this by requiring such extractors to be the _last_ argument your\nhandler takes.\n\nFor example\n\n```rust\nuse axum::{extract::State, http::{Method, HeaderMap}};\n#\n# #[derive(Clone)]\n# struct AppState {\n# }\n\nasync fn handler(\n    // `Method` and `HeaderMap` don't consume the request body so they can\n    // put anywhere in the argument list (but before `body`)\n    method: Method,\n    headers: HeaderMap,\n    // `State` is also an extractor so it needs to be before `body`\n    State(state): State<AppState>,\n    // `String` consumes the request body and thus must be the last extractor\n    body: String,\n) {\n    // ...\n}\n#\n# let _: axum::routing::MethodRouter<AppState> = axum::routing::get(handler);\n```\n\nWe get a compile error if `String` isn't the last extractor:\n\n```rust,compile_fail\nuse axum::http::Method;\n\nasync fn handler(\n    // this doesn't work since `String` must be the last argument\n    body: String,\n    method: Method,\n) {\n    // ...\n}\n#\n# let _: axum::routing::MethodRouter = axum::routing::get(handler);\n```\n\nThis also means you cannot consume the request body twice:\n\n```rust,compile_fail\nuse axum::Json;\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\nstruct Payload {}\n\nasync fn handler(\n    // `String` and `Json` both consume the request body\n    // so they cannot both be used\n    string_body: String,\n    json_body: Json<Payload>,\n) {\n    // ...\n}\n#\n# let _: axum::routing::MethodRouter = axum::routing::get(handler);\n```\n\naxum enforces this by requiring the last extractor implements [`FromRequest`]\nand all others implement [`FromRequestParts`].\n\n# Handling extractor rejections\n\nIf you want to handle the case of an extractor failing within a specific\nhandler, you can wrap it in `Result`, with the error being the rejection type\nof the extractor:\n\n```rust,no_run\nuse axum::{\n    extract::{Json, rejection::JsonRejection},\n    routing::post,\n    Router,\n};\nuse serde_json::Value;\n\nasync fn create_user(payload: Result<Json<Value>, JsonRejection>) {\n    match payload {\n        Ok(payload) => {\n            // We got a valid JSON payload\n        }\n        Err(JsonRejection::MissingJsonContentType(_)) => {\n            // Request didn't have `Content-Type: application/json`\n            // header\n        }\n        Err(JsonRejection::JsonDataError(_)) => {\n            // Couldn't deserialize the body into the target type\n        }\n        Err(JsonRejection::JsonSyntaxError(_)) => {\n            // Syntax error in the body\n        }\n        Err(JsonRejection::BytesRejection(_)) => {\n            // Failed to extract the request body\n        }\n        Err(_) => {\n            // `JsonRejection` is marked `#[non_exhaustive]` so match must\n            // include a catch-all case.\n        }\n    }\n}\n\nlet app = Router::new().route(\"/users\", post(create_user));\n# let _: Router = app;\n```\n\n# Optional extractors\n\nSome extractors implement [`OptionalFromRequestParts`] in addition to\n[`FromRequestParts`], or [`OptionalFromRequest`] in addition to [`FromRequest`].\n\nThese extractors can be used inside of `Option`. It depends on the particular\n`OptionalFromRequestParts` or `OptionalFromRequest` implementation what this\ndoes: For example for `TypedHeader` from axum-extra, you get `None` if the\nheader you're trying to extract is not part of the request, but if the header\nis present and fails to parse, the request is rejected.\n\n```rust,no_run\nuse axum::{routing::post, Router};\nuse axum_extra::{headers::UserAgent, TypedHeader};\nuse serde_json::Value;\n\nasync fn foo(user_agent: Option<TypedHeader<UserAgent>>) {\n    if let Some(TypedHeader(user_agent)) = user_agent {\n        // The client sent a user agent\n    } else {\n        // No user agent header\n    }\n}\n\nlet app = Router::new().route(\"/foo\", post(foo));\n# let _: Router = app;\n```\n\n# Customizing extractor responses\n\nIf an extractor fails it will return a response with the error and your\nhandler will not be called. To customize the error response you have two \noptions:\n\n1. Use `Result<T, T::Rejection>` as your extractor like shown in\n   [\"Handling extractor rejections\"](#handling-extractor-rejections).\n   This works well if you're only using the extractor in a single handler.\n2. Create your own extractor that in its [`FromRequest`] implementation calls\n   one of axum's built in extractors but returns a different response for\n   rejections. See the [customize-extractor-error] example for more details.\n\n# Accessing inner errors\n\naxum's built-in extractors don't directly expose the inner error. This gives us\nmore flexibility and allows us to change internal implementations without\nbreaking the public API.\n\nFor example that means while [`Json`] is implemented using [`serde_json`] it\ndoesn't directly expose the [`serde_json::Error`] that's contained in\n[`JsonRejection::JsonDataError`]. However it is still possible to access via\nmethods from [`std::error::Error`]:\n\n```rust\nuse std::error::Error;\nuse axum::{\n    extract::{Json, rejection::JsonRejection},\n    response::IntoResponse,\n    http::StatusCode,\n};\nuse serde_json::{json, Value};\n\nasync fn handler(\n    result: Result<Json<Value>, JsonRejection>,\n) -> Result<Json<Value>, (StatusCode, String)> {\n    match result {\n        // if the client sent valid JSON then we're good\n        Ok(Json(payload)) => Ok(Json(json!({ \"payload\": payload }))),\n\n        Err(err) => match err {\n            JsonRejection::JsonDataError(err) => {\n                Err(serde_json_error_response(err))\n            }\n            JsonRejection::JsonSyntaxError(err) => {\n                Err(serde_json_error_response(err))\n            }\n            // handle other rejections from the `Json` extractor\n            JsonRejection::MissingJsonContentType(_) => Err((\n                StatusCode::BAD_REQUEST,\n                \"Missing `Content-Type: application/json` header\".to_string(),\n            )),\n            JsonRejection::BytesRejection(_) => Err((\n                StatusCode::INTERNAL_SERVER_ERROR,\n                \"Failed to buffer request body\".to_string(),\n            )),\n            // we must provide a catch-all case since `JsonRejection` is marked\n            // `#[non_exhaustive]`\n            _ => Err((\n                StatusCode::INTERNAL_SERVER_ERROR,\n                \"Unknown error\".to_string(),\n            )),\n        },\n    }\n}\n\n// attempt to extract the inner `serde_path_to_error::Error<serde_json::Error>`,\n// if that succeeds we can provide a more specific error.\n//\n// `Json` uses `serde_path_to_error` so the error will be wrapped in `serde_path_to_error::Error`.\nfn serde_json_error_response<E>(err: E) -> (StatusCode, String)\nwhere\n    E: Error + 'static,\n{\n    if let Some(err) = find_error_source::<serde_path_to_error::Error<serde_json::Error>>(&err) {\n        let serde_json_err = err.inner();\n        (\n            StatusCode::BAD_REQUEST,\n            format!(\n                \"Invalid JSON at line {} column {}\",\n                serde_json_err.line(),\n                serde_json_err.column()\n            ),\n        )\n    } else {\n        (StatusCode::BAD_REQUEST, \"Unknown error\".to_string())\n    }\n}\n\n// attempt to downcast `err` into a `T` and if that fails recursively try and\n// downcast `err`'s source\nfn find_error_source<'a, T>(err: &'a (dyn Error + 'static)) -> Option<&'a T>\nwhere\n    T: Error + 'static,\n{\n    if let Some(err) = err.downcast_ref::<T>() {\n        Some(err)\n    } else if let Some(source) = err.source() {\n        find_error_source(source)\n    } else {\n        None\n    }\n}\n# \n# #[tokio::main]\n# async fn main() {\n#     use axum::extract::FromRequest;\n# \n#     let req = axum::http::Request::builder()\n#         .header(\"content-type\", \"application/json\")\n#         .body(axum::body::Body::from(\"{\"))\n#         .unwrap();\n# \n#     let err = match Json::<serde_json::Value>::from_request(req, &()).await.unwrap_err() {\n#         JsonRejection::JsonSyntaxError(err) => err,\n#         _ => panic!(),\n#     };\n# \n#     let (_, body) = serde_json_error_response(err);\n#     assert_eq!(body, \"Invalid JSON at line 1 column 1\");\n# }\n```\n\nNote that while this approach works it might break in the future if axum changes\nits implementation to use a different error type internally. Such changes might\nhappen without major breaking versions.\n\n# Defining custom extractors\n\nYou can also define your own extractors by implementing either\n[`FromRequestParts`] or [`FromRequest`].\n\n## Implementing `FromRequestParts`\n\nImplement `FromRequestParts` if your extractor doesn't need access to the\nrequest body:\n\n```rust,no_run\nuse axum::{\n    extract::FromRequestParts,\n    routing::get,\n    Router,\n    http::{\n        StatusCode,\n        header::{HeaderValue, USER_AGENT},\n        request::Parts,\n    },\n};\n\nstruct ExtractUserAgent(HeaderValue);\n\nimpl<S> FromRequestParts<S> for ExtractUserAgent\nwhere\n    S: Send + Sync,\n{\n    type Rejection = (StatusCode, &'static str);\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        if let Some(user_agent) = parts.headers.get(USER_AGENT) {\n            Ok(ExtractUserAgent(user_agent.clone()))\n        } else {\n            Err((StatusCode::BAD_REQUEST, \"`User-Agent` header is missing\"))\n        }\n    }\n}\n\nasync fn handler(ExtractUserAgent(user_agent): ExtractUserAgent) {\n    // ...\n}\n\nlet app = Router::new().route(\"/foo\", get(handler));\n# let _: Router = app;\n```\n\n## Implementing `FromRequest`\n\nIf your extractor needs to consume the request body you must implement [`FromRequest`]\n\n```rust,no_run\nuse axum::{\n    extract::{Request, FromRequest},\n    response::{Response, IntoResponse},\n    body::{Bytes, Body},\n    routing::get,\n    Router,\n    http::{\n        StatusCode,\n        header::{HeaderValue, USER_AGENT},\n    },\n};\n\nstruct ValidatedBody(Bytes);\n\nimpl<S> FromRequest<S> for ValidatedBody\nwhere\n    Bytes: FromRequest<S>,\n    S: Send + Sync,\n{\n    type Rejection = Response;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        let body = Bytes::from_request(req, state)\n            .await\n            .map_err(IntoResponse::into_response)?;\n\n        // do validation...\n\n        Ok(Self(body))\n    }\n}\n\nasync fn handler(ValidatedBody(body): ValidatedBody) {\n    // ...\n}\n\nlet app = Router::new().route(\"/foo\", get(handler));\n# let _: Router = app;\n```\n\n## Cannot implement both `FromRequest` and `FromRequestParts`\n\nNote that you will make your extractor unusable by implementing both\n`FromRequest` and `FromRequestParts` directly for the same type, unless it is\nwrapping another extractor:\n\n```rust,compile_fail\nuse axum::{\n    Router,\n    routing::get,\n    extract::{FromRequest, Request, FromRequestParts},\n    http::request::Parts,\n    body::Body,\n};\nuse std::convert::Infallible;\n\n// Some extractor that doesn't wrap another extractor\nstruct MyExtractor;\n\n// `MyExtractor` implements both `FromRequest`\nimpl<S> FromRequest<S> for MyExtractor\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        // ...\n        # todo!()\n    }\n}\n\n// and `FromRequestParts`\nimpl<S> FromRequestParts<S> for MyExtractor\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        // ...\n        # todo!()\n    }\n}\n\nlet app = Router::new().route(\n    \"/\",\n    // This fails when we go to actually use `MyExtractor` in a handler function.\n    // This is due to a limit in Rust's type system.\n    //\n    // The workaround is to implement either `FromRequest` or `FromRequestParts`\n    // but not both, if your extractor doesn't wrap another extractor.\n    //\n    // See \"Wrapping extractors\" for how to wrap other extractors.\n    get(|_: MyExtractor| async {}),\n);\n# let _: Router = app;\n```\n\n# Accessing other extractors in `FromRequest` or `FromRequestParts` implementations\n\nWhen defining custom extractors you often need to access another extractor\nin your implementation.\n\n```rust\nuse axum::{\n    extract::{Extension, FromRequestParts},\n    http::{StatusCode, HeaderMap, request::Parts},\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\n\n#[derive(Clone)]\nstruct State {\n    // ...\n}\n\nstruct AuthenticatedUser {\n    // ...\n}\n\nimpl<S> FromRequestParts<S> for AuthenticatedUser\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Response;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        // You can either call them directly...\n        let headers = HeaderMap::from_request_parts(parts, state)\n            .await\n            .map_err(|err| match err {})?;\n\n        // ... or use `extract` / `extract_with_state` from `RequestExt` / `RequestPartsExt`\n        use axum::RequestPartsExt;\n        let Extension(state) = parts.extract::<Extension<State>>()\n            .await\n            .map_err(|err| err.into_response())?;\n\n        unimplemented!(\"actually perform the authorization\")\n    }\n}\n\nasync fn handler(user: AuthenticatedUser) {\n    // ...\n}\n\nlet state = State { /* ... */ };\n\nlet app = Router::new().route(\"/\", get(handler)).layer(Extension(state));\n# let _: Router = app;\n```\n\n# Request body limits\n\nFor security reasons, [`Bytes`] will, by default, not accept bodies larger than\n2MB. This also applies to extractors that uses [`Bytes`] internally such as\n`String`, [`Json`], and [`Form`].\n\nFor more details, including how to disable this limit, see [`DefaultBodyLimit`].\n\n# Wrapping extractors\n\nIf you want to write an extractor that generically wraps another extractor\n(that may or may not consume the request body) you should implement both\n[`FromRequest`] and [`FromRequestParts`]:\n\n```rust\nuse axum::{\n    Router,\n    body::Body,\n    routing::get,\n    extract::{Request, FromRequest, FromRequestParts},\n    http::{HeaderMap, request::Parts},\n};\nuse std::time::{Instant, Duration};\n\n// an extractor that wraps another and measures how long time it takes to run\nstruct Timing<E> {\n    extractor: E,\n    duration: Duration,\n}\n\n// we must implement both `FromRequestParts`\nimpl<S, T> FromRequestParts<S> for Timing<T>\nwhere\n    S: Send + Sync,\n    T: FromRequestParts<S>,\n{\n    type Rejection = T::Rejection;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let start = Instant::now();\n        let extractor = T::from_request_parts(parts, state).await?;\n        let duration = start.elapsed();\n        Ok(Timing {\n            extractor,\n            duration,\n        })\n    }\n}\n\n// and `FromRequest`\nimpl<S, T> FromRequest<S> for Timing<T>\nwhere\n    S: Send + Sync,\n    T: FromRequest<S>,\n{\n    type Rejection = T::Rejection;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        let start = Instant::now();\n        let extractor = T::from_request(req, state).await?;\n        let duration = start.elapsed();\n        Ok(Timing {\n            extractor,\n            duration,\n        })\n    }\n}\n\nasync fn handler(\n    // this uses the `FromRequestParts` impl\n    _: Timing<HeaderMap>,\n    // this uses the `FromRequest` impl\n    _: Timing<String>,\n) {}\n# let _: axum::routing::MethodRouter = axum::routing::get(handler);\n```\n\n# Logging rejections\n\nAll built-in extractors will log rejections for easier debugging. To see the\nlogs, enable the `tracing` feature for axum (enabled by default) and the\n`axum::rejection=trace` tracing target, for example with\n`RUST_LOG=info,axum::rejection=trace cargo run`.\n\n[axum-extra]: https://docs.rs/axum-extra/latest/axum_extra/extract/index.html\n[`body::Body`]: crate::body::Body\n[`Bytes`]: crate::body::Bytes\n[customize-extractor-error]: https://github.com/tokio-rs/axum/blob/main/examples/customize-extractor-error/src/main.rs\n[`HeaderMap`]: https://docs.rs/http/latest/http/header/struct.HeaderMap.html\n[`Request`]: https://docs.rs/http/latest/http/struct.Request.html\n[`JsonRejection::JsonDataError`]: rejection::JsonRejection::JsonDataError\n"
  },
  {
    "path": "axum/src/docs/handlers_intro.md",
    "content": "In axum a \"handler\" is an async function that accepts zero or more\n[\"extractors\"](crate::extract) as arguments and returns something that\ncan be converted [into a response](crate::response).\n\nHandlers are where your application logic lives and axum applications are built\nby routing between handlers.\n\n[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html\n"
  },
  {
    "path": "axum/src/docs/method_routing/fallback.md",
    "content": "Add a fallback service to the router.\n\nThis service will be called if no routes matches the incoming request.\n\n```rust\nuse axum::{\n    Router,\n    routing::get,\n    handler::Handler,\n    response::IntoResponse,\n    http::{StatusCode, Method, Uri},\n};\n\nlet handler = get(|| async {}).fallback(fallback);\n\nlet app = Router::new().route(\"/\", handler);\n\nasync fn fallback(method: Method, uri: Uri) -> (StatusCode, String) {\n    (StatusCode::NOT_FOUND, format!(\"`{method}` not allowed for {uri}\"))\n}\n# let _: Router = app;\n```\n\n## When used with `MethodRouter::merge`\n\nTwo routers that both have a fallback cannot be merged. Doing so results in a\npanic:\n\n```rust,should_panic\nuse axum::{\n    routing::{get, post},\n    handler::Handler,\n    response::IntoResponse,\n    http::{StatusCode, Uri},\n};\n\nlet one = get(|| async {}).fallback(fallback_one);\n\nlet two = post(|| async {}).fallback(fallback_two);\n\nlet method_route = one.merge(two);\n\nasync fn fallback_one() -> impl IntoResponse { /* ... */ }\nasync fn fallback_two() -> impl IntoResponse { /* ... */ }\n# let app: axum::Router = axum::Router::new().route(\"/\", method_route);\n```\n\n## Setting the `Allow` header\n\nBy default `MethodRouter` will set the `Allow` header when returning `405 Method\nNot Allowed`. This is also done when the fallback returns `405 Method Not Allowed`\nunless the response generated by the fallback already sets the `Allow` header.\n\nThis means if you use `fallback` to accept additional methods, you should make\nsure you set the `Allow` header correctly.\n"
  },
  {
    "path": "axum/src/docs/method_routing/layer.md",
    "content": "Apply a [`tower::Layer`] to all routes in the router.\n\nThis can be used to add additional processing to a request for a group\nof routes.\n\nNote that the middleware is only applied to existing routes. So you have to\nfirst add your routes (and / or fallback) and then call `layer` afterwards. Additional\nroutes added after `layer` is called will not have the middleware added.\n\nWorks similarly to [`Router::layer`](super::Router::layer). See that method for\nmore details.\n\n# Example\n\n```rust\nuse axum::{routing::get, Router};\nuse tower::limit::ConcurrencyLimitLayer;\n\nasync fn handler() {}\n\nlet app = Router::new().route(\n    \"/\",\n    // All requests to `GET /` will be sent through `ConcurrencyLimitLayer`\n    get(handler).layer(ConcurrencyLimitLayer::new(64)),\n);\n# let _: Router = app;\n```\n"
  },
  {
    "path": "axum/src/docs/method_routing/merge.md",
    "content": "Merge two routers into one.\n\nThis is useful for breaking routers into smaller pieces and combining them\ninto one.\n\n```rust\nuse axum::{\n    routing::{get, post},\n    Router,\n};\n\nlet get = get(|| async {});\nlet post = post(|| async {});\n\nlet merged = get.merge(post);\n\nlet app = Router::new().route(\"/\", merged);\n\n// Our app now accepts\n// - GET /\n// - POST /\n# let _: Router = app;\n```\n"
  },
  {
    "path": "axum/src/docs/method_routing/route_layer.md",
    "content": "Apply a [`tower::Layer`] to the router that will only run if the request matches\na route.\n\nNote that the middleware is only applied to existing routes. First add your routes and then call `route_layer`\nafterwards. Additional routes added after `route_layer` is called will not have\nthe middleware added.\n\nThis works similarly to [`MethodRouter::layer`] except the middleware will only run if\nthe request matches a route. This is useful for middleware that return early\n(such as authorization) which might otherwise convert a `405 Method Not Allowed` into a\n`401 Unauthorized`.\n\n# Example\n\n```rust\nuse axum::{\n    routing::get,\n    Router,\n};\nuse tower_http::validate_request::ValidateRequestHeaderLayer;\n\nlet app = Router::new().route(\n    \"/foo\",\n    get(|| async {})\n        .route_layer(ValidateRequestHeaderLayer::bearer(\"password\"))\n);\n\n// `GET /foo` with a valid token will receive `200 OK`\n// `GET /foo` with a invalid token will receive `401 Unauthorized`\n// `POST /FOO` with a invalid token will receive `405 Method Not Allowed`\n# let _: Router = app;\n```\n"
  },
  {
    "path": "axum/src/docs/middleware.md",
    "content": "# Intro\n\naxum is unique in that it doesn't have its own bespoke middleware system and\ninstead integrates with [`tower`]. This means the ecosystem of [`tower`] and\n[`tower-http`] middleware all work with axum.\n\nWhile it's not necessary to fully understand tower to write or use middleware\nwith axum, having at least a basic understanding of tower's concepts is\nrecommended. See [tower's guides][tower-guides] for a general introduction.\nReading the documentation for [`tower::ServiceBuilder`] is also recommended.\n\n# Applying middleware\n\naxum allows you to add middleware just about anywhere\n\n- To entire routers with [`Router::layer`] and [`Router::route_layer`].\n- To method routers with [`MethodRouter::layer`] and [`MethodRouter::route_layer`].\n- To individual handlers with [`Handler::layer`].\n\n## Applying multiple middleware\n\nIt's recommended to use [`tower::ServiceBuilder`] to apply multiple middleware at\nonce, instead of calling `layer` (or `route_layer`) repeatedly:\n\n```rust\nuse axum::{\n    routing::get,\n    Extension,\n    Router,\n};\nuse tower_http::{trace::TraceLayer};\nuse tower::ServiceBuilder;\n\nasync fn handler() {}\n\n#[derive(Clone)]\nstruct State {}\n\nlet app = Router::new()\n    .route(\"/\", get(handler))\n    .layer(\n        ServiceBuilder::new()\n            .layer(TraceLayer::new_for_http())\n            .layer(Extension(State {}))\n    );\n# let _: Router = app;\n```\n\n# Commonly used middleware\n\nSome commonly used middleware are:\n\n- [`TraceLayer`](tower_http::trace) for high level tracing/logging.\n- [`CorsLayer`](tower_http::cors) for handling CORS.\n- [`CompressionLayer`](tower_http::compression) for automatic compression of responses.\n- [`RequestIdLayer`](tower_http::request_id) and\n  [`PropagateRequestIdLayer`](tower_http::request_id) set and propagate request\n  ids.\n- [`TimeoutLayer`](tower_http::timeout::TimeoutLayer) for timeouts.\n\n# Ordering\n\nWhen you add middleware with [`Router::layer`] (or similar) all previously added\nroutes will be wrapped in the middleware. Generally speaking, this results in\nmiddleware being executed from bottom to top.\n\nSo if you do this:\n\n```rust\nuse axum::{routing::get, Router};\n\nasync fn handler() {}\n\n# let layer_one = axum::Extension(());\n# let layer_two = axum::Extension(());\n# let layer_three = axum::Extension(());\n#\nlet app = Router::new()\n    .route(\"/\", get(handler))\n    .layer(layer_one)\n    .layer(layer_two)\n    .layer(layer_three);\n# let _: Router = app;\n```\n\nThink of the middleware as being layered like an onion where each new layer\nwraps all previous layers:\n\n```not_rust\n        requests\n           |\n           v\n+----- layer_three -----+\n| +---- layer_two ----+ |\n| | +-- layer_one --+ | |\n| | |               | | |\n| | |    handler    | | |\n| | |               | | |\n| | +-- layer_one --+ | |\n| +---- layer_two ----+ |\n+----- layer_three -----+\n           |\n           v\n        responses\n```\n\nThat is:\n\n- First `layer_three` receives the request\n- It then does its thing and passes the request onto `layer_two`\n- Which passes the request onto `layer_one`\n- Which passes the request onto `handler` where a response is produced\n- That response is then passed to `layer_one`\n- Then to `layer_two`\n- And finally to `layer_three` where it's returned out of your app\n\nIt's a little more complicated in practice because any middleware is free to\nreturn early and not call the next layer, for example if a request cannot be\nauthorized, but it's a useful mental model to have.\n\nAs previously mentioned it's recommended to add multiple middleware using\n`tower::ServiceBuilder`, however this impacts ordering:\n\n```rust\nuse tower::ServiceBuilder;\nuse axum::{routing::get, Router};\n\nasync fn handler() {}\n\n# let layer_one = axum::Extension(());\n# let layer_two = axum::Extension(());\n# let layer_three = axum::Extension(());\n#\nlet app = Router::new()\n    .route(\"/\", get(handler))\n    .layer(\n        ServiceBuilder::new()\n            .layer(layer_one)\n            .layer(layer_two)\n            .layer(layer_three),\n    );\n# let _: Router = app;\n```\n\n`ServiceBuilder` works by composing all layers into one such that they run top\nto bottom. So with the previous code `layer_one` would receive the request\nfirst, then `layer_two`, then `layer_three`, then `handler`, and then the\nresponse would bubble back up through `layer_three`, then `layer_two`, and\nfinally `layer_one`.\n\nExecuting middleware top to bottom is generally easier to understand and follow\nmentally which is one of the reasons `ServiceBuilder` is recommended.\n\n# Writing middleware\n\naxum offers many ways of writing middleware, at different levels of abstraction\nand with different pros and cons.\n\n## `axum::middleware::from_fn`\n\nUse [`axum::middleware::from_fn`] to write your middleware when:\n\n- You're not comfortable with implementing your own futures and would rather use\n  the familiar `async`/`await` syntax.\n- You don't intend to publish your middleware as a crate for others to use.\n  Middleware written like this are only compatible with axum.\n\n## `axum::middleware::from_extractor`\n\nUse [`axum::middleware::from_extractor`] to write your middleware when:\n\n- You have a type that you sometimes want to use as an extractor and sometimes\n  as a middleware. If you only need your type as a middleware prefer\n  [`middleware::from_fn`].\n\n## tower's combinators\n\ntower has several utility combinators that can be used to perform simple\nmodifications to requests or responses. The most commonly used ones are\n\n- [`ServiceBuilder::map_request`]\n- [`ServiceBuilder::map_response`]\n- [`ServiceBuilder::then`]\n- [`ServiceBuilder::and_then`]\n\nYou should use these when\n\n- You want to perform a small ad hoc operation, such as adding a header.\n- You don't intend to publish your middleware as a crate for others to use.\n\n## `tower::Service` and `Pin<Box<dyn Future>>`\n\nFor maximum control (and a more low level API) you can write your own middleware\nby implementing [`tower::Service`]:\n\nUse [`tower::Service`] with `Pin<Box<dyn Future>>` to write your middleware when:\n\n- Your middleware needs to be configurable for example via builder methods on\n  your [`tower::Layer`] such as [`tower_http::trace::TraceLayer`].\n- You do intend to publish your middleware as a crate for others to use.\n- You're not comfortable with implementing your own futures.\n\nA decent template for such a middleware could be:\n\n```rust\nuse axum::{\n    response::Response,\n    body::Body,\n    extract::Request,\n};\nuse futures_core::future::BoxFuture;\nuse tower::{Service, Layer};\nuse std::task::{Context, Poll};\n\n#[derive(Clone)]\nstruct MyLayer;\n\nimpl<S> Layer<S> for MyLayer {\n    type Service = MyMiddleware<S>;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        MyMiddleware { inner }\n    }\n}\n\n#[derive(Clone)]\nstruct MyMiddleware<S> {\n    inner: S,\n}\n\nimpl<S> Service<Request> for MyMiddleware<S>\nwhere\n    S: Service<Request, Response = Response> + Send + 'static,\n    S::Future: Send + 'static,\n{\n    type Response = S::Response;\n    type Error = S::Error;\n    // `BoxFuture` is a type alias for `Pin<Box<dyn Future + Send + 'a>>`\n    type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;\n\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, request: Request) -> Self::Future {\n        let future = self.inner.call(request);\n        Box::pin(async move {\n            let response: Response = future.await?;\n            Ok(response)\n        })\n    }\n}\n```\n\nNote that your error type being defined as `S::Error` means that your middleware typically _returns no errors_. As a principle always try to return a response and try not to bail out with a custom error type. For example, if a 3rd party library you are using inside your new middleware returns its own specialized error type, try to convert it to some reasonable response and return `Ok` with that response.\n\nIf you choose to implement a custom error type such as `type Error = BoxError` (a boxed opaque error), or any other error type that is not `Infallible`, you must use a `HandleErrorLayer`, here is an example using a `ServiceBuilder`:\n\n```ignore\nServiceBuilder::new()\n        .layer(HandleErrorLayer::new(|_: BoxError| async {\n            // because axum uses infallible errors, you must handle your custom error type from your middleware here\n            StatusCode::BAD_REQUEST\n        }))\n        .layer(\n             // <your actual layer which DOES return an error>\n        );\n```\n\n## `tower::Service` and custom futures\n\nIf you're comfortable implementing your own futures (or want to learn it) and\nneed as much control as possible then using `tower::Service` without boxed\nfutures is the way to go.\n\nUse [`tower::Service`] with manual futures to write your middleware when:\n\n- You want your middleware to have the lowest possible overhead.\n- Your middleware needs to be configurable for example via builder methods on\n  your [`tower::Layer`] such as [`tower_http::trace::TraceLayer`].\n- You do intend to publish your middleware as a crate for others to use, perhaps\n  as part of tower-http.\n- You're comfortable with implementing your own futures, or want to learn how\n  the lower levels of async Rust works.\n\ntower's [\"Building a middleware from scratch\"][tower-from-scratch-guide]\nguide is a good place to learn how to do this.\n\n# Error handling for middleware\n\naxum's error handling model requires handlers to always return a response.\nHowever middleware is one possible way to introduce errors into an application.\nIf hyper receives an error the connection will be closed without sending a\nresponse. Thus axum requires those errors to be handled gracefully:\n\n```rust\nuse axum::{\n    routing::get,\n    error_handling::HandleErrorLayer,\n    http::StatusCode,\n    BoxError,\n    Router,\n};\nuse tower::{ServiceBuilder, timeout::TimeoutLayer};\nuse std::time::Duration;\n\nasync fn handler() {}\n\nlet app = Router::new()\n    .route(\"/\", get(handler))\n    .layer(\n        ServiceBuilder::new()\n            // this middleware goes above `TimeoutLayer` because it will receive\n            // errors returned by `TimeoutLayer`\n            .layer(HandleErrorLayer::new(|_: BoxError| async {\n                StatusCode::REQUEST_TIMEOUT\n            }))\n            .layer(TimeoutLayer::new(Duration::from_secs(10)))\n    );\n# let _: Router = app;\n```\n\nSee [`error_handling`](crate::error_handling) for more details on axum's error\nhandling model.\n\n# Routing to services/middleware and backpressure\n\nGenerally routing to one of multiple services and backpressure doesn't mix\nwell. Ideally you would want ensure a service is ready to receive a request\nbefore calling it. However, in order to know which service to call, you need\nthe request...\n\nOne approach is to not consider the router service itself ready until all\ndestination services are ready. That is the approach used by\n[`tower::steer::Steer`].\n\nAnother approach is to always consider all services ready (always return\n`Poll::Ready(Ok(()))`) from `Service::poll_ready` and then actually drive\nreadiness inside the response future returned by `Service::call`. This works\nwell when your services don't care about backpressure and are always ready\nanyway.\n\naxum expects that all services used in your app won't care about\nbackpressure and so it uses the latter strategy. However that means you\nshould avoid routing to a service (or using a middleware) that _does_ care\nabout backpressure. At the very least you should [load shed][tower::load_shed]\nso requests are dropped quickly and don't keep piling up.\n\nIt also means that if `poll_ready` returns an error then that error will be\nreturned in the response future from `call` and _not_ from `poll_ready`. In\nthat case, the underlying service will _not_ be discarded and will continue\nto be used for future requests. Services that expect to be discarded if\n`poll_ready` fails should _not_ be used with axum.\n\nOne possible approach is to only apply backpressure sensitive middleware\naround your entire app. This is possible because axum applications are\nthemselves services:\n\n```rust\nuse axum::{\n    routing::get,\n    Router,\n};\nuse tower::ServiceBuilder;\n# let some_backpressure_sensitive_middleware =\n#     tower::layer::util::Identity::new();\n\nasync fn handler() { /* ... */ }\n\nlet app = Router::new().route(\"/\", get(handler));\n\nlet app = ServiceBuilder::new()\n    .layer(some_backpressure_sensitive_middleware)\n    .service(app);\n# let _: Router = app;\n```\n\nHowever when applying middleware around your whole application in this way\nyou have to take care that errors are still being handled appropriately.\n\nAlso note that handlers created from async functions don't care about\nbackpressure and are always ready. So if you're not using any Tower\nmiddleware you don't have to worry about any of this.\n\n# Accessing state in middleware\n\nHow to make state available to middleware depends on how the middleware is\nwritten.\n\n## Accessing state in `axum::middleware::from_fn`\n\nUse [`axum::middleware::from_fn_with_state`](crate::middleware::from_fn_with_state).\n\n## Accessing state in custom `tower::Layer`s\n\n```rust\nuse axum::{\n    Router,\n    routing::get,\n    middleware::{self, Next},\n    response::Response,\n    extract::{State, Request},\n};\nuse tower::{Layer, Service};\nuse std::task::{Context, Poll};\n\n#[derive(Clone)]\nstruct AppState {}\n\n#[derive(Clone)]\nstruct MyLayer {\n    state: AppState,\n}\n\nimpl<S> Layer<S> for MyLayer {\n    type Service = MyService<S>;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        MyService {\n            inner,\n            state: self.state.clone(),\n        }\n    }\n}\n\n#[derive(Clone)]\nstruct MyService<S> {\n    inner: S,\n    state: AppState,\n}\n\nimpl<S, B> Service<Request<B>> for MyService<S>\nwhere\n    S: Service<Request<B>>,\n{\n    type Response = S::Response;\n    type Error = S::Error;\n    type Future = S::Future;\n\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        // Do something with `self.state`.\n        //\n        // See `axum::RequestExt` for how to run extractors directly from\n        // a `Request`.\n\n        self.inner.call(req)\n    }\n}\n\nasync fn handler(_: State<AppState>) {}\n\nlet state = AppState {};\n\nlet app = Router::new()\n    .route(\"/\", get(handler))\n    .layer(MyLayer { state: state.clone() })\n    .with_state(state);\n# let _: axum::Router = app;\n```\n\n# Passing state from middleware to handlers\n\nState can be passed from middleware to handlers using [request extensions]:\n\n```rust\nuse axum::{\n    Router,\n    http::StatusCode,\n    routing::get,\n    response::{IntoResponse, Response},\n    middleware::{self, Next},\n    extract::{Request, Extension},\n};\n\n#[derive(Clone)]\nstruct CurrentUser { /* ... */ }\n\nasync fn auth(mut req: Request, next: Next) -> Result<Response, StatusCode> {\n    let auth_header = req.headers()\n        .get(http::header::AUTHORIZATION)\n        .and_then(|header| header.to_str().ok());\n\n    let auth_header = if let Some(auth_header) = auth_header {\n        auth_header\n    } else {\n        return Err(StatusCode::UNAUTHORIZED);\n    };\n\n    if let Some(current_user) = authorize_current_user(auth_header).await {\n        // insert the current user into a request extension so the handler can\n        // extract it\n        req.extensions_mut().insert(current_user);\n        Ok(next.run(req).await)\n    } else {\n        Err(StatusCode::UNAUTHORIZED)\n    }\n}\n\nasync fn authorize_current_user(auth_token: &str) -> Option<CurrentUser> {\n    // ...\n    # unimplemented!()\n}\n\nasync fn handler(\n    // extract the current user, set by the middleware\n    Extension(current_user): Extension<CurrentUser>,\n) {\n    // ...\n}\n\nlet app = Router::new()\n    .route(\"/\", get(handler))\n    .route_layer(middleware::from_fn(auth));\n# let _: Router = app;\n```\n\n[Response extensions] can also be used but note that request extensions are not\nautomatically moved to response extensions. You need to manually do that for the\nextensions you need.\n\n# Rewriting request URI in middleware\n\nMiddleware added with [`Router::layer`] will run after routing. That means it\ncannot be used to run middleware that rewrites the request URI. By the time the\nmiddleware runs the routing is already done.\n\nThe workaround is to wrap the middleware around the entire `Router` (this works\nbecause `Router` implements [`Service`]):\n\n```rust\nuse tower::Layer;\nuse axum::{\n    Router,\n    ServiceExt, // for `into_make_service`\n    response::Response,\n    middleware::Next,\n    extract::Request,\n};\n\nfn rewrite_request_uri<B>(req: Request<B>) -> Request<B> {\n    // ...\n    # req\n}\n\n// this can be any `tower::Layer`\nlet middleware = tower::util::MapRequestLayer::new(rewrite_request_uri);\n\nlet app = Router::new();\n\n// apply the layer around the whole `Router`\n// this way the middleware will run before `Router` receives the request\nlet app_with_middleware = middleware.layer(app);\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, app_with_middleware.into_make_service()).await;\n# };\n```\n\n[`tower`]: https://crates.io/crates/tower\n[`tower-http`]: https://crates.io/crates/tower-http\n[tower-guides]: https://github.com/tower-rs/tower/tree/master/guides\n[`axum::middleware::from_fn`]: fn@crate::middleware::from_fn\n[`middleware::from_fn`]: fn@crate::middleware::from_fn\n[tower-from-scratch-guide]: https://github.com/tower-rs/tower/blob/master/guides/building-a-middleware-from-scratch.md\n[`ServiceBuilder::map_request`]: tower::ServiceBuilder::map_request\n[`ServiceBuilder::map_response`]: tower::ServiceBuilder::map_response\n[`ServiceBuilder::then`]: tower::ServiceBuilder::then\n[`ServiceBuilder::and_then`]: tower::ServiceBuilder::and_then\n[`axum::middleware::from_extractor`]: fn@crate::middleware::from_extractor\n[`Handler::layer`]: crate::handler::Handler::layer\n[`Router::layer`]: crate::routing::Router::layer\n[`MethodRouter::layer`]: crate::routing::MethodRouter::layer\n[`Router::route_layer`]: crate::routing::Router::route_layer\n[`MethodRouter::route_layer`]: crate::routing::MethodRouter::route_layer\n[request extensions]: https://docs.rs/http/latest/http/request/struct.Request.html#method.extensions\n[Response extensions]: https://docs.rs/http/latest/http/response/struct.Response.html#method.extensions\n[`State`]: crate::extract::State\n[`Service`]: tower::Service\n"
  },
  {
    "path": "axum/src/docs/response.md",
    "content": "Types and traits for generating responses.\n\n# Building responses\n\nAnything that implements [`IntoResponse`] can be returned from a handler. axum\nprovides implementations for common types:\n\n```rust,no_run\nuse axum::{\n    Json,\n    response::{Html, IntoResponse},\n    http::{StatusCode, Uri, header::{self, HeaderMap, HeaderName}},\n};\n\n// `()` gives an empty response\nasync fn empty() {}\n\n// String will get a `text/plain; charset=utf-8` content-type\nasync fn plain_text(uri: Uri) -> String {\n    format!(\"Hi from {}\", uri.path())\n}\n\n// Bytes will get a `application/octet-stream` content-type\nasync fn bytes() -> Vec<u8> {\n    vec![1, 2, 3, 4]\n}\n\n// `Json` will get a `application/json` content-type and work with anything that\n// implements `serde::Serialize`\nasync fn json() -> Json<Vec<String>> {\n    Json(vec![\"foo\".to_owned(), \"bar\".to_owned()])\n}\n\n// `Html` will get a `text/html` content-type\nasync fn html() -> Html<&'static str> {\n    Html(\"<p>Hello, World!</p>\")\n}\n\n// `StatusCode` gives an empty response with that status code\nasync fn status() -> StatusCode {\n    StatusCode::NOT_FOUND\n}\n\n// `HeaderMap` gives an empty response with some headers\nasync fn headers() -> HeaderMap {\n    let mut headers = HeaderMap::new();\n    headers.insert(header::SERVER, \"axum\".parse().unwrap());\n    headers\n}\n\n// An array of tuples also gives headers\nasync fn array_headers() -> [(HeaderName, &'static str); 2] {\n    [\n        (header::SERVER, \"axum\"),\n        (header::CONTENT_TYPE, \"text/plain\")\n    ]\n}\n\n// Use `impl IntoResponse` to avoid writing the whole type\nasync fn impl_trait() -> impl IntoResponse {\n    [\n        (header::SERVER, \"axum\"),\n        (header::CONTENT_TYPE, \"text/plain\")\n    ]\n}\n```\n\nAdditionally you can return tuples to build more complex responses from\nindividual parts.\n\n```rust,no_run\nuse axum::{\n    Json,\n    response::IntoResponse,\n    http::{StatusCode, HeaderMap, Uri, header},\n    extract::Extension,\n};\n\n// `(StatusCode, impl IntoResponse)` will override the status code of the response\nasync fn with_status(uri: Uri) -> (StatusCode, String) {\n    (StatusCode::NOT_FOUND, format!(\"Not Found: {}\", uri.path()))\n}\n\n// Use `impl IntoResponse` to avoid having to type the whole type\nasync fn impl_trait(uri: Uri) -> impl IntoResponse {\n    (StatusCode::NOT_FOUND, format!(\"Not Found: {}\", uri.path()))\n}\n\n// `(HeaderMap, impl IntoResponse)` to add additional headers\nasync fn with_headers() -> impl IntoResponse {\n    let mut headers = HeaderMap::new();\n    headers.insert(header::CONTENT_TYPE, \"text/plain\".parse().unwrap());\n    (headers, \"foo\")\n}\n\n// Or an array of tuples to more easily build the headers\nasync fn with_array_headers() -> impl IntoResponse {\n    ([(header::CONTENT_TYPE, \"text/plain\")], \"foo\")\n}\n\n// Use string keys for custom headers\nasync fn with_array_headers_custom() -> impl IntoResponse {\n    ([(\"x-custom\", \"custom\")], \"foo\")\n}\n\n// `(StatusCode, headers, impl IntoResponse)` to set status and add headers\n// `headers` can be either a `HeaderMap` or an array of tuples\nasync fn with_status_and_array_headers() -> impl IntoResponse {\n    (\n        StatusCode::NOT_FOUND,\n        [(header::CONTENT_TYPE, \"text/plain\")],\n        \"foo\",\n    )\n}\n\n// `(Extension<_>, impl IntoResponse)` to set response extensions\nasync fn with_status_extensions() -> impl IntoResponse {\n    (\n        Extension(Foo(\"foo\")),\n        \"foo\",\n    )\n}\n\n#[derive(Clone)]\nstruct Foo(&'static str);\n\n// Or mix and match all the things\nasync fn all_the_things(uri: Uri) -> impl IntoResponse {\n    let mut header_map = HeaderMap::new();\n    if uri.path() == \"/\" {\n        header_map.insert(header::SERVER, \"axum\".parse().unwrap());\n    }\n\n    (\n        // set status code\n        StatusCode::NOT_FOUND,\n        // headers with an array\n        [(\"x-custom\", \"custom\")],\n        // some extensions\n        Extension(Foo(\"foo\")),\n        Extension(Foo(\"bar\")),\n        // more headers, built dynamically\n        header_map,\n        // and finally the body\n        \"foo\",\n    )\n}\n```\n\nIn general you can return tuples like:\n\n- `(StatusCode, impl IntoResponse)`\n- `(Parts, impl IntoResponse)`\n- `(Response<()>, impl IntoResponse)`\n- `(T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].\n- `(StatusCode, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].\n- `(Parts, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].\n- `(Response<()>, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].\n\nThis means you cannot accidentally override the status or body as [`IntoResponseParts`] only allows\nsetting headers and extensions.\n\nUse [`Response`] for more low level control:\n\n```rust,no_run\nuse axum::{\n    Json,\n    response::{IntoResponse, Response},\n    body::Body,\n    http::StatusCode,\n};\n\nasync fn response() -> Response {\n    Response::builder()\n        .status(StatusCode::NOT_FOUND)\n        .header(\"x-foo\", \"custom header\")\n        .body(Body::from(\"not found\"))\n        .unwrap()\n}\n```\n\n# Returning different response types\n\nIf you need to return multiple response types, and `Result<T, E>` isn't appropriate, you can call\n`.into_response()` to turn things into `axum::response::Response`:\n\n```rust\nuse axum::{\n    response::{IntoResponse, Redirect, Response},\n    http::StatusCode,\n};\n\nasync fn handle() -> Response {\n    if something() {\n        \"All good!\".into_response()\n    } else if something_else() {\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            \"Something went wrong...\",\n        ).into_response()\n    } else {\n        Redirect::to(\"/\").into_response()\n    }\n}\n\nfn something() -> bool {\n    // ...\n    # true\n}\n\nfn something_else() -> bool {\n    // ...\n    # true\n}\n```\n\n# Regarding `impl IntoResponse`\n\nYou can use `impl IntoResponse` as the return type from handlers to avoid\ntyping large types. For example\n\n```rust\nuse axum::http::StatusCode;\n\nasync fn handler() -> (StatusCode, [(&'static str, &'static str); 1], &'static str) {\n    (StatusCode::OK, [(\"x-foo\", \"bar\")], \"Hello, World!\")\n}\n```\n\nBecomes easier using `impl IntoResponse`:\n\n```rust\nuse axum::{http::StatusCode, response::IntoResponse};\n\nasync fn impl_into_response() -> impl IntoResponse {\n    (StatusCode::OK, [(\"x-foo\", \"bar\")], \"Hello, World!\")\n}\n```\n\nHowever `impl IntoResponse` has a few limitations. Firstly it can only be used\nto return a single type:\n\n```rust,compile_fail\nuse axum::{http::StatusCode, response::IntoResponse};\n\nasync fn handler() -> impl IntoResponse {\n    if check_something() {\n        StatusCode::NOT_FOUND\n    } else {\n        \"Hello, World!\"\n    }\n}\n\nfn check_something() -> bool {\n    # false\n    // ...\n}\n```\n\nThis function returns either a `StatusCode` or a `&'static str` which `impl\nTrait` doesn't allow.\n\nSecondly `impl IntoResponse` can lead to type inference issues when used with\n`Result` and `?`:\n\n```rust,compile_fail\nuse axum::{http::StatusCode, response::IntoResponse};\n\nasync fn handler() -> impl IntoResponse {\n    create_thing()?;\n    Ok(StatusCode::CREATED)\n}\n\nfn create_thing() -> Result<(), StatusCode> {\n    # Ok(())\n    // ...\n}\n```\n\nThis is because `?` supports using the [`From`] trait to convert to a different\nerror type but it doesn't know which type to convert to, because we only\nspecified `impl IntoResponse` as the return type.\n\n`Result<impl IntoResponse, impl IntoResponse>` doesn't always work either:\n\n```rust,compile_fail\nuse axum::{http::StatusCode, response::IntoResponse};\n\nasync fn handler() -> Result<impl IntoResponse, impl IntoResponse> {\n    create_thing()?;\n    Ok(StatusCode::CREATED)\n}\n\nfn create_thing() -> Result<(), StatusCode> {\n    # Ok(())\n    // ...\n}\n```\n\nThe solution is to use a concrete error type, such as `Result<impl IntoResponse, StatusCode>`:\n\n```rust\nuse axum::{http::StatusCode, response::IntoResponse};\n\nasync fn handler() -> Result<impl IntoResponse, StatusCode> {\n    create_thing()?;\n    Ok(StatusCode::CREATED)\n}\n\nfn create_thing() -> Result<(), StatusCode> {\n    # Ok(())\n    // ...\n}\n```\n\nBecause of this it is generally not recommended to use `impl IntoResponse`\nunless you're familiar with the details of how `impl Trait` works.\n\n[`IntoResponse`]: crate::response::IntoResponse\n[`IntoResponseParts`]: crate::response::IntoResponseParts\n[`StatusCode`]: http::StatusCode\n"
  },
  {
    "path": "axum/src/docs/routing/fallback.md",
    "content": "Add a fallback [`Handler`] to the router.\n\nThis service will be called if no routes matches the incoming request.\n\n```rust\nuse axum::{\n    Router,\n    routing::get,\n    handler::Handler,\n    response::IntoResponse,\n    http::{StatusCode, Uri},\n};\n\nlet app = Router::new()\n    .route(\"/foo\", get(|| async { /* ... */ }))\n    .fallback(fallback);\n\nasync fn fallback(uri: Uri) -> (StatusCode, String) {\n    (StatusCode::NOT_FOUND, format!(\"No route for {uri}\"))\n}\n# let _: Router = app;\n```\n\nFallbacks only apply to routes that aren't matched by anything in the\nrouter. If a handler is matched by a request but returns 404 the\nfallback is not called. Note that this applies to [`MethodRouter`]s too: if the\nrequest hits a valid path but the [`MethodRouter`] does not have an appropriate\nmethod handler installed, the fallback is not called (use\n[`MethodRouter::fallback`] for this purpose instead).\n\n\n# Handling all requests without other routes\n\nUsing `Router::new().fallback(...)` to accept all request regardless of path or\nmethod, if you don't have other routes, isn't optimal:\n\n```rust\nuse axum::Router;\n\nasync fn handler() {}\n\nlet app = Router::new().fallback(handler);\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, app).await;\n# };\n```\n\nRunning the handler directly is faster since it avoids the overhead of routing:\n\n```rust\nuse axum::handler::HandlerWithoutStateExt;\n\nasync fn handler() {}\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, handler.into_make_service()).await;\n# };\n```\n"
  },
  {
    "path": "axum/src/docs/routing/into_make_service_with_connect_info.md",
    "content": "Convert this router into a [`MakeService`], that will store `C`'s\nassociated `ConnectInfo` in a request extension such that [`ConnectInfo`]\ncan extract it.\n\nThis enables extracting things like the client's remote address.\n\nExtracting [`std::net::SocketAddr`] is supported out of the box:\n\n```rust\nuse axum::{\n    extract::ConnectInfo,\n    routing::get,\n    Router,\n};\nuse std::net::SocketAddr;\n\nlet app = Router::new().route(\"/\", get(handler));\n\nasync fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {\n    format!(\"Hello {addr}\")\n}\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await;\n# };\n```\n\nYou can implement custom a [`Connected`] like so:\n\n```rust\nuse axum::{\n    extract::connect_info::{ConnectInfo, Connected},\n    routing::get,\n    serve::IncomingStream,\n    Router,\n};\nuse tokio::net::TcpListener;\n\nlet app = Router::new().route(\"/\", get(handler));\n\nasync fn handler(\n    ConnectInfo(my_connect_info): ConnectInfo<MyConnectInfo>,\n) -> String {\n    format!(\"Hello {my_connect_info:?}\")\n}\n\n#[derive(Clone, Debug)]\nstruct MyConnectInfo {\n    // ...\n}\n\nimpl Connected<IncomingStream<'_, TcpListener>> for MyConnectInfo {\n    fn connect_info(target: IncomingStream<'_, TcpListener>) -> Self {\n        MyConnectInfo {\n            // ...\n        }\n    }\n}\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, app.into_make_service_with_connect_info::<MyConnectInfo>()).await;\n# };\n```\n\nSee the [unix domain socket example][uds] for an example of how to use\nthis to collect UDS connection info.\n\n[`MakeService`]: tower::make::MakeService\n[`Connected`]: crate::extract::connect_info::Connected\n[`ConnectInfo`]: crate::extract::connect_info::ConnectInfo\n[uds]: https://github.com/tokio-rs/axum/blob/main/examples/unix-domain-socket/src/main.rs\n"
  },
  {
    "path": "axum/src/docs/routing/layer.md",
    "content": "Apply a [`tower::Layer`] to all routes in the router.\n\nThis can be used to add additional processing to a request for a group\nof routes.\n\nNote that the middleware is only applied to existing routes. So you have to\nfirst add your routes (and / or fallback) and then call `layer` afterwards. Additional\nroutes added after `layer` is called will not have the middleware added.\n\nIf you want to add middleware to a single handler you can either use\n[`MethodRouter::layer`] or [`Handler::layer`].\n\n# Example\n\nAdding the [`tower_http::trace::TraceLayer`]:\n\n```rust\nuse axum::{routing::get, Router};\nuse tower_http::trace::TraceLayer;\n\nlet app = Router::new()\n    .route(\"/foo\", get(|| async {}))\n    .route(\"/bar\", get(|| async {}))\n    .layer(TraceLayer::new_for_http());\n# let _: Router = app;\n```\n\nIf you need to write your own middleware see [\"Writing\nmiddleware\"](crate::middleware#writing-middleware) for the different options.\n\nIf you only want middleware on some routes you can use [`Router::merge`]:\n\n```rust\nuse axum::{routing::get, Router};\nuse tower_http::{trace::TraceLayer, compression::CompressionLayer};\n\nlet with_tracing = Router::new()\n    .route(\"/foo\", get(|| async {}))\n    .layer(TraceLayer::new_for_http());\n\nlet with_compression = Router::new()\n    .route(\"/bar\", get(|| async {}))\n    .layer(CompressionLayer::new());\n\n// Merge everything into one `Router`\nlet app = Router::new()\n    .merge(with_tracing)\n    .merge(with_compression);\n# let _: Router = app;\n```\n\n# Multiple middleware\n\nIt's recommended to use [`tower::ServiceBuilder`] when applying multiple\nmiddleware. See [`middleware`](crate::middleware) for more details.\n\n# Runs after routing\n\nMiddleware added with this method will run _after_ routing and thus cannot be\nused to rewrite the request URI. See [\"Rewriting request URI in\nmiddleware\"](crate::middleware#rewriting-request-uri-in-middleware) for more\ndetails and a workaround.\n\n# Error handling\n\nSee [`middleware`](crate::middleware) for details on how error handling impacts\nmiddleware.\n"
  },
  {
    "path": "axum/src/docs/routing/merge.md",
    "content": "Merge the paths and fallbacks of two routers into a single [`Router`].\n\nThis is useful for breaking apps into smaller pieces and combining them\ninto one.\n\n```rust\nuse axum::{\n    routing::get,\n    Router,\n};\n#\n# async fn users_list() {}\n# async fn users_show() {}\n# async fn teams_list() {}\n\n// define some routes separately\nlet user_routes = Router::new()\n    .route(\"/users\", get(users_list))\n    .route(\"/users/{id}\", get(users_show));\n\nlet team_routes = Router::new()\n    .route(\"/teams\", get(teams_list));\n\n// combine them into one\nlet app = Router::new()\n    .merge(user_routes)\n    .merge(team_routes);\n\n// could also do `user_routes.merge(team_routes)`\n\n// Our app now accepts\n// - GET /users\n// - GET /users/{id}\n// - GET /teams\n# let _: Router = app;\n```\n\n# Merging routers with state\n\nWhen combining [`Router`]s with this method, each [`Router`] must have the\nsame type of state. If your routers have different types you can use\n[`Router::with_state`] to provide the state and make the types match:\n\n```rust\nuse axum::{\n    Router,\n    routing::get,\n    extract::State,\n};\n\n#[derive(Clone)]\nstruct InnerState {}\n\n#[derive(Clone)]\nstruct OuterState {}\n\nasync fn inner_handler(state: State<InnerState>) {}\n\nlet inner_router = Router::new()\n    .route(\"/bar\", get(inner_handler))\n    .with_state(InnerState {});\n\nasync fn outer_handler(state: State<OuterState>) {}\n\nlet app = Router::new()\n    .route(\"/\", get(outer_handler))\n    .merge(inner_router)\n    .with_state(OuterState {});\n# let _: axum::Router = app;\n```\n\n# Merging routers with fallbacks\n\nWhen combining [`Router`]s with this method, the [fallback](Router::fallback) is also merged.\nHowever only one of the routers can have a fallback.\n\n# Panics\n\n- If two routers that each have a [fallback](Router::fallback) are merged. This\n  is because `Router` only allows a single fallback.\n"
  },
  {
    "path": "axum/src/docs/routing/method_not_allowed_fallback.md",
    "content": "Add a fallback [`Handler`] for the case where a route exists, but the method of the request is not supported.\n\nSets a fallback on all previously registered [`MethodRouter`]s,\nto be called when no matching method handler is set.\n\n```rust,no_run\nuse axum::{response::IntoResponse, routing::get, Router};\n\nasync fn hello_world() -> impl IntoResponse {\n    \"Hello, world!\\n\"\n}\n\nasync fn default_fallback() -> impl IntoResponse {\n    \"Default fallback\\n\"\n}\n\nasync fn handle_405() -> impl IntoResponse {\n    \"Method not allowed fallback\"\n}\n\n#[tokio::main]\nasync fn main() {\n    let router = Router::new()\n        .route(\"/\", get(hello_world))\n        .fallback(default_fallback)\n        .method_not_allowed_fallback(handle_405);\n\n    let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n\n    axum::serve(listener, router).await;\n}\n```\n\nThe fallback only applies if there is a `MethodRouter` registered for a given path, \nbut the method used in the request is not specified. In the example, a `GET` on \n`http://localhost:3000` causes the `hello_world` handler to react, while issuing a \n`POST` triggers `handle_405`. Calling an entirely different route, like `http://localhost:3000/hello` \ncauses `default_fallback` to run.\n"
  },
  {
    "path": "axum/src/docs/routing/nest.md",
    "content": "Nest a [`Router`] at some path.\n\nThis allows you to break your application into smaller pieces and compose\nthem together.\n\n# Example\n\n```rust\nuse axum::{\n    routing::{get, post},\n    Router,\n};\n\nlet user_routes = Router::new().route(\"/{id}\", get(|| async {}));\n\nlet team_routes = Router::new().route(\"/\", post(|| async {}));\n\nlet api_routes = Router::new()\n    .nest(\"/users\", user_routes)\n    .nest(\"/teams\", team_routes);\n\nlet app = Router::new().nest(\"/api\", api_routes);\n\n// Our app now accepts\n// - GET /api/users/{id}\n// - POST /api/teams\n# let _: Router = app;\n```\n\n# How the URI changes\n\nNote that nested routes will not see the original request URI but instead\nhave the matched prefix stripped. This is necessary for services like static\nfile serving to work. Use [`OriginalUri`] if you need the original request\nURI.\n\n# Captures from outer routes\n\nTake care when using `nest` together with dynamic routes as nesting also\ncaptures from the outer routes:\n\n```rust\nuse axum::{\n    extract::Path,\n    routing::get,\n    Router,\n};\nuse std::collections::HashMap;\n\nasync fn users_get(Path(params): Path<HashMap<String, String>>) {\n    // Both `version` and `id` were captured even though `users_api` only\n    // explicitly captures `id`.\n    let version = params.get(\"version\");\n    let id = params.get(\"id\");\n}\n\nlet users_api = Router::new().route(\"/users/{id}\", get(users_get));\n\nlet app = Router::new().nest(\"/{version}/api\", users_api);\n# let _: Router = app;\n```\n\n# Differences from wildcard routes\n\nNested routes are similar to wildcard routes. The difference is that\nwildcard routes still see the whole URI whereas nested routes will have\nthe prefix stripped:\n\n```rust\nuse axum::{routing::get, http::Uri, Router};\n\nlet nested_router = Router::new()\n    .route(\"/\", get(|uri: Uri| async {\n        // `uri` will _not_ contain `/bar`\n    }));\n\nlet app = Router::new()\n    .route(\"/foo/{*rest}\", get(|uri: Uri| async {\n        // `uri` will contain `/foo`\n    }))\n    .nest(\"/bar\", nested_router);\n# let _: Router = app;\n```\n\nAdditionally, while the wildcard route `/foo/*rest` will not match the\npaths `/foo` or `/foo/`, a nested router at `/foo` will match the path `/foo`\n(but not `/foo/`), and a nested router at `/foo/` will match the path `/foo/`\n(but not `/foo`).\n\n# Fallbacks\n\nIf a nested router doesn't have its own fallback then it will inherit the\nfallback from the outer router:\n\n```rust\nuse axum::{routing::get, http::StatusCode, handler::Handler, Router};\n\nasync fn fallback() -> (StatusCode, &'static str) {\n    (StatusCode::NOT_FOUND, \"Not Found\")\n}\n\nlet api_routes = Router::new().route(\"/users\", get(|| async {}));\n\nlet app = Router::new()\n    .nest(\"/api\", api_routes)\n    .fallback(fallback);\n# let _: Router = app;\n```\n\nHere requests like `GET /api/not-found` will go into `api_routes` but because\nit doesn't have a matching route and doesn't have its own fallback it will call\nthe fallback from the outer router, i.e. the `fallback` function.\n\nIf the nested router has its own fallback then the outer fallback will not be\ninherited:\n\n```rust\nuse axum::{\n    routing::get,\n    http::StatusCode,\n    handler::Handler,\n    Json,\n    Router,\n};\n\nasync fn fallback() -> (StatusCode, &'static str) {\n    (StatusCode::NOT_FOUND, \"Not Found\")\n}\n\nasync fn api_fallback() -> (StatusCode, Json<serde_json::Value>) {\n    (\n        StatusCode::NOT_FOUND,\n        Json(serde_json::json!({ \"status\": \"Not Found\" })),\n    )\n}\n\nlet api_routes = Router::new()\n    .route(\"/users\", get(|| async {}))\n    .fallback(api_fallback);\n\nlet app = Router::new()\n    .nest(\"/api\", api_routes)\n    .fallback(fallback);\n# let _: Router = app;\n```\n\nHere requests like `GET /api/not-found` will go to `api_fallback`.\n\n# Nesting routers with state\n\nWhen combining [`Router`]s with this method, each [`Router`] must have the\nsame type of state. If your routers have different types you can use\n[`Router::with_state`] to provide the state and make the types match:\n\n```rust\nuse axum::{\n    Router,\n    routing::get,\n    extract::State,\n};\n\n#[derive(Clone)]\nstruct InnerState {}\n\n#[derive(Clone)]\nstruct OuterState {}\n\nasync fn inner_handler(state: State<InnerState>) {}\n\nlet inner_router = Router::new()\n    .route(\"/bar\", get(inner_handler))\n    .with_state(InnerState {});\n\nasync fn outer_handler(state: State<OuterState>) {}\n\nlet app = Router::new()\n    .route(\"/\", get(outer_handler))\n    .nest(\"/foo\", inner_router)\n    .with_state(OuterState {});\n# let _: axum::Router = app;\n```\n\nNote that the inner router will still inherit the fallback from the outer\nrouter.\n\n# Panics\n\n- If the route overlaps with another route. See [`Router::route`]\n  for more details.\n- If the route contains a wildcard (`*`).\n- If `path` is empty.\n\n[`OriginalUri`]: crate::extract::OriginalUri\n[fallbacks]: Router::fallback\n"
  },
  {
    "path": "axum/src/docs/routing/route.md",
    "content": "Add another route to the router.\n\n`path` is a string of path segments separated by `/`. Each segment\ncan be either static, a capture, or a wildcard.\n\n`method_router` is the [`MethodRouter`] that should receive the request if the\npath matches `path`. Usually, `method_router` will be a handler wrapped in a method\nrouter like [`get`]. See [`handler`](crate::handler) for more details on handlers.\n\n# Static paths\n\nExamples:\n\n- `/`\n- `/foo`\n- `/users/123`\n\nIf the incoming request matches the path exactly the corresponding service will\nbe called.\n\n# Captures\n\nPaths can contain segments like `/{key}` which matches any single segment and\nwill store the value captured at `key`. The value captured can be zero-length\nexcept for in the invalid path `//`.\n\nExamples:\n\n- `/{key}`\n- `/users/{id}`\n- `/users/{id}/tweets`\n\nCaptures can be extracted using [`Path`](crate::extract::Path). See its\ndocumentation for more details.\n\nIt is not possible to create segments that only match some types like numbers or\nregular expression. You must handle that manually in your handlers.\n\n[`MatchedPath`] can be used to extract the matched path rather than the actual path.\n\n# Wildcards\n\nPaths can end in `/{*key}` which matches all segments and will store the segments\ncaptured at `key`.\n\nExamples:\n\n- `/{*key}`\n- `/assets/{*path}`\n- `/{id}/{repo}/{*tree}`\n\nNote that `/{*key}` doesn't match empty segments. Thus:\n\n- `/{*key}` doesn't match `/` but does match `/a`, `/a/`, etc.\n- `/x/{*key}` doesn't match `/x` or `/x/` but does match `/x/a`, `/x/a/`, etc.\n\nWildcard captures can also be extracted using [`Path`](crate::extract::Path):\n\n```rust\nuse axum::{\n    Router,\n    routing::get,\n    extract::Path,\n};\n\nlet app: Router = Router::new().route(\"/{*key}\", get(handler));\n\nasync fn handler(Path(path): Path<String>) -> String {\n    path\n}\n```\n\nNote that the leading slash is not included, i.e. for the route `/foo/{*rest}` and\nthe path `/foo/bar/baz` the value of `rest` will be `bar/baz`.\n\n# Accepting multiple methods\n\nTo accept multiple methods for the same route you can add all handlers at the\nsame time:\n\n```rust\nuse axum::{Router, routing::{get, delete}, extract::Path};\n\nlet app = Router::new().route(\n    \"/\",\n    get(get_root).post(post_root).delete(delete_root),\n);\n\nasync fn get_root() {}\n\nasync fn post_root() {}\n\nasync fn delete_root() {}\n# let _: Router = app;\n```\n\nOr you can add them one by one:\n\n```rust\n# use axum::Router;\n# use axum::routing::{get, post, delete};\n#\nlet app = Router::new()\n    .route(\"/\", get(get_root))\n    .route(\"/\", post(post_root))\n    .route(\"/\", delete(delete_root));\n#\n# let _: Router = app;\n# async fn get_root() {}\n# async fn post_root() {}\n# async fn delete_root() {}\n```\n\n# More examples\n\n```rust\nuse axum::{Router, routing::{get, delete}, extract::Path};\n\nlet app = Router::new()\n    .route(\"/\", get(root))\n    .route(\"/users\", get(list_users).post(create_user))\n    .route(\"/users/{id}\", get(show_user))\n    .route(\"/api/{version}/users/{id}/action\", delete(do_users_action))\n    .route(\"/assets/{*path}\", get(serve_asset));\n\nasync fn root() {}\n\nasync fn list_users() {}\n\nasync fn create_user() {}\n\nasync fn show_user(Path(id): Path<u64>) {}\n\nasync fn do_users_action(Path((version, id)): Path<(String, u64)>) {}\n\nasync fn serve_asset(Path(path): Path<String>) {}\n# let _: Router = app;\n```\n\n# Panics\n\nPanics if the route overlaps with another route:\n\n```rust,should_panic\nuse axum::{routing::get, Router};\n\nlet app = Router::new()\n    .route(\"/\", get(|| async {}))\n    .route(\"/\", get(|| async {}));\n# let _: Router = app;\n```\n\nThe static route `/foo` and the dynamic route `/{key}` are not considered to\noverlap and `/foo` will take precedence.\n\nAlso panics if `path` is empty.\n"
  },
  {
    "path": "axum/src/docs/routing/route_layer.md",
    "content": "Apply a [`tower::Layer`] to the router that will only run if the request matches\na route.\n\nNote that the middleware is only applied to existing routes. So you have to\nfirst add your routes (and / or fallback) and then call `route_layer`\nafterwards. Additional routes added after `route_layer` is called will not have\nthe middleware added.\n\nThis works similarly to [`Router::layer`] except the middleware will only run if\nthe request matches a route. This is useful for middleware that return early\n(such as authorization) which might otherwise convert a `404 Not Found` into a\n`401 Unauthorized`.\n\nThis function will panic if no routes have been declared yet on the router,\nsince the new layer will have no effect, and this is typically a bug.\nIn generic code, you can test if that is the case first, by calling [`Router::has_routes`].\n\n# Example\n\n```rust\nuse axum::{\n    routing::get,\n    Router,\n};\nuse tower_http::validate_request::ValidateRequestHeaderLayer;\n\nlet app = Router::new()\n    .route(\"/foo\", get(|| async {}))\n    .route_layer(ValidateRequestHeaderLayer::bearer(\"password\"));\n\n// `GET /foo` with a valid token will receive `200 OK`\n// `GET /foo` with a invalid token will receive `401 Unauthorized`\n// `GET /not-found` with a invalid token will receive `404 Not Found`\n# let _: Router = app;\n```\n"
  },
  {
    "path": "axum/src/docs/routing/route_service.md",
    "content": "Add another route to the router that calls a [`Service`].\n\n# Example\n\n```rust,no_run\nuse axum::{\n    Router,\n    body::Body,\n    routing::{any_service, get_service},\n    extract::Request,\n    http::StatusCode,\n    error_handling::HandleErrorLayer,\n};\nuse tower_http::services::ServeFile;\nuse http::Response;\nuse std::{convert::Infallible, io};\nuse tower::service_fn;\n\nlet app = Router::new()\n    .route(\n        // Any request to `/` goes to a service\n        \"/\",\n        // Services whose response body is not `axum::body::BoxBody`\n        // can be wrapped in `axum::routing::any_service` (or one of the other routing filters)\n        // to have the response body mapped\n        any_service(service_fn(|_: Request| async {\n            let res = Response::new(Body::from(\"Hi from `GET /`\"));\n            Ok::<_, Infallible>(res)\n        }))\n    )\n    .route_service(\n        \"/foo\",\n        // This service's response body is `axum::body::BoxBody` so\n        // it can be routed to directly.\n        service_fn(|req: Request| async move {\n            let body = Body::from(format!(\"Hi from `{} /foo`\", req.method()));\n            let res = Response::new(body);\n            Ok::<_, Infallible>(res)\n        })\n    )\n    .route_service(\n        // GET `/static/Cargo.toml` goes to a service from tower-http\n        \"/static/Cargo.toml\",\n        ServeFile::new(\"Cargo.toml\"),\n    );\n# let _: Router = app;\n```\n\nRouting to arbitrary services in this way has complications for backpressure\n([`Service::poll_ready`]). See the [Routing to services and backpressure] module\nfor more details.\n\n# Panics\n\nPanics for the same reasons as [`Router::route`] or if you attempt to route to a\n`Router`:\n\n```rust,should_panic\nuse axum::{routing::get, Router};\n\nlet app = Router::new().route_service(\n    \"/\",\n    Router::new().route(\"/foo\", get(|| async {})),\n);\n# let _: Router = app;\n```\n\nUse [`Router::nest`] instead.\n\n[Routing to services and backpressure]: middleware/index.html#routing-to-servicesmiddleware-and-backpressure\n"
  },
  {
    "path": "axum/src/docs/routing/with_state.md",
    "content": "Provide the state for the router. State passed to this method is global and will be used\nfor all requests this router receives. That means it is not suitable for holding state derived from a request, such as authorization data extracted in a middleware. Use [`Extension`] instead for such data.\n\n```rust\nuse axum::{Router, routing::get, extract::State};\n\n#[derive(Clone)]\nstruct AppState {}\n\nlet routes = Router::new()\n    .route(\"/\", get(|State(state): State<AppState>| async {\n        // use state\n    }))\n    .with_state(AppState {});\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, routes).await;\n# };\n```\n\n# Returning routers with states from functions\n\nWhen returning `Router`s from functions, it is generally recommended not to set the\nstate directly:\n\n```rust\nuse axum::{Router, routing::get, extract::State};\n\n#[derive(Clone)]\nstruct AppState {}\n\n// Don't call `Router::with_state` here\nfn routes() -> Router<AppState> {\n    Router::new()\n        .route(\"/\", get(|_: State<AppState>| async {}))\n}\n\n// Instead do it before you run the server\nlet routes = routes().with_state(AppState {});\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, routes).await;\n# };\n```\n\nIf you do need to provide the state, and you're _not_ nesting/merging the router\ninto another router, then return `Router` without any type parameters:\n\n```rust\n# use axum::{Router, routing::get, extract::State};\n# #[derive(Clone)]\n# struct AppState {}\n#\n// Don't return `Router<AppState>`\nfn routes(state: AppState) -> Router {\n    Router::new()\n        .route(\"/\", get(|_: State<AppState>| async {}))\n        .with_state(state)\n}\n\nlet routes = routes(AppState {});\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, routes).await;\n# };\n```\n\nThis is because we can only call `Router::into_make_service` on `Router<()>`,\nnot `Router<AppState>`. See below for more details about why that is.\n\nNote that the state defaults to `()` so `Router` and `Router<()>` is the same.\n\nIf you are nesting/merging the router it is recommended to use a generic state\ntype on the resulting router:\n\n```rust\n# use axum::{Router, routing::get, extract::State};\n# #[derive(Clone)]\n# struct AppState {}\n#\nfn routes<S>(state: AppState) -> Router<S> {\n    Router::new()\n        .route(\"/\", get(|_: State<AppState>| async {}))\n        .with_state(state)\n}\n\nlet routes = Router::new().nest(\"/api\", routes(AppState {}));\n\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, routes).await;\n# };\n```\n\n# What `S` in `Router<S>` means\n\n`Router<S>` means a router that is _missing_ a state of type `S` to be able to\nhandle requests. It does _not_ mean a `Router` that _has_ a state of type `S`.\n\nFor example:\n\n```rust\n# use axum::{Router, routing::get, extract::State};\n# #[derive(Clone)]\n# struct AppState {}\n# \n// A router that _needs_ an `AppState` to handle requests\nlet router: Router<AppState> = Router::new()\n    .route(\"/\", get(|_: State<AppState>| async {}));\n\n// Once we call `Router::with_state` the router isn't missing\n// the state anymore, because we just provided it\n//\n// Therefore the router type becomes `Router<()>`, i.e a router\n// that is not missing any state\nlet router: Router<()> = router.with_state(AppState {});\n\n// Only `Router<()>` has the `into_make_service` method.\n//\n// You cannot call `into_make_service` on a `Router<AppState>`\n// because it is still missing an `AppState`.\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, router).await;\n# };\n```\n\nPerhaps a little counter intuitively, `Router::with_state` doesn't always return a\n`Router<()>`. Instead you get to pick what the new missing state type is:\n\n```rust\n# use axum::{Router, routing::get, extract::State};\n# #[derive(Clone)]\n# struct AppState {}\n# \nlet router: Router<AppState> = Router::new()\n    .route(\"/\", get(|_: State<AppState>| async {}));\n\n// When we call `with_state` we're able to pick what the next missing state type is.\n// Here we pick `String`.\nlet string_router: Router<String> = router.with_state(AppState {});\n\n// That allows us to add new routes that uses `String` as the state type\nlet string_router = string_router\n    .route(\"/needs-string\", get(|_: State<String>| async {}));\n\n// Provide the `String` and choose `()` as the new missing state.\nlet final_router: Router<()> = string_router.with_state(\"foo\".to_owned());\n\n// Since we have a `Router<()>` we can run it.\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, final_router).await;\n# };\n```\n\nThis is why returning `Router<AppState>` after calling `with_state` doesn't\nwork:\n\n```rust,compile_fail\n# use axum::{Router, routing::get, extract::State};\n# #[derive(Clone)]\n# struct AppState {}\n# \n// This won't work because we're returning a `Router<AppState>`\n// i.e. we're saying we're still missing an `AppState`\nfn routes(state: AppState) -> Router<AppState> {\n    Router::new()\n        .route(\"/\", get(|_: State<AppState>| async {}))\n        .with_state(state)\n}\n\nlet app = routes(AppState {});\n\n// We can only call `Router::into_make_service` on a `Router<()>`\n// but `app` is a `Router<AppState>`\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, app).await;\n# };\n```\n\nInstead return `Router<()>` since we have provided all the state needed:\n\n```rust\n# use axum::{Router, routing::get, extract::State};\n# #[derive(Clone)]\n# struct AppState {}\n# \n// We've provided all the state necessary so return `Router<()>`\nfn routes(state: AppState) -> Router<()> {\n    Router::new()\n        .route(\"/\", get(|_: State<AppState>| async {}))\n        .with_state(state)\n}\n\nlet app = routes(AppState {});\n\n// We can now call `Router::into_make_service`\n# async {\nlet listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\naxum::serve(listener, app).await;\n# };\n```\n\n# A note about performance\n\nIf you need a `Router` that implements `Service` but you don't need any state (perhaps\nyou're making a library that uses axum internally) then it is recommended to call this\nmethod before you start serving requests:\n\n```rust\nuse axum::{Router, routing::get};\n\nlet app = Router::new()\n    .route(\"/\", get(|| async { /* ... */ }))\n    // even though we don't need any state, call `with_state(())` anyway\n    .with_state(());\n# let _: Router = app;\n```\n\nThis is not required but it gives axum a chance to update some internals in the router\nwhich may impact performance and reduce allocations.\n\nNote that [`Router::into_make_service`] and [`Router::into_make_service_with_connect_info`]\ndo this automatically.\n\n[`Extension`]: crate::Extension\n"
  },
  {
    "path": "axum/src/docs/routing/without_v07_checks.md",
    "content": "Turn off checks for compatibility with route matching syntax from 0.7.\n\nThis allows usage of paths starting with a colon `:` or an asterisk `*` which are otherwise prohibited.\n\n# Example\n\n```rust\nuse axum::{\n    routing::get,\n    Router,\n};\n\nlet app = Router::<()>::new()\n    .without_v07_checks()\n    .route(\"/:colon\", get(|| async {}))\n    .route(\"/*asterisk\", get(|| async {}));\n\n// Our app now accepts\n// - GET /:colon\n// - GET /*asterisk\n# let _: Router = app;\n```\n\nAdding such routes without calling this method first will panic.\n\n```rust,should_panic\nuse axum::{\n    routing::get,\n    Router,\n};\n\n// This panics...\nlet app = Router::<()>::new()\n    .route(\"/:colon\", get(|| async {}));\n```\n\n# Merging\n\nWhen two routers are merged, v0.7 checks are disabled for route registrations on the resulting router if both of the two routers had them also disabled.\n\n# Nesting\n\nEach router needs to have the checks explicitly disabled. Nesting a router with the checks either enabled or disabled has no effect on the outer router.\n"
  },
  {
    "path": "axum/src/error_handling/mod.rs",
    "content": "#![doc = include_str!(\"../docs/error_handling.md\")]\n\nuse crate::{\n    extract::FromRequestParts,\n    http::Request,\n    response::{IntoResponse, Response},\n};\nuse std::{\n    convert::Infallible,\n    fmt,\n    future::Future,\n    marker::PhantomData,\n    task::{Context, Poll},\n};\nuse tower::ServiceExt;\nuse tower_layer::Layer;\nuse tower_service::Service;\n\n/// [`Layer`] that applies [`HandleError`] which is a [`Service`] adapter\n/// that handles errors by converting them into responses.\n///\n/// See [module docs](self) for more details on axum's error handling model.\npub struct HandleErrorLayer<F, T> {\n    f: F,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<F, T> HandleErrorLayer<F, T> {\n    /// Create a new `HandleErrorLayer`.\n    pub fn new(f: F) -> Self {\n        Self {\n            f,\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<F, T> Clone for HandleErrorLayer<F, T>\nwhere\n    F: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            f: self.f.clone(),\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<F, E> fmt::Debug for HandleErrorLayer<F, E> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"HandleErrorLayer\")\n            .field(\"f\", &format_args!(\"{}\", std::any::type_name::<F>()))\n            .finish()\n    }\n}\n\nimpl<S, F, T> Layer<S> for HandleErrorLayer<F, T>\nwhere\n    F: Clone,\n{\n    type Service = HandleError<S, F, T>;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        HandleError::new(inner, self.f.clone())\n    }\n}\n\n/// A [`Service`] adapter that handles errors by converting them into responses.\n///\n/// See [module docs](self) for more details on axum's error handling model.\npub struct HandleError<S, F, T> {\n    inner: S,\n    f: F,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<S, F, T> HandleError<S, F, T> {\n    /// Create a new `HandleError`.\n    pub fn new(inner: S, f: F) -> Self {\n        Self {\n            inner,\n            f,\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<S, F, T> Clone for HandleError<S, F, T>\nwhere\n    S: Clone,\n    F: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            inner: self.inner.clone(),\n            f: self.f.clone(),\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<S, F, E> fmt::Debug for HandleError<S, F, E>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"HandleError\")\n            .field(\"inner\", &self.inner)\n            .field(\"f\", &format_args!(\"{}\", std::any::type_name::<F>()))\n            .finish()\n    }\n}\n\nimpl<S, F, B, Fut, Res> Service<Request<B>> for HandleError<S, F, ()>\nwhere\n    S: Service<Request<B>> + Clone + Send + 'static,\n    S::Response: IntoResponse + Send,\n    S::Error: Send,\n    S::Future: Send,\n    F: FnOnce(S::Error) -> Fut + Clone + Send + 'static,\n    Fut: Future<Output = Res> + Send,\n    Res: IntoResponse,\n    B: Send + 'static,\n{\n    type Response = Response;\n    type Error = Infallible;\n    type Future = future::HandleErrorFuture;\n\n    fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Poll::Ready(Ok(()))\n    }\n\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        let f = self.f.clone();\n\n        let clone = self.inner.clone();\n        let inner = std::mem::replace(&mut self.inner, clone);\n\n        let future = Box::pin(async move {\n            match inner.oneshot(req).await {\n                Ok(res) => Ok(res.into_response()),\n                Err(err) => Ok(f(err).await.into_response()),\n            }\n        });\n\n        future::HandleErrorFuture { future }\n    }\n}\n\n#[allow(unused_macros)]\nmacro_rules! impl_service {\n    ( $($ty:ident),* $(,)? ) => {\n        impl<S, F, B, Res, Fut, $($ty,)*> Service<Request<B>>\n            for HandleError<S, F, ($($ty,)*)>\n        where\n            S: Service<Request<B>> + Clone + Send + 'static,\n            S::Response: IntoResponse + Send,\n            S::Error: Send,\n            S::Future: Send,\n            F: FnOnce($($ty),*, S::Error) -> Fut + Clone + Send + 'static,\n            Fut: Future<Output = Res> + Send,\n            Res: IntoResponse,\n            $( $ty: FromRequestParts<()> + Send,)*\n            B: Send + 'static,\n        {\n            type Response = Response;\n            type Error = Infallible;\n\n            type Future = future::HandleErrorFuture;\n\n            fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n                Poll::Ready(Ok(()))\n            }\n\n            #[allow(non_snake_case)]\n            fn call(&mut self, req: Request<B>) -> Self::Future {\n                let f = self.f.clone();\n\n                let clone = self.inner.clone();\n                let inner = std::mem::replace(&mut self.inner, clone);\n\n                let (mut parts, body) = req.into_parts();\n\n                let future = Box::pin(async move {\n                    $(\n                        let $ty = match $ty::from_request_parts(&mut parts, &()).await {\n                            Ok(value) => value,\n                            Err(rejection) => return Ok(rejection.into_response()),\n                        };\n                    )*\n\n                    let req = Request::from_parts(parts, body);\n\n                    match inner.oneshot(req).await {\n                        Ok(res) => Ok(res.into_response()),\n                        Err(err) => Ok(f($($ty),*, err).await.into_response()),\n                    }\n                });\n\n                future::HandleErrorFuture { future }\n            }\n        }\n    }\n}\n\nimpl_service!(T1);\nimpl_service!(T1, T2);\nimpl_service!(T1, T2, T3);\nimpl_service!(T1, T2, T3, T4);\nimpl_service!(T1, T2, T3, T4, T5);\nimpl_service!(T1, T2, T3, T4, T5, T6);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);\n\npub mod future {\n    //! Future types.\n\n    use crate::response::Response;\n    use pin_project_lite::pin_project;\n    use std::{\n        convert::Infallible,\n        future::Future,\n        pin::Pin,\n        task::{Context, Poll},\n    };\n\n    pin_project! {\n        /// Response future for [`HandleError`].\n        pub struct HandleErrorFuture {\n            #[pin]\n            pub(super) future: Pin<Box<dyn Future<Output = Result<Response, Infallible>>\n                + Send\n                + 'static\n            >>,\n        }\n    }\n\n    impl Future for HandleErrorFuture {\n        type Output = Result<Response, Infallible>;\n\n        fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n            self.project().future.poll(cx)\n        }\n    }\n}\n\n#[test]\nfn traits() {\n    use crate::test_helpers::*;\n\n    assert_send::<HandleError<(), (), NotSendSync>>();\n    assert_sync::<HandleError<(), (), NotSendSync>>();\n}\n"
  },
  {
    "path": "axum/src/extension.rs",
    "content": "use crate::{extract::rejection::*, response::IntoResponseParts};\nuse axum_core::extract::OptionalFromRequestParts;\nuse axum_core::{\n    extract::FromRequestParts,\n    response::{IntoResponse, Response, ResponseParts},\n};\nuse http::{request::Parts, Extensions, Request};\nuse std::{\n    convert::Infallible,\n    task::{Context, Poll},\n};\nuse tower_service::Service;\n\n/// Extractor and response for extensions.\n///\n/// # As extractor\n///\n/// This is commonly used to share state across handlers.\n///\n/// ```rust,no_run\n/// use axum::{\n///     Router,\n///     Extension,\n///     routing::get,\n/// };\n/// use std::sync::Arc;\n///\n/// // Some shared state used throughout our application\n/// struct State {\n///     // ...\n/// }\n///\n/// async fn handler(state: Extension<Arc<State>>) {\n///     // ...\n/// }\n///\n/// let state = Arc::new(State { /* ... */ });\n///\n/// let app = Router::new().route(\"/\", get(handler))\n///     // Add middleware that inserts the state into all incoming request's\n///     // extensions.\n///     .layer(Extension(state));\n/// # let _: Router = app;\n/// ```\n///\n/// If the extension is missing it will reject the request with a `500 Internal\n/// Server Error` response. Alternatively, you can use `Option<Extension<T>>` to\n/// make the extension extractor optional.\n///\n/// # As response\n///\n/// Response extensions can be used to share state with middleware.\n///\n/// ```rust\n/// use axum::{\n///     Extension,\n///     response::IntoResponse,\n/// };\n///\n/// async fn handler() -> (Extension<Foo>, &'static str) {\n///     (\n///         Extension(Foo(\"foo\")),\n///         \"Hello, World!\"\n///     )\n/// }\n///\n/// #[derive(Clone)]\n/// struct Foo(&'static str);\n/// ```\n#[derive(Debug, Clone, Copy, Default)]\n#[must_use]\npub struct Extension<T>(pub T);\n\nimpl<T> Extension<T>\nwhere\n    T: Clone + Send + Sync + 'static,\n{\n    fn from_extensions(extensions: &Extensions) -> Option<Self> {\n        extensions.get::<T>().cloned().map(Extension)\n    }\n}\n\nimpl<T, S> FromRequestParts<S> for Extension<T>\nwhere\n    T: Clone + Send + Sync + 'static,\n    S: Send + Sync,\n{\n    type Rejection = ExtensionRejection;\n\n    async fn from_request_parts(req: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        Ok(Self::from_extensions(&req.extensions).ok_or_else(|| {\n            MissingExtension::from_err(format!(\n                \"Extension of type `{}` was not found. Perhaps you forgot to add it? See `axum::Extension`.\",\n                std::any::type_name::<T>()\n            ))\n        })?)\n    }\n}\n\nimpl<T, S> OptionalFromRequestParts<S> for Extension<T>\nwhere\n    T: Clone + Send + Sync + 'static,\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(\n        req: &mut Parts,\n        _state: &S,\n    ) -> Result<Option<Self>, Self::Rejection> {\n        Ok(Self::from_extensions(&req.extensions))\n    }\n}\n\naxum_core::__impl_deref!(Extension);\n\nimpl<T> IntoResponseParts for Extension<T>\nwhere\n    T: Clone + Send + Sync + 'static,\n{\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        res.extensions_mut().insert(self.0);\n        Ok(res)\n    }\n}\n\nimpl<T> IntoResponse for Extension<T>\nwhere\n    T: Clone + Send + Sync + 'static,\n{\n    fn into_response(self) -> Response {\n        let mut res = ().into_response();\n        res.extensions_mut().insert(self.0);\n        res\n    }\n}\n\nimpl<S, T> tower_layer::Layer<S> for Extension<T>\nwhere\n    T: Clone + Send + Sync + 'static,\n{\n    type Service = AddExtension<S, T>;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        AddExtension {\n            inner,\n            value: self.0.clone(),\n        }\n    }\n}\n\n/// Middleware for adding some shareable value to [request extensions].\n///\n/// See [Passing state from middleware to handlers](index.html#passing-state-from-middleware-to-handlers)\n/// for more details.\n///\n/// [request extensions]: https://docs.rs/http/latest/http/struct.Extensions.html\n///\n/// If you need a layer to add an extension to every request,\n/// use the [Layer](tower::Layer) implementation of [Extension].\n#[derive(Clone, Copy, Debug)]\npub struct AddExtension<S, T> {\n    pub(crate) inner: S,\n    pub(crate) value: T,\n}\n\nimpl<ResBody, S, T> Service<Request<ResBody>> for AddExtension<S, T>\nwhere\n    S: Service<Request<ResBody>>,\n    T: Clone + Send + Sync + 'static,\n{\n    type Response = S::Response;\n    type Error = S::Error;\n    type Future = S::Future;\n\n    #[inline]\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, mut req: Request<ResBody>) -> Self::Future {\n        req.extensions_mut().insert(self.value.clone());\n        self.inner.call(req)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::routing::get;\n    use crate::test_helpers::TestClient;\n    use crate::Router;\n    use http::StatusCode;\n\n    #[derive(Clone)]\n    struct Foo(String);\n\n    #[derive(Clone)]\n    struct Bar(String);\n\n    #[crate::test]\n    async fn extension_extractor() {\n        async fn requires_foo(Extension(foo): Extension<Foo>) -> String {\n            foo.0\n        }\n\n        async fn optional_foo(extension: Option<Extension<Foo>>) -> String {\n            extension.map(|foo| foo.0 .0).unwrap_or(\"none\".to_owned())\n        }\n\n        async fn requires_bar(Extension(bar): Extension<Bar>) -> String {\n            bar.0\n        }\n\n        async fn optional_bar(extension: Option<Extension<Bar>>) -> String {\n            extension.map(|bar| bar.0 .0).unwrap_or(\"none\".to_owned())\n        }\n\n        let app = Router::new()\n            .route(\"/requires_foo\", get(requires_foo))\n            .route(\"/optional_foo\", get(optional_foo))\n            .route(\"/requires_bar\", get(requires_bar))\n            .route(\"/optional_bar\", get(optional_bar))\n            .layer(Extension(Foo(\"foo\".to_owned())));\n\n        let client = TestClient::new(app);\n\n        let response = client.get(\"/requires_foo\").await;\n        assert_eq!(response.status(), StatusCode::OK);\n        assert_eq!(response.text().await, \"foo\");\n\n        let response = client.get(\"/optional_foo\").await;\n        assert_eq!(response.status(), StatusCode::OK);\n        assert_eq!(response.text().await, \"foo\");\n\n        let response = client.get(\"/requires_bar\").await;\n        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert_eq!(response.text().await, \"Missing request extension: Extension of type `axum::extension::tests::Bar` was not found. Perhaps you forgot to add it? See `axum::Extension`.\");\n\n        let response = client.get(\"/optional_bar\").await;\n        assert_eq!(response.status(), StatusCode::OK);\n        assert_eq!(response.text().await, \"none\");\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/connect_info.rs",
    "content": "//! Extractor for getting connection information from a client.\n//!\n//! See [`Router::into_make_service_with_connect_info`] for more details.\n//!\n//! [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info\n\nuse crate::extension::AddExtension;\n\nuse super::{Extension, FromRequestParts};\nuse http::request::Parts;\nuse std::{\n    convert::Infallible,\n    fmt,\n    future::ready,\n    marker::PhantomData,\n    net::SocketAddr,\n    task::{Context, Poll},\n};\nuse tower_layer::Layer;\nuse tower_service::Service;\n\n/// A [`MakeService`] created from a router.\n///\n/// See [`Router::into_make_service_with_connect_info`] for more details.\n///\n/// [`MakeService`]: tower::make::MakeService\n/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info\npub struct IntoMakeServiceWithConnectInfo<S, C> {\n    svc: S,\n    _connect_info: PhantomData<fn() -> C>,\n}\n\nimpl<S, C> IntoMakeServiceWithConnectInfo<S, C> {\n    pub(crate) fn new(svc: S) -> Self {\n        Self {\n            svc,\n            _connect_info: PhantomData,\n        }\n    }\n}\n\nimpl<S, C> fmt::Debug for IntoMakeServiceWithConnectInfo<S, C>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"IntoMakeServiceWithConnectInfo\")\n            .field(\"svc\", &self.svc)\n            .finish()\n    }\n}\n\nimpl<S, C> Clone for IntoMakeServiceWithConnectInfo<S, C>\nwhere\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            svc: self.svc.clone(),\n            _connect_info: PhantomData,\n        }\n    }\n}\n\n/// Trait that connected IO resources implement and use to produce information\n/// about the connection.\n///\n/// The goal for this trait is to allow users to implement custom IO types that\n/// can still provide the same connection metadata.\n///\n/// See [`Router::into_make_service_with_connect_info`] for more details.\n///\n/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info\npub trait Connected<T>: Clone + Send + Sync + 'static {\n    /// Create type holding information about the connection.\n    fn connect_info(stream: T) -> Self;\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nconst _: () = {\n    use crate::serve;\n\n    impl<L> Connected<serve::IncomingStream<'_, L>> for SocketAddr\n    where\n        L: serve::Listener<Addr = Self>,\n    {\n        fn connect_info(stream: serve::IncomingStream<'_, L>) -> Self {\n            *stream.remote_addr()\n        }\n    }\n};\n\nimpl Connected<Self> for SocketAddr {\n    fn connect_info(remote_addr: Self) -> Self {\n        remote_addr\n    }\n}\n\nimpl<S, C, T> Service<T> for IntoMakeServiceWithConnectInfo<S, C>\nwhere\n    S: Clone,\n    C: Connected<T>,\n{\n    type Response = AddExtension<S, ConnectInfo<C>>;\n    type Error = Infallible;\n    type Future = ResponseFuture<S, C>;\n\n    #[inline]\n    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Poll::Ready(Ok(()))\n    }\n\n    fn call(&mut self, target: T) -> Self::Future {\n        let connect_info = ConnectInfo(C::connect_info(target));\n        let svc = Extension(connect_info).layer(self.svc.clone());\n        ResponseFuture::new(ready(Ok(svc)))\n    }\n}\n\nopaque_future! {\n    /// Response future for [`IntoMakeServiceWithConnectInfo`].\n    pub type ResponseFuture<S, C> =\n        std::future::Ready<Result<AddExtension<S, ConnectInfo<C>>, Infallible>>;\n}\n\n/// Extractor for getting connection information produced by a [`Connected`].\n///\n/// Note this extractor requires you to use\n/// [`Router::into_make_service_with_connect_info`] to run your app\n/// otherwise it will fail at runtime.\n///\n/// See [`Router::into_make_service_with_connect_info`] for more details.\n///\n/// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info\n#[derive(Clone, Copy, Debug)]\npub struct ConnectInfo<T>(pub T);\n\nimpl<S, T> FromRequestParts<S> for ConnectInfo<T>\nwhere\n    S: Send + Sync,\n    T: Clone + Send + Sync + 'static,\n{\n    type Rejection = <Extension<Self> as FromRequestParts<S>>::Rejection;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        match Extension::<Self>::from_request_parts(parts, state).await {\n            Ok(Extension(connect_info)) => Ok(connect_info),\n            Err(err) => match parts.extensions.get::<MockConnectInfo<T>>() {\n                Some(MockConnectInfo(connect_info)) => Ok(Self(connect_info.clone())),\n                None => Err(err),\n            },\n        }\n    }\n}\n\naxum_core::__impl_deref!(ConnectInfo);\n\n/// Middleware used to mock [`ConnectInfo`] during tests.\n///\n/// If you're accidentally using [`MockConnectInfo`] and\n/// [`Router::into_make_service_with_connect_info`] at the same time then\n/// [`Router::into_make_service_with_connect_info`] takes precedence.\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     Router,\n///     extract::connect_info::{MockConnectInfo, ConnectInfo},\n///     body::Body,\n///     routing::get,\n///     http::{Request, StatusCode},\n/// };\n/// use std::net::SocketAddr;\n/// use tower::ServiceExt;\n///\n/// async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) {}\n///\n/// // this router you can run with `app.into_make_service_with_connect_info::<SocketAddr>()`\n/// fn app() -> Router {\n///     Router::new().route(\"/\", get(handler))\n/// }\n///\n/// // use this router for tests\n/// fn test_app() -> Router {\n///     app().layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 1337))))\n/// }\n///\n/// // #[tokio::test]\n/// async fn some_test() {\n///     let app = test_app();\n///\n///     let request = Request::new(Body::empty());\n///     let response = app.oneshot(request).await.unwrap();\n///     assert_eq!(response.status(), StatusCode::OK);\n/// }\n/// #\n/// # #[tokio::main]\n/// # async fn main() {\n/// #     some_test().await;\n/// # }\n/// ```\n///\n/// [`Router::into_make_service_with_connect_info`]: crate::Router::into_make_service_with_connect_info\n#[derive(Clone, Copy, Debug)]\npub struct MockConnectInfo<T>(pub T);\n\nimpl<S, T> Layer<S> for MockConnectInfo<T>\nwhere\n    T: Clone + Send + Sync + 'static,\n{\n    type Service = <Extension<Self> as Layer<S>>::Service;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        Extension(self.clone()).layer(inner)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{\n        extract::connect_info::Connected, routing::get, serve::IncomingStream, serve::Listener,\n        test_helpers::TestClient, Router,\n    };\n    use tokio::net::{TcpListener, TcpStream};\n\n    #[test]\n    fn into_make_service_traits() {\n        use crate::test_helpers::*;\n        assert_send::<IntoMakeServiceWithConnectInfo<(), NotSendSync>>();\n    }\n\n    #[allow(dead_code)]\n    #[allow(clippy::todo)]\n    fn connected_traits() {\n        // Test that the `Connected` trait can be used with custom address and listener types.\n\n        fn create_router() -> Router {\n            todo!()\n        }\n\n        fn tcp_listener() -> TcpListener {\n            todo!()\n        }\n\n        #[derive(Clone)]\n        struct CustomAddr(SocketAddr);\n\n        impl Connected<IncomingStream<'_, TcpListener>> for CustomAddr {\n            fn connect_info(_stream: IncomingStream<'_, TcpListener>) -> Self {\n                todo!()\n            }\n        }\n\n        impl Connected<IncomingStream<'_, CustomListener>> for CustomAddr {\n            fn connect_info(_stream: IncomingStream<'_, CustomListener>) -> Self {\n                todo!()\n            }\n        }\n\n        struct CustomListener {}\n\n        impl Listener for CustomListener {\n            type Io = TcpStream;\n            type Addr = SocketAddr;\n\n            async fn accept(&mut self) -> (Self::Io, Self::Addr) {\n                todo!()\n            }\n\n            fn local_addr(&self) -> tokio::io::Result<Self::Addr> {\n                todo!()\n            }\n        }\n\n        fn custom_connected() {\n            let router = create_router();\n            let _ = crate::serve(\n                tcp_listener(),\n                router.into_make_service_with_connect_info::<CustomAddr>(),\n            );\n        }\n\n        fn custom_listener() {\n            let router = create_router();\n            let _ = crate::serve(CustomListener {}, router.into_make_service());\n        }\n\n        fn custom_listener_with_connect() {\n            let router = create_router();\n            let _ = crate::serve(\n                CustomListener {},\n                router.into_make_service_with_connect_info::<SocketAddr>(),\n            );\n        }\n\n        fn custom_listener_with_custom_connect() {\n            let router = create_router();\n            let _ = crate::serve(\n                CustomListener {},\n                router.into_make_service_with_connect_info::<CustomAddr>(),\n            );\n        }\n    }\n\n    #[crate::test]\n    async fn socket_addr() {\n        async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {\n            format!(\"{addr}\")\n        }\n\n        let listener = TcpListener::bind(\"127.0.0.1:0\").await.unwrap();\n        let addr = listener.local_addr().unwrap();\n\n        let (tx, rx) = tokio::sync::oneshot::channel();\n        tokio::spawn(async move {\n            let app = Router::new().route(\"/\", get(handler));\n            tx.send(()).unwrap();\n            crate::serve(\n                listener,\n                app.into_make_service_with_connect_info::<SocketAddr>(),\n            )\n            .await;\n        });\n        rx.await.unwrap();\n\n        let client = reqwest::Client::new();\n\n        let res = client.get(format!(\"http://{addr}\")).send().await.unwrap();\n        let body = res.text().await.unwrap();\n        assert!(body.starts_with(\"127.0.0.1:\"));\n    }\n\n    #[crate::test]\n    async fn custom() {\n        #[derive(Clone, Debug)]\n        struct MyConnectInfo {\n            value: &'static str,\n        }\n\n        impl Connected<IncomingStream<'_, TcpListener>> for MyConnectInfo {\n            fn connect_info(_target: IncomingStream<'_, TcpListener>) -> Self {\n                Self {\n                    value: \"it worked!\",\n                }\n            }\n        }\n\n        async fn handler(ConnectInfo(addr): ConnectInfo<MyConnectInfo>) -> &'static str {\n            addr.value\n        }\n\n        let listener = TcpListener::bind(\"127.0.0.1:0\").await.unwrap();\n        let addr = listener.local_addr().unwrap();\n\n        let (tx, rx) = tokio::sync::oneshot::channel();\n        tokio::spawn(async move {\n            let app = Router::new().route(\"/\", get(handler));\n            tx.send(()).unwrap();\n            crate::serve(\n                listener,\n                app.into_make_service_with_connect_info::<MyConnectInfo>(),\n            )\n            .await;\n        });\n        rx.await.unwrap();\n\n        let client = reqwest::Client::new();\n\n        let res = client.get(format!(\"http://{addr}\")).send().await.unwrap();\n        let body = res.text().await.unwrap();\n        assert_eq!(body, \"it worked!\");\n    }\n\n    #[crate::test]\n    async fn mock_connect_info() {\n        async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {\n            format!(\"{addr}\")\n        }\n\n        let app = Router::new()\n            .route(\"/\", get(handler))\n            .layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 1337))));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n        let body = res.text().await;\n        assert!(body.starts_with(\"0.0.0.0:1337\"));\n    }\n\n    #[crate::test]\n    async fn both_mock_and_real_connect_info() {\n        async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {\n            format!(\"{addr}\")\n        }\n\n        let listener = TcpListener::bind(\"127.0.0.1:0\").await.unwrap();\n        let addr = listener.local_addr().unwrap();\n\n        tokio::spawn(async move {\n            let app = Router::new()\n                .route(\"/\", get(handler))\n                .layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 1337))));\n\n            crate::serve(\n                listener,\n                app.into_make_service_with_connect_info::<SocketAddr>(),\n            )\n            .await;\n        });\n\n        let client = reqwest::Client::new();\n\n        let res = client.get(format!(\"http://{addr}\")).send().await.unwrap();\n        let body = res.text().await.unwrap();\n        assert!(body.starts_with(\"127.0.0.1:\"));\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/matched_path.rs",
    "content": "use super::{rejection::*, FromRequestParts};\nuse crate::routing::{RouteId, NEST_TAIL_PARAM_CAPTURE};\nuse axum_core::extract::OptionalFromRequestParts;\nuse http::request::Parts;\nuse std::{collections::HashMap, convert::Infallible, sync::Arc};\n\n/// Access the path in the router that matches the request.\n///\n/// ```\n/// use axum::{\n///     Router,\n///     extract::MatchedPath,\n///     routing::get,\n/// };\n///\n/// let app = Router::new().route(\n///     \"/users/{id}\",\n///     get(|path: MatchedPath| async move {\n///         let path = path.as_str();\n///         // `path` will be \"/users/{id}\"\n///     })\n/// );\n/// # let _: Router = app;\n/// ```\n///\n/// # Accessing `MatchedPath` via extensions\n///\n/// `MatchedPath` can also be accessed from middleware via request extensions.\n///\n/// This is useful for example with [`Trace`](tower_http::trace::Trace) to\n/// create a span that contains the matched path:\n///\n/// ```\n/// use axum::{\n///     Router,\n///     extract::{Request, MatchedPath},\n///     routing::get,\n/// };\n/// use tower_http::trace::TraceLayer;\n///\n/// let app = Router::new()\n///     .route(\"/users/{id}\", get(|| async { /* ... */ }))\n///     .layer(\n///         TraceLayer::new_for_http().make_span_with(|req: &Request<_>| {\n///             let path = if let Some(path) = req.extensions().get::<MatchedPath>() {\n///                 path.as_str()\n///             } else {\n///                 req.uri().path()\n///             };\n///             tracing::info_span!(\"http-request\", %path)\n///         }),\n///     );\n/// # let _: Router = app;\n/// ```\n#[cfg_attr(docsrs, doc(cfg(feature = \"matched-path\")))]\n#[derive(Clone, Debug)]\npub struct MatchedPath(pub(crate) Arc<str>);\n\nimpl MatchedPath {\n    /// Returns a `str` representation of the path.\n    #[must_use]\n    pub fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\nimpl<S> FromRequestParts<S> for MatchedPath\nwhere\n    S: Send + Sync,\n{\n    type Rejection = MatchedPathRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        let matched_path = parts\n            .extensions\n            .get::<Self>()\n            .ok_or(MatchedPathRejection::MatchedPathMissing(MatchedPathMissing))?\n            .clone();\n\n        Ok(matched_path)\n    }\n}\n\nimpl<S> OptionalFromRequestParts<S> for MatchedPath\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(\n        parts: &mut Parts,\n        _state: &S,\n    ) -> Result<Option<Self>, Self::Rejection> {\n        Ok(parts.extensions.get::<Self>().cloned())\n    }\n}\n\n#[derive(Clone, Debug)]\nstruct MatchedNestedPath(Arc<str>);\n\npub(crate) fn set_matched_path_for_request(\n    id: RouteId,\n    route_id_to_path: &HashMap<RouteId, Arc<str>>,\n    extensions: &mut http::Extensions,\n) {\n    let Some(matched_path) = route_id_to_path.get(&id) else {\n        #[cfg(debug_assertions)]\n        panic!(\"should always have a matched path for a route id\");\n        #[cfg(not(debug_assertions))]\n        return;\n    };\n\n    let matched_path = append_nested_matched_path(matched_path, extensions);\n\n    if matched_path.ends_with(NEST_TAIL_PARAM_CAPTURE) {\n        extensions.insert(MatchedNestedPath(matched_path));\n        debug_assert!(extensions.remove::<MatchedPath>().is_none());\n    } else {\n        extensions.insert(MatchedPath(matched_path));\n        extensions.remove::<MatchedNestedPath>();\n    }\n}\n\n// a previous `MatchedPath` might exist if we're inside a nested Router\nfn append_nested_matched_path(matched_path: &Arc<str>, extensions: &http::Extensions) -> Arc<str> {\n    if let Some(previous) = extensions\n        .get::<MatchedPath>()\n        .map(|matched_path| matched_path.as_str())\n        .or_else(|| Some(&extensions.get::<MatchedNestedPath>()?.0))\n    {\n        let previous = previous\n            .strip_suffix(NEST_TAIL_PARAM_CAPTURE)\n            .unwrap_or(previous);\n\n        let matched_path = format!(\"{previous}{matched_path}\");\n        matched_path.into()\n    } else {\n        Arc::clone(matched_path)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{\n        extract::Request,\n        handler::HandlerWithoutStateExt,\n        middleware::map_request,\n        routing::{any, get},\n        test_helpers::*,\n        Router,\n    };\n    use http::StatusCode;\n\n    #[crate::test]\n    async fn extracting_on_handler() {\n        let app = Router::new().route(\n            \"/{a}\",\n            get(|path: MatchedPath| async move { path.as_str().to_owned() }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo\").await;\n        assert_eq!(res.text().await, \"/{a}\");\n    }\n\n    #[crate::test]\n    async fn extracting_on_handler_in_nested_router() {\n        let app = Router::new().nest(\n            \"/{a}\",\n            Router::new().route(\n                \"/{b}\",\n                get(|path: MatchedPath| async move { path.as_str().to_owned() }),\n            ),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.text().await, \"/{a}/{b}\");\n    }\n\n    #[crate::test]\n    async fn extracting_on_handler_in_deeply_nested_router() {\n        let app = Router::new().nest(\n            \"/{a}\",\n            Router::new().nest(\n                \"/{b}\",\n                Router::new().route(\n                    \"/{c}\",\n                    get(|path: MatchedPath| async move { path.as_str().to_owned() }),\n                ),\n            ),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar/baz\").await;\n        assert_eq!(res.text().await, \"/{a}/{b}/{c}\");\n    }\n\n    #[crate::test]\n    async fn cannot_extract_nested_matched_path_in_middleware() {\n        async fn extract_matched_path<B>(\n            matched_path: Option<MatchedPath>,\n            req: Request<B>,\n        ) -> Request<B> {\n            assert!(matched_path.is_none());\n            req\n        }\n\n        let app = Router::new()\n            .nest_service(\"/{a}\", Router::new().route(\"/{b}\", get(|| async move {})))\n            .layer(map_request(extract_matched_path));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn can_extract_nested_matched_path_in_middleware_using_nest() {\n        async fn extract_matched_path<B>(\n            matched_path: Option<MatchedPath>,\n            req: Request<B>,\n        ) -> Request<B> {\n            assert_eq!(matched_path.unwrap().as_str(), \"/{a}/{b}\");\n            req\n        }\n\n        let app = Router::new()\n            .nest(\"/{a}\", Router::new().route(\"/{b}\", get(|| async move {})))\n            .layer(map_request(extract_matched_path));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn cannot_extract_nested_matched_path_in_middleware_via_extension() {\n        async fn assert_no_matched_path<B>(req: Request<B>) -> Request<B> {\n            assert!(req.extensions().get::<MatchedPath>().is_none());\n            req\n        }\n\n        let app = Router::new()\n            .nest_service(\"/{a}\", Router::new().route(\"/{b}\", get(|| async move {})))\n            .layer(map_request(assert_no_matched_path));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[tokio::test]\n    async fn can_extract_nested_matched_path_in_middleware_via_extension_using_nest() {\n        async fn assert_matched_path<B>(req: Request<B>) -> Request<B> {\n            assert!(req.extensions().get::<MatchedPath>().is_some());\n            req\n        }\n\n        let app = Router::new()\n            .nest(\"/{a}\", Router::new().route(\"/{b}\", get(|| async move {})))\n            .layer(map_request(assert_matched_path));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn can_extract_nested_matched_path_in_middleware_on_nested_router() {\n        async fn extract_matched_path<B>(matched_path: MatchedPath, req: Request<B>) -> Request<B> {\n            assert_eq!(matched_path.as_str(), \"/{a}/{b}\");\n            req\n        }\n\n        let app = Router::new().nest(\n            \"/{a}\",\n            Router::new()\n                .route(\"/{b}\", get(|| async move {}))\n                .layer(map_request(extract_matched_path)),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn can_extract_nested_matched_path_in_middleware_on_nested_router_via_extension() {\n        async fn extract_matched_path<B>(req: Request<B>) -> Request<B> {\n            let matched_path = req.extensions().get::<MatchedPath>().unwrap();\n            assert_eq!(matched_path.as_str(), \"/{a}/{b}\");\n            req\n        }\n\n        let app = Router::new().nest(\n            \"/{a}\",\n            Router::new()\n                .route(\"/{b}\", get(|| async move {}))\n                .layer(map_request(extract_matched_path)),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn extracting_on_nested_handler() {\n        async fn handler(path: Option<MatchedPath>) {\n            assert!(path.is_none());\n        }\n\n        let app = Router::new().nest_service(\"/{a}\", handler.into_service());\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    // https://github.com/tokio-rs/axum/issues/1579\n    #[crate::test]\n    async fn doesnt_panic_if_router_called_from_wildcard_route() {\n        use tower::ServiceExt;\n\n        let app = Router::new().route(\n            \"/{*path}\",\n            any(|req: Request| {\n                Router::new()\n                    .nest(\"/foo\", Router::new().route(\"/bar\", get(|| async {})))\n                    .oneshot(req)\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn cant_extract_in_fallback() {\n        async fn handler(path: Option<MatchedPath>, req: Request) {\n            assert!(path.is_none());\n            assert!(req.extensions().get::<MatchedPath>().is_none());\n        }\n\n        let app = Router::new().fallback(handler);\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn matching_colon() {\n        let app = Router::new().without_v07_checks().route(\n            \"/:foo\",\n            get(|path: MatchedPath| async move { path.as_str().to_owned() }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/:foo\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"/:foo\");\n\n        let res = client.get(\"/:bar\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n        let res = client.get(\"/foo\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    }\n\n    #[crate::test]\n    async fn matching_asterisk() {\n        let app = Router::new().without_v07_checks().route(\n            \"/*foo\",\n            get(|path: MatchedPath| async move { path.as_str().to_owned() }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/*foo\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"/*foo\");\n\n        let res = client.get(\"/*bar\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n        let res = client.get(\"/foo\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/mod.rs",
    "content": "#![doc = include_str!(\"../docs/extract.md\")]\n\nuse http::header::{self, HeaderMap};\n\n#[cfg(feature = \"tokio\")]\npub mod connect_info;\npub mod path;\npub mod rejection;\n\n#[cfg(feature = \"ws\")]\npub mod ws;\n\npub(crate) mod nested_path;\n#[cfg(feature = \"original-uri\")]\nmod original_uri;\nmod raw_form;\nmod raw_query;\nmod state;\n\n#[doc(inline)]\npub use axum_core::extract::{\n    DefaultBodyLimit, FromRef, FromRequest, FromRequestParts, OptionalFromRequest,\n    OptionalFromRequestParts, Request,\n};\n\n#[cfg(feature = \"macros\")]\npub use axum_macros::{FromRef, FromRequest, FromRequestParts};\n\n#[doc(inline)]\npub use self::{\n    nested_path::NestedPath,\n    path::{Path, RawPathParams},\n    raw_form::RawForm,\n    raw_query::RawQuery,\n    state::State,\n};\n\n#[doc(inline)]\n#[cfg(feature = \"tokio\")]\npub use self::connect_info::ConnectInfo;\n\n#[doc(no_inline)]\n#[cfg(feature = \"json\")]\npub use crate::Json;\n\n#[doc(no_inline)]\npub use crate::Extension;\n\n#[cfg(feature = \"form\")]\n#[doc(no_inline)]\npub use crate::form::Form;\n\n#[cfg(feature = \"matched-path\")]\npub(crate) mod matched_path;\n\n#[cfg(feature = \"matched-path\")]\n#[doc(inline)]\npub use self::matched_path::MatchedPath;\n\n#[cfg(feature = \"multipart\")]\npub mod multipart;\n\n#[cfg(feature = \"multipart\")]\n#[doc(inline)]\npub use self::multipart::Multipart;\n\n#[cfg(feature = \"query\")]\nmod query;\n\n#[cfg(feature = \"query\")]\n#[doc(inline)]\npub use self::query::Query;\n\n#[cfg(feature = \"original-uri\")]\n#[doc(inline)]\npub use self::original_uri::OriginalUri;\n\n#[cfg(feature = \"ws\")]\n#[doc(inline)]\npub use self::ws::WebSocketUpgrade;\n\n// this is duplicated in `axum-extra/src/extract/form.rs`\npub(super) fn has_content_type(headers: &HeaderMap, expected_content_type: &mime::Mime) -> bool {\n    let Some(content_type) = headers.get(header::CONTENT_TYPE) else {\n        return false;\n    };\n\n    let Ok(content_type) = content_type.to_str() else {\n        return false;\n    };\n\n    content_type.starts_with(expected_content_type.as_ref())\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{routing::get, test_helpers::*, Router};\n\n    #[crate::test]\n    async fn consume_body() {\n        let app = Router::new().route(\"/\", get(|body: String| async { body }));\n\n        let client = TestClient::new(app);\n        let res = client.get(\"/\").body(\"foo\").await;\n        let body = res.text().await;\n\n        assert_eq!(body, \"foo\");\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/multipart.rs",
    "content": "//! Extractor that parses `multipart/form-data` requests commonly used with file uploads.\n//!\n//! See [`Multipart`] for more details.\n\nuse super::{FromRequest, Request};\nuse crate::body::Bytes;\nuse axum_core::{\n    __composite_rejection as composite_rejection, __define_rejection as define_rejection,\n    extract::OptionalFromRequest,\n    response::{IntoResponse, Response},\n    RequestExt,\n};\nuse futures_core::Stream;\nuse http::{\n    header::{HeaderMap, CONTENT_TYPE},\n    StatusCode,\n};\nuse std::{\n    error::Error,\n    fmt,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\n/// Extractor that parses `multipart/form-data` requests (commonly used with file uploads).\n///\n/// ⚠️ Since extracting multipart form data from the request requires consuming the body, the\n/// `Multipart` extractor must be *last* if there are multiple extractors in a handler.\n/// See [\"the order of extractors\"][order-of-extractors]\n///\n/// [order-of-extractors]: crate::extract#the-order-of-extractors\n///\n/// # Example\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::Multipart,\n///     routing::post,\n///     Router,\n/// };\n/// use futures_util::stream::StreamExt;\n///\n/// async fn upload(mut multipart: Multipart) {\n///     while let Some(mut field) = multipart.next_field().await.unwrap() {\n///         let name = field.name().unwrap().to_string();\n///         let data = field.bytes().await.unwrap();\n///\n///         println!(\"Length of `{}` is {} bytes\", name, data.len());\n///     }\n/// }\n///\n/// let app = Router::new().route(\"/upload\", post(upload));\n/// # let _: Router = app;\n/// ```\n///\n/// # Large Files\n///\n/// For security reasons, by default, `Multipart` limits the request body size to 2MB.\n/// See [`DefaultBodyLimit`][default-body-limit] for how to configure this limit.\n///\n/// [default-body-limit]: crate::extract::DefaultBodyLimit\n#[cfg_attr(docsrs, doc(cfg(feature = \"multipart\")))]\n#[derive(Debug)]\npub struct Multipart {\n    inner: multer::Multipart<'static>,\n}\n\nimpl<S> FromRequest<S> for Multipart\nwhere\n    S: Send + Sync,\n{\n    type Rejection = MultipartRejection;\n\n    async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        let boundary = content_type_str(req.headers())\n            .and_then(|content_type| multer::parse_boundary(content_type).ok())\n            .ok_or(InvalidBoundary)?;\n        let stream = req.with_limited_body().into_body();\n        let multipart = multer::Multipart::new(stream.into_data_stream(), boundary);\n        Ok(Self { inner: multipart })\n    }\n}\n\nimpl<S> OptionalFromRequest<S> for Multipart\nwhere\n    S: Send + Sync,\n{\n    type Rejection = MultipartRejection;\n\n    async fn from_request(req: Request, _state: &S) -> Result<Option<Self>, Self::Rejection> {\n        let Some(content_type) = content_type_str(req.headers()) else {\n            return Ok(None);\n        };\n        match multer::parse_boundary(content_type) {\n            Ok(boundary) => {\n                let stream = req.with_limited_body().into_body();\n                let multipart = multer::Multipart::new(stream.into_data_stream(), boundary);\n                Ok(Some(Self { inner: multipart }))\n            }\n            Err(multer::Error::NoMultipart) => Ok(None),\n            Err(_) => Err(MultipartRejection::InvalidBoundary(InvalidBoundary)),\n        }\n    }\n}\n\nimpl Multipart {\n    /// Yields the next [`Field`] if available.\n    pub async fn next_field(&mut self) -> Result<Option<Field<'_>>, MultipartError> {\n        let field = self\n            .inner\n            .next_field()\n            .await\n            .map_err(MultipartError::from_multer)?;\n\n        if let Some(field) = field {\n            Ok(Some(Field {\n                inner: field,\n                _multipart: self,\n            }))\n        } else {\n            Ok(None)\n        }\n    }\n}\n\n/// A single field in a multipart stream.\n#[derive(Debug)]\npub struct Field<'a> {\n    inner: multer::Field<'static>,\n    // multer requires there to only be one live `multer::Field` at any point. This enforces that\n    // statically, which multer does not do, it returns an error instead.\n    _multipart: &'a mut Multipart,\n}\n\nimpl Stream for Field<'_> {\n    type Item = Result<Bytes, MultipartError>;\n\n    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {\n        Pin::new(&mut self.inner)\n            .poll_next(cx)\n            .map_err(MultipartError::from_multer)\n    }\n}\n\nimpl Field<'_> {\n    /// The field name found in the\n    /// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)\n    /// header.\n    #[must_use]\n    pub fn name(&self) -> Option<&str> {\n        self.inner.name()\n    }\n\n    /// The file name found in the\n    /// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)\n    /// header.\n    #[must_use]\n    pub fn file_name(&self) -> Option<&str> {\n        self.inner.file_name()\n    }\n\n    /// Get the [content type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) of the field.\n    #[must_use]\n    pub fn content_type(&self) -> Option<&str> {\n        self.inner.content_type().map(|m| m.as_ref())\n    }\n\n    /// Get a map of headers as [`HeaderMap`].\n    #[must_use]\n    pub fn headers(&self) -> &HeaderMap {\n        self.inner.headers()\n    }\n\n    /// Get the full data of the field as [`Bytes`].\n    pub async fn bytes(self) -> Result<Bytes, MultipartError> {\n        self.inner\n            .bytes()\n            .await\n            .map_err(MultipartError::from_multer)\n    }\n\n    /// Get the full field data as text.\n    pub async fn text(self) -> Result<String, MultipartError> {\n        self.inner.text().await.map_err(MultipartError::from_multer)\n    }\n\n    /// Stream a chunk of the field data.\n    ///\n    /// When the field data has been exhausted, this will return [`None`].\n    ///\n    /// Note this does the same thing as `Field`'s [`Stream`] implementation.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///    extract::Multipart,\n    ///    routing::post,\n    ///    response::IntoResponse,\n    ///    http::StatusCode,\n    ///    Router,\n    /// };\n    ///\n    /// async fn upload(mut multipart: Multipart) -> Result<(), (StatusCode, String)> {\n    ///     while let Some(mut field) = multipart\n    ///         .next_field()\n    ///         .await\n    ///         .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))?\n    ///     {\n    ///         while let Some(chunk) = field\n    ///             .chunk()\n    ///             .await\n    ///             .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))?\n    ///         {\n    ///             println!(\"received {} bytes\", chunk.len());\n    ///         }\n    ///     }\n    ///\n    ///     Ok(())\n    /// }\n    ///\n    /// let app = Router::new().route(\"/upload\", post(upload));\n    /// # let _: Router = app;\n    /// ```\n    pub async fn chunk(&mut self) -> Result<Option<Bytes>, MultipartError> {\n        self.inner\n            .chunk()\n            .await\n            .map_err(MultipartError::from_multer)\n    }\n}\n\n/// Errors associated with parsing `multipart/form-data` requests.\n#[derive(Debug)]\npub struct MultipartError {\n    source: multer::Error,\n}\n\nimpl MultipartError {\n    fn from_multer(multer: multer::Error) -> Self {\n        Self { source: multer }\n    }\n\n    /// Get the response body text used for this rejection.\n    #[must_use]\n    pub fn body_text(&self) -> String {\n        if is_body_limit_error(&self.source) {\n            \"Request payload is too large\".to_owned()\n        } else {\n            self.source.to_string()\n        }\n    }\n\n    /// Get the status code used for this rejection.\n    #[must_use]\n    pub fn status(&self) -> http::StatusCode {\n        status_code_from_multer_error(&self.source)\n    }\n}\n\nfn status_code_from_multer_error(err: &multer::Error) -> StatusCode {\n    match err {\n        multer::Error::UnknownField { .. }\n        | multer::Error::IncompleteFieldData { .. }\n        | multer::Error::IncompleteHeaders\n        | multer::Error::ReadHeaderFailed(..)\n        | multer::Error::DecodeHeaderName { .. }\n        | multer::Error::DecodeContentType(..)\n        | multer::Error::NoBoundary\n        | multer::Error::DecodeHeaderValue { .. }\n        | multer::Error::NoMultipart\n        | multer::Error::IncompleteStream => StatusCode::BAD_REQUEST,\n        multer::Error::FieldSizeExceeded { .. } | multer::Error::StreamSizeExceeded { .. } => {\n            StatusCode::PAYLOAD_TOO_LARGE\n        }\n        multer::Error::StreamReadFailed(err) => {\n            if let Some(err) = err.downcast_ref::<multer::Error>() {\n                return status_code_from_multer_error(err);\n            }\n\n            if err\n                .downcast_ref::<crate::Error>()\n                .and_then(|err| err.source())\n                .and_then(|err| err.downcast_ref::<http_body_util::LengthLimitError>())\n                .is_some()\n            {\n                return StatusCode::PAYLOAD_TOO_LARGE;\n            }\n\n            StatusCode::INTERNAL_SERVER_ERROR\n        }\n        _ => StatusCode::INTERNAL_SERVER_ERROR,\n    }\n}\n\nfn is_body_limit_error(err: &multer::Error) -> bool {\n    match err {\n        multer::Error::FieldSizeExceeded { .. } | multer::Error::StreamSizeExceeded { .. } => true,\n        multer::Error::StreamReadFailed(err) => {\n            if let Some(err) = err.downcast_ref::<multer::Error>() {\n                return is_body_limit_error(err);\n            }\n            err.downcast_ref::<crate::Error>()\n                .and_then(|err| err.source())\n                .and_then(|err| err.downcast_ref::<http_body_util::LengthLimitError>())\n                .is_some()\n        }\n        _ => false,\n    }\n}\n\nimpl fmt::Display for MultipartError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"Error parsing `multipart/form-data` request\")\n    }\n}\n\nimpl std::error::Error for MultipartError {\n    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n        Some(&self.source)\n    }\n}\n\nimpl IntoResponse for MultipartError {\n    fn into_response(self) -> Response {\n        let body = self.body_text();\n        axum_core::__log_rejection!(\n            rejection_type = Self,\n            body_text = body,\n            status = self.status(),\n        );\n        (self.status(), body).into_response()\n    }\n}\n\nfn content_type_str(headers: &HeaderMap) -> Option<&str> {\n    headers.get(CONTENT_TYPE)?.to_str().ok()\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Multipart`].\n    ///\n    /// Contains one variant for each way the [`Multipart`] extractor can fail.\n    pub enum MultipartRejection {\n        InvalidBoundary,\n    }\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Invalid `boundary` for `multipart/form-data` request\"]\n    /// Rejection type used if the `boundary` in a `multipart/form-data` is\n    /// missing or invalid.\n    pub struct InvalidBoundary;\n}\n\n#[cfg(test)]\nmod tests {\n    use axum_core::extract::DefaultBodyLimit;\n\n    use super::*;\n    use crate::{routing::post, test_helpers::*, Router};\n\n    #[crate::test]\n    async fn content_type_with_encoding() {\n        const BYTES: &[u8] = \"<!doctype html><title>🦀</title>\".as_bytes();\n        const FILE_NAME: &str = \"index.html\";\n        const CONTENT_TYPE: &str = \"text/html; charset=utf-8\";\n\n        async fn handle(mut multipart: Multipart) -> impl IntoResponse {\n            let field = multipart.next_field().await.unwrap().unwrap();\n\n            assert_eq!(field.file_name().unwrap(), FILE_NAME);\n            assert_eq!(field.content_type().unwrap(), CONTENT_TYPE);\n            assert_eq!(field.headers()[\"foo\"], \"bar\");\n            assert_eq!(field.bytes().await.unwrap(), BYTES);\n\n            assert!(multipart.next_field().await.unwrap().is_none());\n        }\n\n        let app = Router::new().route(\"/\", post(handle));\n\n        let client = TestClient::new(app);\n\n        let form = reqwest::multipart::Form::new().part(\n            \"file\",\n            reqwest::multipart::Part::bytes(BYTES)\n                .file_name(FILE_NAME)\n                .mime_str(CONTENT_TYPE)\n                .unwrap()\n                .headers(reqwest::header::HeaderMap::from_iter([(\n                    reqwest::header::HeaderName::from_static(\"foo\"),\n                    reqwest::header::HeaderValue::from_static(\"bar\"),\n                )])),\n        );\n\n        client.post(\"/\").multipart(form).await;\n    }\n\n    // No need for this to be a #[test], we just want to make sure it compiles\n    fn _multipart_from_request_limited() {\n        async fn handler(_: Multipart) {}\n        let _app: Router = Router::new()\n            .route(\"/\", post(handler))\n            .layer(tower_http::limit::RequestBodyLimitLayer::new(1024));\n    }\n\n    #[crate::test]\n    async fn body_too_large() {\n        const BYTES: &[u8] = \"<!doctype html><title>🦀</title>\".as_bytes();\n\n        async fn handle(mut multipart: Multipart) -> Result<(), MultipartError> {\n            while let Some(field) = multipart.next_field().await? {\n                field.bytes().await?;\n            }\n            Ok(())\n        }\n\n        let app = Router::new()\n            .route(\"/\", post(handle))\n            .layer(DefaultBodyLimit::max(BYTES.len() - 1));\n\n        let client = TestClient::new(app);\n\n        let form =\n            reqwest::multipart::Form::new().part(\"file\", reqwest::multipart::Part::bytes(BYTES));\n\n        let res = client.post(\"/\").multipart(form).await;\n        assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n        assert_eq!(res.text().await, \"Request payload is too large\");\n    }\n\n    #[crate::test]\n    async fn optional_multipart() {\n        const BYTES: &[u8] = \"<!doctype html><title>🦀</title>\".as_bytes();\n\n        async fn handle(multipart: Option<Multipart>) -> Result<StatusCode, MultipartError> {\n            if let Some(mut multipart) = multipart {\n                while let Some(field) = multipart.next_field().await? {\n                    field.bytes().await?;\n                }\n                Ok(StatusCode::OK)\n            } else {\n                Ok(StatusCode::NO_CONTENT)\n            }\n        }\n\n        let app = Router::new().route(\"/\", post(handle));\n        let client = TestClient::new(app);\n        let form =\n            reqwest::multipart::Form::new().part(\"file\", reqwest::multipart::Part::bytes(BYTES));\n\n        let res = client.post(\"/\").multipart(form).await;\n        assert_eq!(res.status(), StatusCode::OK);\n\n        let res = client.post(\"/\").await;\n        assert_eq!(res.status(), StatusCode::NO_CONTENT);\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/nested_path.rs",
    "content": "use std::{\n    sync::Arc,\n    task::{Context, Poll},\n};\n\nuse crate::extract::Request;\nuse axum_core::extract::FromRequestParts;\nuse http::request::Parts;\nuse tower_layer::{layer_fn, Layer};\nuse tower_service::Service;\n\nuse super::rejection::NestedPathRejection;\n\n/// Access the path the matched the route is nested at.\n///\n/// This can for example be used when doing redirects.\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     Router,\n///     extract::NestedPath,\n///     routing::get,\n/// };\n///\n/// let api = Router::new().route(\n///     \"/users\",\n///     get(|path: NestedPath| async move {\n///         // `path` will be \"/api\" because that's what this\n///         // router is nested at when we build `app`\n///         let path = path.as_str();\n///     })\n/// );\n///\n/// let app = Router::new().nest(\"/api\", api);\n/// # let _: Router = app;\n/// ```\n#[derive(Debug, Clone)]\npub struct NestedPath(Arc<str>);\n\nimpl NestedPath {\n    /// Returns a `str` representation of the path.\n    #[must_use]\n    pub fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\n#[diagnostic::do_not_recommend] // pretty niche type\nimpl<S> FromRequestParts<S> for NestedPath\nwhere\n    S: Send + Sync,\n{\n    type Rejection = NestedPathRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        match parts.extensions.get::<Self>() {\n            Some(nested_path) => Ok(nested_path.clone()),\n            None => Err(NestedPathRejection),\n        }\n    }\n}\n\n#[derive(Clone)]\npub(crate) struct SetNestedPath<S> {\n    inner: S,\n    path: Arc<str>,\n}\n\nimpl<S> SetNestedPath<S> {\n    pub(crate) fn layer(path: &str) -> impl Layer<S, Service = Self> + Clone {\n        let path = Arc::from(path);\n        layer_fn(move |inner| Self {\n            inner,\n            path: Arc::clone(&path),\n        })\n    }\n}\n\nimpl<S, B> Service<Request<B>> for SetNestedPath<S>\nwhere\n    S: Service<Request<B>>,\n{\n    type Response = S::Response;\n    type Error = S::Error;\n    type Future = S::Future;\n\n    #[inline]\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, mut req: Request<B>) -> Self::Future {\n        if let Some(prev) = req.extensions_mut().get_mut::<NestedPath>() {\n            let new_path = if prev.as_str() == \"/\" {\n                Arc::clone(&self.path)\n            } else {\n                format!(\"{}{}\", prev.as_str().trim_end_matches('/'), self.path).into()\n            };\n            prev.0 = new_path;\n        } else {\n            req.extensions_mut()\n                .insert(NestedPath(Arc::clone(&self.path)));\n        };\n\n        self.inner.call(req)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use axum_core::response::Response;\n    use http::StatusCode;\n\n    use crate::{\n        extract::{NestedPath, Request},\n        middleware::{from_fn, Next},\n        routing::get,\n        test_helpers::*,\n        Router,\n    };\n\n    #[crate::test]\n    async fn one_level_of_nesting() {\n        let api = Router::new().route(\n            \"/users\",\n            get(|nested_path: NestedPath| {\n                assert_eq!(nested_path.as_str(), \"/api\");\n                async {}\n            }),\n        );\n\n        let app = Router::new().nest(\"/api\", api);\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/api/users\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn one_level_of_nesting_with_trailing_slash() {\n        let api = Router::new().route(\n            \"/users\",\n            get(|nested_path: NestedPath| {\n                assert_eq!(nested_path.as_str(), \"/api/\");\n                async {}\n            }),\n        );\n\n        let app = Router::new().nest(\"/api/\", api);\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/api/users\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn two_levels_of_nesting() {\n        let api = Router::new().route(\n            \"/users\",\n            get(|nested_path: NestedPath| {\n                assert_eq!(nested_path.as_str(), \"/api/v2\");\n                async {}\n            }),\n        );\n\n        let app = Router::new().nest(\"/api\", Router::new().nest(\"/v2\", api));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/api/v2/users\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn two_levels_of_nesting_with_trailing_slash() {\n        let api = Router::new().route(\n            \"/users\",\n            get(|nested_path: NestedPath| {\n                assert_eq!(nested_path.as_str(), \"/api/v2\");\n                async {}\n            }),\n        );\n\n        let app = Router::new().nest(\"/api/\", Router::new().nest(\"/v2\", api));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/api/v2/users\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn in_fallbacks() {\n        let api = Router::new().fallback(get(|nested_path: NestedPath| {\n            assert_eq!(nested_path.as_str(), \"/api\");\n            async {}\n        }));\n\n        let app = Router::new().nest(\"/api\", api);\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/api/doesnt-exist\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn in_middleware() {\n        async fn middleware(nested_path: NestedPath, req: Request, next: Next) -> Response {\n            assert_eq!(nested_path.as_str(), \"/api\");\n            next.run(req).await\n        }\n\n        let api = Router::new()\n            .route(\"/users\", get(|| async {}))\n            .layer(from_fn(middleware));\n\n        let app = Router::new().nest(\"/api\", api);\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/api/users\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/original_uri.rs",
    "content": "use super::{Extension, FromRequestParts};\nuse http::{request::Parts, Uri};\nuse std::convert::Infallible;\n\n/// Extractor that gets the original request URI regardless of nesting.\n///\n/// This is necessary since [`Uri`](http::Uri), when used as an extractor, will\n/// have the prefix stripped if used in a nested service.\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     routing::get,\n///     Router,\n///     extract::OriginalUri,\n///     http::Uri\n/// };\n///\n/// let api_routes = Router::new()\n///     .route(\n///         \"/users\",\n///         get(|uri: Uri, OriginalUri(original_uri): OriginalUri| async {\n///             // `uri` is `/users`\n///             // `original_uri` is `/api/users`\n///         }),\n///     );\n///\n/// let app = Router::new().nest(\"/api\", api_routes);\n/// # let _: Router = app;\n/// ```\n///\n/// # Extracting via request extensions\n///\n/// `OriginalUri` can also be accessed from middleware via request extensions.\n/// This is useful for example with [`Trace`](tower_http::trace::Trace) to\n/// create a span that contains the full path, if your service might be nested:\n///\n/// ```\n/// use axum::{\n///     Router,\n///     extract::OriginalUri,\n///     http::Request,\n///     routing::get,\n/// };\n/// use tower_http::trace::TraceLayer;\n///\n/// let api_routes = Router::new()\n///     .route(\"/users/{id}\", get(|| async { /* ... */ }))\n///     .layer(\n///         TraceLayer::new_for_http().make_span_with(|req: &Request<_>| {\n///             let path = if let Some(path) = req.extensions().get::<OriginalUri>() {\n///                 // This will include `/api`\n///                 path.0.path().to_owned()\n///             } else {\n///                 // The `OriginalUri` extension will always be present if using\n///                 // `Router` unless another extractor or middleware has removed it\n///                 req.uri().path().to_owned()\n///             };\n///             tracing::info_span!(\"http-request\", %path)\n///         }),\n///     );\n///\n/// let app = Router::new().nest(\"/api\", api_routes);\n/// # let _: Router = app;\n/// ```\n#[derive(Debug, Clone)]\npub struct OriginalUri(pub Uri);\n\nimpl<S> FromRequestParts<S> for OriginalUri\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let uri = Extension::<Self>::from_request_parts(parts, state)\n            .await\n            .unwrap_or_else(|_| Extension(Self(parts.uri.clone())))\n            .0;\n        Ok(uri)\n    }\n}\n\naxum_core::__impl_deref!(OriginalUri: Uri);\n"
  },
  {
    "path": "axum/src/extract/path/de.rs",
    "content": "use super::{ErrorKind, PathDeserializationError};\nuse crate::util::PercentDecodedStr;\nuse serde_core::{\n    de::{self, DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor},\n    forward_to_deserialize_any, Deserializer,\n};\nuse std::{any::type_name, sync::Arc};\n\nmacro_rules! unsupported_type {\n    ($trait_fn:ident) => {\n        fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>\n        where\n            V: Visitor<'de>,\n        {\n            Err(PathDeserializationError::unsupported_type(type_name::<\n                V::Value,\n            >()))\n        }\n    };\n}\n\nmacro_rules! parse_single_value {\n    ($trait_fn:ident, $visit_fn:ident, $ty:literal) => {\n        fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n        where\n            V: Visitor<'de>,\n        {\n            if self.url_params.len() != 1 {\n                return Err(PathDeserializationError::wrong_number_of_parameters()\n                    .got(self.url_params.len())\n                    .expected(1));\n            }\n\n            let value = self.url_params[0].1.parse().map_err(|_| {\n                PathDeserializationError::new(ErrorKind::ParseError {\n                    value: self.url_params[0].1.as_str().to_owned(),\n                    expected_type: $ty,\n                })\n            })?;\n            visitor.$visit_fn(value)\n        }\n    };\n}\n\npub(crate) struct PathDeserializer<'de> {\n    url_params: &'de [(Arc<str>, PercentDecodedStr)],\n}\n\nimpl<'de> PathDeserializer<'de> {\n    #[inline]\n    pub(crate) fn new(url_params: &'de [(Arc<str>, PercentDecodedStr)]) -> Self {\n        PathDeserializer { url_params }\n    }\n}\n\nimpl<'de> Deserializer<'de> for PathDeserializer<'de> {\n    type Error = PathDeserializationError;\n\n    unsupported_type!(deserialize_bytes);\n    unsupported_type!(deserialize_option);\n    unsupported_type!(deserialize_identifier);\n    unsupported_type!(deserialize_ignored_any);\n\n    parse_single_value!(deserialize_bool, visit_bool, \"bool\");\n    parse_single_value!(deserialize_i8, visit_i8, \"i8\");\n    parse_single_value!(deserialize_i16, visit_i16, \"i16\");\n    parse_single_value!(deserialize_i32, visit_i32, \"i32\");\n    parse_single_value!(deserialize_i64, visit_i64, \"i64\");\n    parse_single_value!(deserialize_i128, visit_i128, \"i128\");\n    parse_single_value!(deserialize_u8, visit_u8, \"u8\");\n    parse_single_value!(deserialize_u16, visit_u16, \"u16\");\n    parse_single_value!(deserialize_u32, visit_u32, \"u32\");\n    parse_single_value!(deserialize_u64, visit_u64, \"u64\");\n    parse_single_value!(deserialize_u128, visit_u128, \"u128\");\n    parse_single_value!(deserialize_f32, visit_f32, \"f32\");\n    parse_single_value!(deserialize_f64, visit_f64, \"f64\");\n    parse_single_value!(deserialize_string, visit_string, \"String\");\n    parse_single_value!(deserialize_byte_buf, visit_string, \"String\");\n    parse_single_value!(deserialize_char, visit_char, \"char\");\n\n    fn deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        self.deserialize_str(v)\n    }\n\n    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        if self.url_params.len() != 1 {\n            return Err(PathDeserializationError::wrong_number_of_parameters()\n                .got(self.url_params.len())\n                .expected(1));\n        }\n        let key = &self.url_params[0].0;\n        let value = &self.url_params[0].1;\n        visitor\n            .visit_borrowed_str(value)\n            .map_err(|e: PathDeserializationError| {\n                if let ErrorKind::Message(message) = &e.kind {\n                    PathDeserializationError::new(ErrorKind::DeserializeError {\n                        key: key.to_string(),\n                        value: value.as_str().to_owned(),\n                        message: message.to_owned(),\n                    })\n                } else {\n                    e\n                }\n            })\n    }\n\n    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_unit()\n    }\n\n    fn deserialize_unit_struct<V>(\n        self,\n        _name: &'static str,\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_unit()\n    }\n\n    fn deserialize_newtype_struct<V>(\n        self,\n        _name: &'static str,\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_newtype_struct(self)\n    }\n\n    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_seq(SeqDeserializer {\n            params: self.url_params,\n            idx: 0,\n        })\n    }\n\n    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        if self.url_params.len() != len {\n            return Err(PathDeserializationError::wrong_number_of_parameters()\n                .got(self.url_params.len())\n                .expected(len));\n        }\n        visitor.visit_seq(SeqDeserializer {\n            params: self.url_params,\n            idx: 0,\n        })\n    }\n\n    fn deserialize_tuple_struct<V>(\n        self,\n        _name: &'static str,\n        len: usize,\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        if self.url_params.len() != len {\n            return Err(PathDeserializationError::wrong_number_of_parameters()\n                .got(self.url_params.len())\n                .expected(len));\n        }\n        visitor.visit_seq(SeqDeserializer {\n            params: self.url_params,\n            idx: 0,\n        })\n    }\n\n    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_map(MapDeserializer {\n            params: self.url_params,\n            value: None,\n            key: None,\n        })\n    }\n\n    fn deserialize_struct<V>(\n        self,\n        _name: &'static str,\n        _fields: &'static [&'static str],\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        self.deserialize_map(visitor)\n    }\n\n    fn deserialize_enum<V>(\n        self,\n        _name: &'static str,\n        _variants: &'static [&'static str],\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        if self.url_params.len() != 1 {\n            return Err(PathDeserializationError::wrong_number_of_parameters()\n                .got(self.url_params.len())\n                .expected(1));\n        }\n\n        visitor.visit_enum(EnumDeserializer {\n            value: &self.url_params[0].1,\n        })\n    }\n}\n\nstruct MapDeserializer<'de> {\n    params: &'de [(Arc<str>, PercentDecodedStr)],\n    key: Option<KeyOrIdx<'de>>,\n    value: Option<&'de PercentDecodedStr>,\n}\n\nimpl<'de> MapAccess<'de> for MapDeserializer<'de> {\n    type Error = PathDeserializationError;\n\n    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>\n    where\n        K: DeserializeSeed<'de>,\n    {\n        match self.params.split_first() {\n            Some(((key, value), tail)) => {\n                self.value = Some(value);\n                self.params = tail;\n                self.key = Some(KeyOrIdx::Key(key));\n                seed.deserialize(KeyDeserializer { key }).map(Some)\n            }\n            None => Ok(None),\n        }\n    }\n\n    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>\n    where\n        V: DeserializeSeed<'de>,\n    {\n        match self.value.take() {\n            Some(value) => seed.deserialize(ValueDeserializer {\n                key: self.key.take(),\n                value,\n            }),\n            None => Err(PathDeserializationError::custom(\"value is missing\")),\n        }\n    }\n}\n\nstruct KeyDeserializer<'de> {\n    key: &'de str,\n}\n\nmacro_rules! parse_key {\n    ($trait_fn:ident) => {\n        fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n        where\n            V: Visitor<'de>,\n        {\n            visitor.visit_str(&self.key)\n        }\n    };\n}\n\nimpl<'de> Deserializer<'de> for KeyDeserializer<'de> {\n    type Error = PathDeserializationError;\n\n    parse_key!(deserialize_identifier);\n    parse_key!(deserialize_str);\n    parse_key!(deserialize_string);\n\n    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        Err(PathDeserializationError::custom(\"Unexpected key type\"))\n    }\n\n    forward_to_deserialize_any! {\n        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char bytes\n        byte_buf option unit unit_struct seq tuple\n        tuple_struct map newtype_struct struct enum ignored_any\n    }\n}\n\nmacro_rules! parse_value {\n    ($trait_fn:ident, $visit_fn:ident, $ty:literal) => {\n        fn $trait_fn<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>\n        where\n            V: Visitor<'de>,\n        {\n            let v = self.value.parse().map_err(|_| {\n                if let Some(key) = self.key.take() {\n                    let kind = match key {\n                        KeyOrIdx::Key(key) => ErrorKind::ParseErrorAtKey {\n                            key: key.to_owned(),\n                            value: self.value.as_str().to_owned(),\n                            expected_type: $ty,\n                        },\n                        KeyOrIdx::Idx { idx: index, key: _ } => ErrorKind::ParseErrorAtIndex {\n                            index,\n                            value: self.value.as_str().to_owned(),\n                            expected_type: $ty,\n                        },\n                    };\n                    PathDeserializationError::new(kind)\n                } else {\n                    PathDeserializationError::new(ErrorKind::ParseError {\n                        value: self.value.as_str().to_owned(),\n                        expected_type: $ty,\n                    })\n                }\n            })?;\n            visitor.$visit_fn(v)\n        }\n    };\n}\n\n#[derive(Debug)]\nstruct ValueDeserializer<'de> {\n    key: Option<KeyOrIdx<'de>>,\n    value: &'de PercentDecodedStr,\n}\n\nimpl<'de> Deserializer<'de> for ValueDeserializer<'de> {\n    type Error = PathDeserializationError;\n\n    unsupported_type!(deserialize_map);\n    unsupported_type!(deserialize_identifier);\n\n    parse_value!(deserialize_bool, visit_bool, \"bool\");\n    parse_value!(deserialize_i8, visit_i8, \"i8\");\n    parse_value!(deserialize_i16, visit_i16, \"i16\");\n    parse_value!(deserialize_i32, visit_i32, \"i32\");\n    parse_value!(deserialize_i64, visit_i64, \"i64\");\n    parse_value!(deserialize_i128, visit_i128, \"i128\");\n    parse_value!(deserialize_u8, visit_u8, \"u8\");\n    parse_value!(deserialize_u16, visit_u16, \"u16\");\n    parse_value!(deserialize_u32, visit_u32, \"u32\");\n    parse_value!(deserialize_u64, visit_u64, \"u64\");\n    parse_value!(deserialize_u128, visit_u128, \"u128\");\n    parse_value!(deserialize_f32, visit_f32, \"f32\");\n    parse_value!(deserialize_f64, visit_f64, \"f64\");\n    parse_value!(deserialize_string, visit_string, \"String\");\n    parse_value!(deserialize_byte_buf, visit_string, \"String\");\n    parse_value!(deserialize_char, visit_char, \"char\");\n\n    fn deserialize_any<V>(self, v: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        self.deserialize_str(v)\n    }\n\n    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor\n            .visit_borrowed_str(self.value)\n            .map_err(|e: PathDeserializationError| {\n                if let (ErrorKind::Message(message), Some(key)) = (&e.kind, self.key.as_ref()) {\n                    PathDeserializationError::new(ErrorKind::DeserializeError {\n                        key: key.key().to_owned(),\n                        value: self.value.as_str().to_owned(),\n                        message: message.to_owned(),\n                    })\n                } else {\n                    e\n                }\n            })\n    }\n\n    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_borrowed_bytes(self.value.as_bytes())\n    }\n\n    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_some(self)\n    }\n\n    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_unit()\n    }\n\n    fn deserialize_unit_struct<V>(\n        self,\n        _name: &'static str,\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_unit()\n    }\n\n    fn deserialize_newtype_struct<V>(\n        self,\n        _name: &'static str,\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_newtype_struct(self)\n    }\n\n    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        struct PairDeserializer<'de> {\n            key: Option<KeyOrIdx<'de>>,\n            value: Option<&'de PercentDecodedStr>,\n        }\n\n        impl<'de> SeqAccess<'de> for PairDeserializer<'de> {\n            type Error = PathDeserializationError;\n\n            fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>\n            where\n                T: DeserializeSeed<'de>,\n            {\n                match self.key.take() {\n                    Some(KeyOrIdx::Idx { idx: _, key }) => {\n                        return seed.deserialize(KeyDeserializer { key }).map(Some);\n                    }\n                    Some(KeyOrIdx::Key(_)) => {\n                        return Err(PathDeserializationError::custom(\n                            \"array types are not supported\",\n                        ));\n                    }\n                    None => {}\n                };\n\n                self.value\n                    .take()\n                    .map(|value| seed.deserialize(ValueDeserializer { key: None, value }))\n                    .transpose()\n            }\n        }\n\n        if len == 2 {\n            match self.key {\n                Some(key) => visitor.visit_seq(PairDeserializer {\n                    key: Some(key),\n                    value: Some(self.value),\n                }),\n                // `self.key` is only `None` when deserializing maps so `deserialize_seq`\n                // wouldn't be called for that\n                None => unreachable!(),\n            }\n        } else {\n            Err(PathDeserializationError::unsupported_type(type_name::<\n                V::Value,\n            >()))\n        }\n    }\n\n    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        Err(PathDeserializationError::unsupported_type(type_name::<\n            V::Value,\n        >()))\n    }\n\n    fn deserialize_tuple_struct<V>(\n        self,\n        _name: &'static str,\n        _len: usize,\n        _visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        Err(PathDeserializationError::unsupported_type(type_name::<\n            V::Value,\n        >()))\n    }\n\n    fn deserialize_struct<V>(\n        self,\n        _name: &'static str,\n        _fields: &'static [&'static str],\n        _visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        Err(PathDeserializationError::unsupported_type(type_name::<\n            V::Value,\n        >()))\n    }\n\n    fn deserialize_enum<V>(\n        self,\n        _name: &'static str,\n        _variants: &'static [&'static str],\n        visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_enum(EnumDeserializer { value: self.value })\n    }\n\n    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        visitor.visit_unit()\n    }\n}\n\nstruct EnumDeserializer<'de> {\n    value: &'de str,\n}\n\nimpl<'de> EnumAccess<'de> for EnumDeserializer<'de> {\n    type Error = PathDeserializationError;\n    type Variant = UnitVariant;\n\n    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>\n    where\n        V: de::DeserializeSeed<'de>,\n    {\n        Ok((\n            seed.deserialize(KeyDeserializer { key: self.value })?,\n            UnitVariant,\n        ))\n    }\n}\n\nstruct UnitVariant;\n\nimpl<'de> VariantAccess<'de> for UnitVariant {\n    type Error = PathDeserializationError;\n\n    fn unit_variant(self) -> Result<(), Self::Error> {\n        Ok(())\n    }\n\n    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>\n    where\n        T: DeserializeSeed<'de>,\n    {\n        Err(PathDeserializationError::unsupported_type(\n            \"newtype enum variant\",\n        ))\n    }\n\n    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        Err(PathDeserializationError::unsupported_type(\n            \"tuple enum variant\",\n        ))\n    }\n\n    fn struct_variant<V>(\n        self,\n        _fields: &'static [&'static str],\n        _visitor: V,\n    ) -> Result<V::Value, Self::Error>\n    where\n        V: Visitor<'de>,\n    {\n        Err(PathDeserializationError::unsupported_type(\n            \"struct enum variant\",\n        ))\n    }\n}\n\nstruct SeqDeserializer<'de> {\n    params: &'de [(Arc<str>, PercentDecodedStr)],\n    idx: usize,\n}\n\nimpl<'de> SeqAccess<'de> for SeqDeserializer<'de> {\n    type Error = PathDeserializationError;\n\n    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>\n    where\n        T: DeserializeSeed<'de>,\n    {\n        match self.params.split_first() {\n            Some(((key, value), tail)) => {\n                self.params = tail;\n                let idx = self.idx;\n                self.idx += 1;\n                Ok(Some(seed.deserialize(ValueDeserializer {\n                    key: Some(KeyOrIdx::Idx { idx, key }),\n                    value,\n                })?))\n            }\n            None => Ok(None),\n        }\n    }\n}\n\n#[derive(Debug, Clone)]\nenum KeyOrIdx<'de> {\n    Key(&'de str),\n    Idx { idx: usize, key: &'de str },\n}\n\nimpl<'de> KeyOrIdx<'de> {\n    fn key(&self) -> &'de str {\n        match &self {\n            Self::Idx { key, .. } | Self::Key(key) => key,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use serde::Deserialize;\n    use std::collections::HashMap;\n\n    #[derive(Debug, Deserialize, Eq, PartialEq)]\n    enum MyEnum {\n        A,\n        B,\n        #[serde(rename = \"c\")]\n        C,\n    }\n\n    #[derive(Debug, Deserialize, Eq, PartialEq)]\n    struct Struct {\n        c: String,\n        b: bool,\n        a: i32,\n    }\n\n    fn create_url_params<I, K, V>(values: I) -> Vec<(Arc<str>, PercentDecodedStr)>\n    where\n        I: IntoIterator<Item = (K, V)>,\n        K: AsRef<str>,\n        V: AsRef<str>,\n    {\n        values\n            .into_iter()\n            .map(|(k, v)| (Arc::from(k.as_ref()), PercentDecodedStr::new(v).unwrap()))\n            .collect()\n    }\n\n    macro_rules! check_single_value {\n        ($ty:ty, $value_str:literal, $value:expr) => {\n            #[allow(clippy::bool_assert_comparison)]\n            {\n                let url_params = create_url_params(vec![(\"value\", $value_str)]);\n                let deserializer = PathDeserializer::new(&url_params);\n                assert_eq!(<$ty>::deserialize(deserializer).unwrap(), $value);\n            }\n        };\n    }\n\n    #[test]\n    fn test_parse_single_value() {\n        check_single_value!(bool, \"true\", true);\n        check_single_value!(bool, \"false\", false);\n        check_single_value!(i8, \"-123\", -123);\n        check_single_value!(i16, \"-123\", -123);\n        check_single_value!(i32, \"-123\", -123);\n        check_single_value!(i64, \"-123\", -123);\n        check_single_value!(i128, \"123\", 123);\n        check_single_value!(u8, \"123\", 123);\n        check_single_value!(u16, \"123\", 123);\n        check_single_value!(u32, \"123\", 123);\n        check_single_value!(u64, \"123\", 123);\n        check_single_value!(u128, \"123\", 123);\n        check_single_value!(f32, \"123\", 123.0);\n        check_single_value!(f64, \"123\", 123.0);\n        check_single_value!(String, \"abc\", \"abc\");\n        check_single_value!(String, \"one%20two\", \"one two\");\n        check_single_value!(&str, \"abc\", \"abc\");\n        check_single_value!(&str, \"one%20two\", \"one two\");\n        check_single_value!(char, \"a\", 'a');\n\n        let url_params = create_url_params(vec![(\"a\", \"B\")]);\n        assert_eq!(\n            MyEnum::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            MyEnum::B\n        );\n\n        let url_params = create_url_params(vec![(\"a\", \"1\"), (\"b\", \"2\")]);\n        let error_kind = i32::deserialize(PathDeserializer::new(&url_params))\n            .unwrap_err()\n            .kind;\n        assert!(matches!(\n            error_kind,\n            ErrorKind::WrongNumberOfParameters {\n                expected: 1,\n                got: 2\n            }\n        ));\n    }\n\n    #[test]\n    fn test_parse_seq() {\n        let url_params = create_url_params(vec![(\"a\", \"1\"), (\"b\", \"true\"), (\"c\", \"abc\")]);\n        assert_eq!(\n            <(i32, bool, String)>::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            (1, true, \"abc\".to_owned())\n        );\n\n        #[derive(Debug, Deserialize, Eq, PartialEq)]\n        struct TupleStruct(i32, bool, String);\n        assert_eq!(\n            TupleStruct::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            TupleStruct(1, true, \"abc\".to_owned())\n        );\n\n        let url_params = create_url_params(vec![(\"a\", \"1\"), (\"b\", \"2\"), (\"c\", \"3\")]);\n        assert_eq!(\n            <Vec<i32>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            vec![1, 2, 3]\n        );\n\n        let url_params = create_url_params(vec![(\"a\", \"c\"), (\"a\", \"B\")]);\n        assert_eq!(\n            <Vec<MyEnum>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            vec![MyEnum::C, MyEnum::B]\n        );\n    }\n\n    #[test]\n    fn test_parse_seq_tuple_string_string() {\n        let url_params = create_url_params(vec![(\"a\", \"foo\"), (\"b\", \"bar\")]);\n        assert_eq!(\n            <Vec<(String, String)>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            vec![\n                (\"a\".to_owned(), \"foo\".to_owned()),\n                (\"b\".to_owned(), \"bar\".to_owned())\n            ]\n        );\n    }\n\n    #[test]\n    fn test_parse_seq_tuple_string_parse() {\n        let url_params = create_url_params(vec![(\"a\", \"1\"), (\"b\", \"2\")]);\n        assert_eq!(\n            <Vec<(String, u32)>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            vec![(\"a\".to_owned(), 1), (\"b\".to_owned(), 2)]\n        );\n    }\n\n    #[test]\n    fn test_parse_struct() {\n        let url_params = create_url_params(vec![(\"a\", \"1\"), (\"b\", \"true\"), (\"c\", \"abc\")]);\n        assert_eq!(\n            Struct::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            Struct {\n                c: \"abc\".to_owned(),\n                b: true,\n                a: 1,\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_struct_ignoring_additional_fields() {\n        let url_params = create_url_params(vec![\n            (\"a\", \"1\"),\n            (\"b\", \"true\"),\n            (\"c\", \"abc\"),\n            (\"d\", \"false\"),\n        ]);\n        assert_eq!(\n            Struct::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            Struct {\n                c: \"abc\".to_owned(),\n                b: true,\n                a: 1,\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_map() {\n        let url_params = create_url_params(vec![(\"a\", \"1\"), (\"b\", \"true\"), (\"c\", \"abc\")]);\n        assert_eq!(\n            <HashMap<String, String>>::deserialize(PathDeserializer::new(&url_params)).unwrap(),\n            [(\"a\", \"1\"), (\"b\", \"true\"), (\"c\", \"abc\")]\n                .iter()\n                .map(|(key, value)| ((*key).to_owned(), (*value).to_owned()))\n                .collect()\n        );\n    }\n\n    macro_rules! test_parse_error {\n        (\n            $params:expr,\n            $ty:ty,\n            $expected_error_kind:expr $(,)?\n        ) => {\n            let url_params = create_url_params($params);\n            let actual_error_kind = <$ty>::deserialize(PathDeserializer::new(&url_params))\n                .unwrap_err()\n                .kind;\n            assert_eq!(actual_error_kind, $expected_error_kind);\n        };\n    }\n\n    #[test]\n    fn test_parse_tuple_too_many_fields() {\n        test_parse_error!(\n            vec![(\"a\", \"abc\"), (\"b\", \"true\"), (\"c\", \"1\"), (\"d\", \"false\"),],\n            (&str, bool, u32),\n            ErrorKind::WrongNumberOfParameters {\n                got: 4,\n                expected: 3,\n            }\n        );\n    }\n\n    #[test]\n    fn test_wrong_number_of_parameters_error() {\n        test_parse_error!(\n            vec![(\"a\", \"1\")],\n            (u32, u32),\n            ErrorKind::WrongNumberOfParameters {\n                got: 1,\n                expected: 2,\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_error_at_key_error() {\n        #[derive(Debug, Deserialize)]\n        #[allow(dead_code)]\n        struct Params {\n            a: u32,\n        }\n        test_parse_error!(\n            vec![(\"a\", \"false\")],\n            Params,\n            ErrorKind::ParseErrorAtKey {\n                key: \"a\".to_owned(),\n                value: \"false\".to_owned(),\n                expected_type: \"u32\",\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_error_at_key_error_multiple() {\n        #[derive(Debug, Deserialize)]\n        #[allow(dead_code)]\n        struct Params {\n            a: u32,\n            b: u32,\n        }\n        test_parse_error!(\n            vec![(\"a\", \"false\")],\n            Params,\n            ErrorKind::ParseErrorAtKey {\n                key: \"a\".to_owned(),\n                value: \"false\".to_owned(),\n                expected_type: \"u32\",\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_error_at_index_error() {\n        test_parse_error!(\n            vec![(\"a\", \"false\"), (\"b\", \"true\")],\n            (bool, u32),\n            ErrorKind::ParseErrorAtIndex {\n                index: 1,\n                value: \"true\".to_owned(),\n                expected_type: \"u32\",\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_error_error() {\n        test_parse_error!(\n            vec![(\"a\", \"false\")],\n            u32,\n            ErrorKind::ParseError {\n                value: \"false\".to_owned(),\n                expected_type: \"u32\",\n            }\n        );\n    }\n\n    #[test]\n    fn test_unsupported_type_error_nested_data_structure() {\n        test_parse_error!(\n            vec![(\"a\", \"false\")],\n            Vec<Vec<u32>>,\n            ErrorKind::UnsupportedType {\n                name: \"alloc::vec::Vec<u32>\",\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_seq_tuple_unsupported_key_type() {\n        test_parse_error!(\n            vec![(\"a\", \"false\")],\n            Vec<(u32, String)>,\n            ErrorKind::Message(\"Unexpected key type\".to_owned())\n        );\n    }\n\n    #[test]\n    fn test_parse_seq_wrong_tuple_length() {\n        test_parse_error!(\n            vec![(\"a\", \"false\")],\n            Vec<(String, String, String)>,\n            ErrorKind::UnsupportedType {\n                name: \"(alloc::string::String, alloc::string::String, alloc::string::String)\",\n            }\n        );\n    }\n\n    #[test]\n    fn test_parse_seq_seq() {\n        test_parse_error!(\n            vec![(\"a\", \"false\")],\n            Vec<Vec<String>>,\n            ErrorKind::UnsupportedType {\n                name: \"alloc::vec::Vec<alloc::string::String>\",\n            }\n        );\n    }\n\n    #[test]\n    fn test_deserialize_key_value() {\n        test_parse_error!(\n            vec![(\"id\", \"123123-123-123123\")],\n            uuid::Uuid,\n            ErrorKind::DeserializeError {\n                key: \"id\".to_owned(),\n                value: \"123123-123-123123\".to_owned(),\n                message: \"UUID parsing failed: invalid group count: expected 5, found 3\".to_owned(),\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/path/mod.rs",
    "content": "//! Extractor that will get captures from the URL and parse them using\n//! [`serde`].\n\nmod de;\n\nuse crate::{\n    extract::{rejection::*, FromRequestParts},\n    routing::url_params::UrlParams,\n    util::PercentDecodedStr,\n};\nuse axum_core::{\n    extract::OptionalFromRequestParts,\n    response::{IntoResponse, Response},\n    RequestPartsExt as _,\n};\nuse http::{request::Parts, StatusCode};\nuse serde_core::de::DeserializeOwned;\nuse std::{fmt, sync::Arc};\n\n/// Extractor that will get captures from the URL and parse them using\n/// [`serde`].\n///\n/// Any percent encoded parameters will be automatically decoded. The decoded\n/// parameters must be valid UTF-8, otherwise `Path` will fail and return a `400\n/// Bad Request` response.\n///\n/// # `Option<Path<T>>` behavior\n///\n/// You can use `Option<Path<T>>` as an extractor to allow the same handler to\n/// be used in a route with parameters that deserialize to `T`, and another\n/// route with no parameters at all.\n///\n/// # Example\n///\n/// These examples assume the `serde` feature of the [`uuid`] crate is enabled.\n///\n/// One `Path` can extract multiple captures. It is not necessary (and does\n/// not work) to give a handler more than one `Path` argument.\n///\n/// [`uuid`]: https://crates.io/crates/uuid\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::Path,\n///     routing::get,\n///     Router,\n/// };\n/// use uuid::Uuid;\n///\n/// async fn users_teams_show(\n///     Path((user_id, team_id)): Path<(Uuid, Uuid)>,\n/// ) {\n///     // ...\n/// }\n///\n/// let app = Router::new().route(\"/users/{user_id}/team/{team_id}\", get(users_teams_show));\n/// # let _: Router = app;\n/// ```\n///\n/// If the path contains only one parameter, then you can omit the tuple.\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::Path,\n///     routing::get,\n///     Router,\n/// };\n/// use uuid::Uuid;\n///\n/// async fn user_info(Path(user_id): Path<Uuid>) {\n///     // ...\n/// }\n///\n/// let app = Router::new().route(\"/users/{user_id}\", get(user_info));\n/// # let _: Router = app;\n/// ```\n///\n/// Path segments also can be deserialized into any type that implements\n/// [`serde::Deserialize`]. This includes tuples and structs:\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::Path,\n///     routing::get,\n///     Router,\n/// };\n/// use serde::Deserialize;\n/// use uuid::Uuid;\n///\n/// // Path segment labels will be matched with struct field names\n/// #[derive(Deserialize)]\n/// struct Params {\n///     user_id: Uuid,\n///     team_id: Uuid,\n/// }\n///\n/// async fn users_teams_show(\n///     Path(Params { user_id, team_id }): Path<Params>,\n/// ) {\n///     // ...\n/// }\n///\n/// // When using tuples the path segments will be matched by their position in the route\n/// async fn users_teams_create(\n///     Path((user_id, team_id)): Path<(String, String)>,\n/// ) {\n///     // ...\n/// }\n///\n/// let app = Router::new().route(\n///     \"/users/{user_id}/team/{team_id}\",\n///     get(users_teams_show).post(users_teams_create),\n/// );\n/// # let _: Router = app;\n/// ```\n///\n/// If you wish to capture all path parameters you can use `HashMap` or `Vec`:\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::Path,\n///     routing::get,\n///     Router,\n/// };\n/// use std::collections::HashMap;\n///\n/// async fn params_map(\n///     Path(params): Path<HashMap<String, String>>,\n/// ) {\n///     // ...\n/// }\n///\n/// async fn params_vec(\n///     Path(params): Path<Vec<(String, String)>>,\n/// ) {\n///     // ...\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/users/{user_id}/team/{team_id}\", get(params_map).post(params_vec));\n/// # let _: Router = app;\n/// ```\n///\n/// # Providing detailed rejection output\n///\n/// If the URI cannot be deserialized into the target type the request will be rejected and an\n/// error response will be returned. See [`customize-path-rejection`] for an example of how to customize that error.\n///\n/// [`serde`]: https://crates.io/crates/serde\n/// [`serde::Deserialize`]: https://docs.rs/serde/1.0.127/serde/trait.Deserialize.html\n/// [`customize-path-rejection`]: https://github.com/tokio-rs/axum/blob/main/examples/customize-path-rejection/src/main.rs\n#[derive(Debug)]\npub struct Path<T>(pub T);\n\naxum_core::__impl_deref!(Path);\n\nimpl<T, S> FromRequestParts<S> for Path<T>\nwhere\n    T: DeserializeOwned + Send,\n    S: Send + Sync,\n{\n    type Rejection = PathRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        // Extracted into separate fn so it's only compiled once for all T.\n        fn get_params(parts: &Parts) -> Result<&[(Arc<str>, PercentDecodedStr)], PathRejection> {\n            match parts.extensions.get::<UrlParams>() {\n                Some(UrlParams::Params(params)) => Ok(params),\n                Some(UrlParams::InvalidUtf8InPathParam { key }) => {\n                    let err = PathDeserializationError {\n                        kind: ErrorKind::InvalidUtf8InPathParam {\n                            key: key.to_string(),\n                        },\n                    };\n                    Err(FailedToDeserializePathParams(err).into())\n                }\n                None => Err(MissingPathParams.into()),\n            }\n        }\n\n        fn failed_to_deserialize_path_params(err: PathDeserializationError) -> PathRejection {\n            PathRejection::FailedToDeserializePathParams(FailedToDeserializePathParams(err))\n        }\n\n        match T::deserialize(de::PathDeserializer::new(get_params(parts)?)) {\n            Ok(val) => Ok(Self(val)),\n            Err(e) => Err(failed_to_deserialize_path_params(e)),\n        }\n    }\n}\n\nimpl<T, S> OptionalFromRequestParts<S> for Path<T>\nwhere\n    T: DeserializeOwned + Send + 'static,\n    S: Send + Sync,\n{\n    type Rejection = PathRejection;\n\n    async fn from_request_parts(\n        parts: &mut Parts,\n        _state: &S,\n    ) -> Result<Option<Self>, Self::Rejection> {\n        match parts.extract::<Self>().await {\n            Ok(Self(params)) => Ok(Some(Self(params))),\n            Err(PathRejection::FailedToDeserializePathParams(e))\n                if matches!(e.kind(), ErrorKind::WrongNumberOfParameters { got: 0, .. }) =>\n            {\n                Ok(None)\n            }\n            Err(e) => Err(e),\n        }\n    }\n}\n\n// this wrapper type is used as the deserializer error to hide the `serde::de::Error` impl which\n// would otherwise be public if we used `ErrorKind` as the error directly\n#[derive(Debug)]\npub(crate) struct PathDeserializationError {\n    pub(super) kind: ErrorKind,\n}\n\nimpl PathDeserializationError {\n    pub(super) fn new(kind: ErrorKind) -> Self {\n        Self { kind }\n    }\n\n    pub(super) fn wrong_number_of_parameters() -> WrongNumberOfParameters<()> {\n        WrongNumberOfParameters { got: () }\n    }\n\n    #[track_caller]\n    pub(super) fn unsupported_type(name: &'static str) -> Self {\n        Self::new(ErrorKind::UnsupportedType { name })\n    }\n}\n\npub(super) struct WrongNumberOfParameters<G> {\n    got: G,\n}\n\nimpl<G> WrongNumberOfParameters<G> {\n    #[allow(clippy::unused_self)]\n    pub(super) fn got<G2>(self, got: G2) -> WrongNumberOfParameters<G2> {\n        WrongNumberOfParameters { got }\n    }\n}\n\nimpl WrongNumberOfParameters<usize> {\n    pub(super) fn expected(self, expected: usize) -> PathDeserializationError {\n        PathDeserializationError::new(ErrorKind::WrongNumberOfParameters {\n            got: self.got,\n            expected,\n        })\n    }\n}\n\nimpl serde_core::de::Error for PathDeserializationError {\n    #[inline]\n    fn custom<T>(msg: T) -> Self\n    where\n        T: fmt::Display,\n    {\n        Self {\n            kind: ErrorKind::Message(msg.to_string()),\n        }\n    }\n}\n\nimpl fmt::Display for PathDeserializationError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.kind.fmt(f)\n    }\n}\n\nimpl std::error::Error for PathDeserializationError {}\n\n/// The kinds of errors that can happen we deserializing into a [`Path`].\n///\n/// This type is obtained through [`FailedToDeserializePathParams::kind`] or\n/// [`FailedToDeserializePathParams::into_kind`] and is useful for building\n/// more precise error messages.\n#[must_use]\n#[derive(Debug, PartialEq, Eq)]\n#[non_exhaustive]\npub enum ErrorKind {\n    /// The URI contained the wrong number of parameters.\n    WrongNumberOfParameters {\n        /// The number of actual parameters in the URI.\n        got: usize,\n        /// The number of expected parameters.\n        expected: usize,\n    },\n\n    /// Failed to parse the value at a specific key into the expected type.\n    ///\n    /// This variant is used when deserializing into types that have named fields, such as structs.\n    ParseErrorAtKey {\n        /// The key at which the value was located.\n        key: String,\n        /// The value from the URI.\n        value: String,\n        /// The expected type of the value.\n        expected_type: &'static str,\n    },\n\n    /// Failed to parse the value at a specific index into the expected type.\n    ///\n    /// This variant is used when deserializing into sequence types, such as tuples.\n    ParseErrorAtIndex {\n        /// The index at which the value was located.\n        index: usize,\n        /// The value from the URI.\n        value: String,\n        /// The expected type of the value.\n        expected_type: &'static str,\n    },\n\n    /// Failed to parse a value into the expected type.\n    ///\n    /// This variant is used when deserializing into a primitive type (such as `String` and `u32`).\n    ParseError {\n        /// The value from the URI.\n        value: String,\n        /// The expected type of the value.\n        expected_type: &'static str,\n    },\n\n    /// A parameter contained text that, once percent decoded, wasn't valid UTF-8.\n    InvalidUtf8InPathParam {\n        /// The key at which the invalid value was located.\n        key: String,\n    },\n\n    /// Tried to serialize into an unsupported type such as nested maps.\n    ///\n    /// This error kind is caused by programmer errors and thus gets converted into a `500 Internal\n    /// Server Error` response.\n    UnsupportedType {\n        /// The name of the unsupported type.\n        name: &'static str,\n    },\n\n    /// Failed to deserialize the value with a custom deserialization error.\n    DeserializeError {\n        /// The key at which the invalid value was located.\n        key: String,\n        /// The value that failed to deserialize.\n        value: String,\n        /// The deserialization failure message.\n        message: String,\n    },\n\n    /// Catch-all variant for errors that don't fit any other variant.\n    Message(String),\n}\n\nimpl fmt::Display for ErrorKind {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::Message(error) => error.fmt(f),\n            Self::InvalidUtf8InPathParam { key } => write!(f, \"Invalid UTF-8 in `{key}`\"),\n            Self::WrongNumberOfParameters { got, expected } => {\n                write!(\n                    f,\n                    \"Wrong number of path arguments for `Path`. Expected {expected} but got {got}\"\n                )?;\n\n                if *expected == 1 {\n                    write!(f, \". Note that multiple parameters must be extracted with a tuple `Path<(_, _)>` or a struct `Path<YourParams>`\")?;\n                }\n\n                Ok(())\n            }\n            Self::UnsupportedType { name } => write!(f, \"Unsupported type `{name}`\"),\n            Self::ParseErrorAtKey {\n                key,\n                value,\n                expected_type,\n            } => write!(\n                f,\n                \"Cannot parse `{key}` with value `{value}` to a `{expected_type}`\"\n            ),\n            Self::ParseError {\n                value,\n                expected_type,\n            } => write!(f, \"Cannot parse `{value}` to a `{expected_type}`\"),\n            Self::ParseErrorAtIndex {\n                index,\n                value,\n                expected_type,\n            } => write!(\n                f,\n                \"Cannot parse value at index {index} with value `{value}` to a `{expected_type}`\"\n            ),\n            Self::DeserializeError {\n                key,\n                value,\n                message,\n            } => write!(f, \"Cannot parse `{key}` with value `{value}`: {message}\"),\n        }\n    }\n}\n\n/// Rejection type for [`Path`] if the captured routes params couldn't be deserialized\n/// into the expected type.\n#[derive(Debug)]\npub struct FailedToDeserializePathParams(PathDeserializationError);\n\nimpl FailedToDeserializePathParams {\n    /// Get a reference to the underlying error kind.\n    pub fn kind(&self) -> &ErrorKind {\n        &self.0.kind\n    }\n\n    /// Convert this error into the underlying error kind.\n    pub fn into_kind(self) -> ErrorKind {\n        self.0.kind\n    }\n\n    /// Get the response body text used for this rejection.\n    #[must_use]\n    pub fn body_text(&self) -> String {\n        match self.0.kind {\n            ErrorKind::Message(_)\n            | ErrorKind::DeserializeError { .. }\n            | ErrorKind::InvalidUtf8InPathParam { .. }\n            | ErrorKind::ParseError { .. }\n            | ErrorKind::ParseErrorAtIndex { .. }\n            | ErrorKind::ParseErrorAtKey { .. } => format!(\"Invalid URL: {}\", self.0.kind),\n            ErrorKind::WrongNumberOfParameters { .. } | ErrorKind::UnsupportedType { .. } => {\n                self.0.kind.to_string()\n            }\n        }\n    }\n\n    /// Get the status code used for this rejection.\n    #[must_use]\n    pub fn status(&self) -> StatusCode {\n        match self.0.kind {\n            ErrorKind::Message(_)\n            | ErrorKind::DeserializeError { .. }\n            | ErrorKind::InvalidUtf8InPathParam { .. }\n            | ErrorKind::ParseError { .. }\n            | ErrorKind::ParseErrorAtIndex { .. }\n            | ErrorKind::ParseErrorAtKey { .. } => StatusCode::BAD_REQUEST,\n            ErrorKind::WrongNumberOfParameters { .. } | ErrorKind::UnsupportedType { .. } => {\n                StatusCode::INTERNAL_SERVER_ERROR\n            }\n        }\n    }\n}\n\nimpl IntoResponse for FailedToDeserializePathParams {\n    fn into_response(self) -> Response {\n        let body = self.body_text();\n        axum_core::__log_rejection!(\n            rejection_type = Self,\n            body_text = body,\n            status = self.status(),\n        );\n        (self.status(), body).into_response()\n    }\n}\n\nimpl fmt::Display for FailedToDeserializePathParams {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.0.fmt(f)\n    }\n}\n\nimpl std::error::Error for FailedToDeserializePathParams {}\n\n/// Extractor that will get captures from the URL without deserializing them.\n///\n/// In general you should prefer to use [`Path`] as it is higher level, however `RawPathParams` is\n/// suitable if just want the raw params without deserializing them and thus saving some\n/// allocations.\n///\n/// Any percent encoded parameters will be automatically decoded. The decoded parameters must be\n/// valid UTF-8, otherwise `RawPathParams` will fail and return a `400 Bad Request` response.\n///\n/// # Example\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::RawPathParams,\n///     routing::get,\n///     Router,\n/// };\n///\n/// async fn users_teams_show(params: RawPathParams) {\n///     for (key, value) in &params {\n///         println!(\"{key:?} = {value:?}\");\n///     }\n/// }\n///\n/// let app = Router::new().route(\"/users/{user_id}/team/{team_id}\", get(users_teams_show));\n/// # let _: Router = app;\n/// ```\n#[derive(Debug)]\npub struct RawPathParams(Vec<(Arc<str>, PercentDecodedStr)>);\n\nimpl<S> FromRequestParts<S> for RawPathParams\nwhere\n    S: Send + Sync,\n{\n    type Rejection = RawPathParamsRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        let params = match parts.extensions.get::<UrlParams>() {\n            Some(UrlParams::Params(params)) => params,\n            Some(UrlParams::InvalidUtf8InPathParam { key }) => {\n                return Err(InvalidUtf8InPathParam {\n                    key: Arc::clone(key),\n                }\n                .into());\n            }\n            None => {\n                return Err(MissingPathParams.into());\n            }\n        };\n\n        Ok(Self(params.clone()))\n    }\n}\n\nimpl RawPathParams {\n    /// Get an iterator over the path parameters.\n    #[must_use]\n    pub fn iter(&self) -> RawPathParamsIter<'_> {\n        self.into_iter()\n    }\n}\n\nimpl<'a> IntoIterator for &'a RawPathParams {\n    type Item = (&'a str, &'a str);\n    type IntoIter = RawPathParamsIter<'a>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        RawPathParamsIter(self.0.iter())\n    }\n}\n\n/// An iterator over raw path parameters.\n///\n/// Created with [`RawPathParams::iter`].\n#[derive(Debug)]\npub struct RawPathParamsIter<'a>(std::slice::Iter<'a, (Arc<str>, PercentDecodedStr)>);\n\nimpl<'a> Iterator for RawPathParamsIter<'a> {\n    type Item = (&'a str, &'a str);\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let (key, value) = self.0.next()?;\n        Some((&**key, value.as_str()))\n    }\n}\n\n/// Rejection used by [`RawPathParams`] if a parameter contained text that, once percent decoded,\n/// wasn't valid UTF-8.\n#[derive(Debug)]\npub struct InvalidUtf8InPathParam {\n    key: Arc<str>,\n}\n\nimpl InvalidUtf8InPathParam {\n    /// Get the response body text used for this rejection.\n    #[must_use]\n    pub fn body_text(&self) -> String {\n        self.to_string()\n    }\n\n    /// Get the status code used for this rejection.\n    #[must_use]\n    pub fn status(&self) -> StatusCode {\n        StatusCode::BAD_REQUEST\n    }\n}\n\nimpl fmt::Display for InvalidUtf8InPathParam {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"Invalid UTF-8 in `{}`\", self.key)\n    }\n}\n\nimpl std::error::Error for InvalidUtf8InPathParam {}\n\nimpl IntoResponse for InvalidUtf8InPathParam {\n    fn into_response(self) -> Response {\n        let body = self.body_text();\n        axum_core::__log_rejection!(\n            rejection_type = Self,\n            body_text = body,\n            status = self.status(),\n        );\n        (self.status(), body).into_response()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{routing::get, test_helpers::*, Router};\n    use serde::Deserialize;\n    use std::collections::HashMap;\n\n    #[crate::test]\n    async fn extracting_url_params() {\n        let app = Router::new().route(\n            \"/users/{id}\",\n            get(|Path(id): Path<i32>| async move {\n                assert_eq!(id, 42);\n            })\n            .post(|Path(params_map): Path<HashMap<String, i32>>| async move {\n                assert_eq!(params_map.get(\"id\").unwrap(), &1337);\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/users/42\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n\n        let res = client.post(\"/users/1337\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn extracting_url_params_multiple_times() {\n        let app = Router::new().route(\"/users/{id}\", get(|_: Path<i32>, _: Path<String>| async {}));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/users/42\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn percent_decoding() {\n        let app = Router::new().route(\n            \"/{key}\",\n            get(|Path(param): Path<String>| async move { param }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/one%20two\").await;\n\n        assert_eq!(res.text().await, \"one two\");\n    }\n\n    #[crate::test]\n    async fn supports_128_bit_numbers() {\n        let app = Router::new()\n            .route(\n                \"/i/{key}\",\n                get(|Path(param): Path<i128>| async move { param.to_string() }),\n            )\n            .route(\n                \"/u/{key}\",\n                get(|Path(param): Path<u128>| async move { param.to_string() }),\n            );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/i/123\").await;\n        assert_eq!(res.text().await, \"123\");\n\n        let res = client.get(\"/u/123\").await;\n        assert_eq!(res.text().await, \"123\");\n    }\n\n    #[crate::test]\n    async fn wildcard() {\n        let app = Router::new()\n            .route(\n                \"/foo/{*rest}\",\n                get(|Path(param): Path<String>| async move { param }),\n            )\n            .route(\n                \"/bar/{*rest}\",\n                get(|Path(params): Path<HashMap<String, String>>| async move {\n                    params.get(\"rest\").unwrap().clone()\n                }),\n            );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar/baz\").await;\n        assert_eq!(res.text().await, \"bar/baz\");\n\n        let res = client.get(\"/bar/baz/qux\").await;\n        assert_eq!(res.text().await, \"baz/qux\");\n    }\n\n    #[crate::test]\n    async fn captures_dont_match_empty_path() {\n        let app = Router::new().route(\"/{key}\", get(|| async {}));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n        let res = client.get(\"/foo\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn captures_match_empty_inner_segments() {\n        let app = Router::new().route(\n            \"/{key}/method\",\n            get(|Path(param): Path<String>| async move { param.clone() }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/abc/method\").await;\n        assert_eq!(res.text().await, \"abc\");\n\n        let res = client.get(\"//method\").await;\n        assert_eq!(res.text().await, \"\");\n    }\n\n    #[crate::test]\n    async fn captures_match_empty_inner_segments_near_end() {\n        let app = Router::new().route(\n            \"/method/{key}/\",\n            get(|Path(param): Path<String>| async move { param.clone() }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/method/abc\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n        let res = client.get(\"/method/abc/\").await;\n        assert_eq!(res.text().await, \"abc\");\n\n        let res = client.get(\"/method//\").await;\n        assert_eq!(res.text().await, \"\");\n    }\n\n    #[crate::test]\n    async fn captures_match_empty_trailing_segment() {\n        let app = Router::new().route(\n            \"/method/{key}\",\n            get(|Path(param): Path<String>| async move { param.clone() }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/method/abc/\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n        let res = client.get(\"/method/abc\").await;\n        assert_eq!(res.text().await, \"abc\");\n\n        let res = client.get(\"/method/\").await;\n        assert_eq!(res.text().await, \"\");\n\n        let res = client.get(\"/method\").await;\n        assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    }\n\n    #[crate::test]\n    async fn str_reference_deserialize() {\n        struct Param(String);\n        impl<'de> serde::Deserialize<'de> for Param {\n            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n            where\n                D: serde::Deserializer<'de>,\n            {\n                let s = <&str as serde::Deserialize>::deserialize(deserializer)?;\n                Ok(Self(s.to_owned()))\n            }\n        }\n\n        let app = Router::new().route(\n            \"/{key}\",\n            get(|param: Path<Param>| async move { param.0 .0 }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo\").await;\n        assert_eq!(res.text().await, \"foo\");\n\n        // percent decoding should also work\n        let res = client.get(\"/foo%20bar\").await;\n        assert_eq!(res.text().await, \"foo bar\");\n    }\n\n    #[crate::test]\n    async fn two_path_extractors() {\n        let app = Router::new().route(\"/{a}/{b}\", get(|_: Path<String>, _: Path<String>| async {}));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/a/b\").await;\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert_eq!(\n            res.text().await,\n            \"Wrong number of path arguments for `Path`. Expected 1 but got 2. \\\n            Note that multiple parameters must be extracted with a tuple `Path<(_, _)>` or a struct `Path<YourParams>`\",\n        );\n    }\n\n    #[crate::test]\n    async fn tuple_param_matches_exactly() {\n        #[allow(dead_code)]\n        #[derive(Deserialize)]\n        struct Tuple(String, String);\n\n        let app = Router::new()\n            .route(\n                \"/foo/{a}/{b}/{c}\",\n                get(|_: Path<(String, String)>| async {}),\n            )\n            .route(\"/bar/{a}/{b}/{c}\", get(|_: Path<Tuple>| async {}));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/a/b/c\").await;\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert_eq!(\n            res.text().await,\n            \"Wrong number of path arguments for `Path`. Expected 2 but got 3\",\n        );\n\n        let res = client.get(\"/bar/a/b/c\").await;\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert_eq!(\n            res.text().await,\n            \"Wrong number of path arguments for `Path`. Expected 2 but got 3\",\n        );\n    }\n\n    #[crate::test]\n    async fn deserialize_into_vec_of_tuples() {\n        let app = Router::new().route(\n            \"/{a}/{b}\",\n            get(|Path(params): Path<Vec<(String, String)>>| async move {\n                assert_eq!(\n                    params,\n                    vec![\n                        (\"a\".to_owned(), \"foo\".to_owned()),\n                        (\"b\".to_owned(), \"bar\".to_owned())\n                    ]\n                );\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/bar\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[crate::test]\n    async fn type_that_uses_deserialize_any() {\n        use time::Date;\n\n        #[derive(Deserialize)]\n        struct Params {\n            a: Date,\n            b: Date,\n            c: Date,\n        }\n\n        let app = Router::new()\n            .route(\n                \"/single/{a}\",\n                get(|Path(a): Path<Date>| async move { format!(\"single: {a}\") }),\n            )\n            .route(\n                \"/tuple/{a}/{b}/{c}\",\n                get(|Path((a, b, c)): Path<(Date, Date, Date)>| async move {\n                    format!(\"tuple: {a} {b} {c}\")\n                }),\n            )\n            .route(\n                \"/vec/{a}/{b}/{c}\",\n                get(|Path(vec): Path<Vec<Date>>| async move {\n                    let [a, b, c]: [Date; 3] = vec.try_into().unwrap();\n                    format!(\"vec: {a} {b} {c}\")\n                }),\n            )\n            .route(\n                \"/vec_pairs/{a}/{b}/{c}\",\n                get(|Path(vec): Path<Vec<(String, Date)>>| async move {\n                    let [(_, a), (_, b), (_, c)]: [(String, Date); 3] = vec.try_into().unwrap();\n                    format!(\"vec_pairs: {a} {b} {c}\")\n                }),\n            )\n            .route(\n                \"/map/{a}/{b}/{c}\",\n                get(|Path(mut map): Path<HashMap<String, Date>>| async move {\n                    let a = map.remove(\"a\").unwrap();\n                    let b = map.remove(\"b\").unwrap();\n                    let c = map.remove(\"c\").unwrap();\n                    format!(\"map: {a} {b} {c}\")\n                }),\n            )\n            .route(\n                \"/struct/{a}/{b}/{c}\",\n                get(|Path(params): Path<Params>| async move {\n                    format!(\"struct: {} {} {}\", params.a, params.b, params.c)\n                }),\n            );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/single/2023-01-01\").await;\n        assert_eq!(res.text().await, \"single: 2023-01-01\");\n\n        let res = client.get(\"/tuple/2023-01-01/2023-01-02/2023-01-03\").await;\n        assert_eq!(res.text().await, \"tuple: 2023-01-01 2023-01-02 2023-01-03\");\n\n        let res = client.get(\"/vec/2023-01-01/2023-01-02/2023-01-03\").await;\n        assert_eq!(res.text().await, \"vec: 2023-01-01 2023-01-02 2023-01-03\");\n\n        let res = client\n            .get(\"/vec_pairs/2023-01-01/2023-01-02/2023-01-03\")\n            .await;\n        assert_eq!(\n            res.text().await,\n            \"vec_pairs: 2023-01-01 2023-01-02 2023-01-03\",\n        );\n\n        let res = client.get(\"/map/2023-01-01/2023-01-02/2023-01-03\").await;\n        assert_eq!(res.text().await, \"map: 2023-01-01 2023-01-02 2023-01-03\");\n\n        let res = client.get(\"/struct/2023-01-01/2023-01-02/2023-01-03\").await;\n        assert_eq!(res.text().await, \"struct: 2023-01-01 2023-01-02 2023-01-03\");\n    }\n\n    #[crate::test]\n    async fn wrong_number_of_parameters_json() {\n        use serde_json::Value;\n\n        let app = Router::new()\n            .route(\"/one/{a}\", get(|_: Path<(Value, Value)>| async {}))\n            .route(\"/two/{a}/{b}\", get(|_: Path<Value>| async {}));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/one/1\").await;\n        assert!(res\n            .text()\n            .await\n            .starts_with(\"Wrong number of path arguments for `Path`. Expected 2 but got 1\"));\n\n        let res = client.get(\"/two/1/2\").await;\n        assert!(res\n            .text()\n            .await\n            .starts_with(\"Wrong number of path arguments for `Path`. Expected 1 but got 2\"));\n    }\n\n    #[crate::test]\n    async fn raw_path_params() {\n        let app = Router::new().route(\n            \"/{a}/{b}/{c}\",\n            get(|params: RawPathParams| async move {\n                params\n                    .into_iter()\n                    .map(|(key, value)| format!(\"{key}={value}\"))\n                    .collect::<Vec<_>>()\n                    .join(\" \")\n            }),\n        );\n\n        let client = TestClient::new(app);\n        let res = client.get(\"/foo/bar/baz\").await;\n        let body = res.text().await;\n        assert_eq!(body, \"a=foo b=bar c=baz\");\n    }\n\n    #[crate::test]\n    async fn deserialize_error_single_value() {\n        let app = Router::new().route(\n            \"/resources/{res}\",\n            get(|res: Path<uuid::Uuid>| async move {\n                let _res = res;\n            }),\n        );\n\n        let client = TestClient::new(app);\n        let response = client.get(\"/resources/123123-123-123123\").await;\n        let body = response.text().await;\n        assert_eq!(\n            body,\n            \"Invalid URL: Cannot parse `res` with value `123123-123-123123`: UUID parsing failed: invalid group count: expected 5, found 3\"\n        );\n    }\n\n    #[crate::test]\n    async fn deserialize_error_multi_value() {\n        let app = Router::new().route(\n            \"/resources/{res}/sub/{sub}\",\n            get(\n                |Path((res, sub)): Path<(uuid::Uuid, uuid::Uuid)>| async move {\n                    let _res = res;\n                    let _sub = sub;\n                },\n            ),\n        );\n\n        let client = TestClient::new(app);\n        let response = client.get(\"/resources/456456-123-456456/sub/123\").await;\n        let body = response.text().await;\n        assert_eq!(\n            body,\n            \"Invalid URL: Cannot parse `res` with value `456456-123-456456`: UUID parsing failed: invalid group count: expected 5, found 3\"\n        );\n    }\n\n    #[crate::test]\n    async fn regression_3038() {\n        #[derive(Deserialize)]\n        #[allow(dead_code)]\n        struct MoreChars {\n            first_two: [char; 2],\n            second_two: [char; 2],\n            crate_name: String,\n        }\n\n        let app = Router::new().route(\n            \"/{first_two}/{second_two}/{crate_name}\",\n            get(|Path(_): Path<MoreChars>| async move {}),\n        );\n\n        let client = TestClient::new(app);\n        let res = client.get(\"/te/st/_thing\").await;\n        let body = res.text().await;\n        assert_eq!(body, \"Invalid URL: array types are not supported\");\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/query.rs",
    "content": "use super::{rejection::*, FromRequestParts};\nuse http::{request::Parts, Uri};\nuse serde_core::de::DeserializeOwned;\n\n/// Extractor that deserializes query strings into some type.\n///\n/// `T` is expected to implement [`serde::Deserialize`].\n///\n/// # Examples\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::Query,\n///     routing::get,\n///     Router,\n/// };\n/// use serde::Deserialize;\n///\n/// #[derive(Deserialize)]\n/// struct Pagination {\n///     page: usize,\n///     per_page: usize,\n/// }\n///\n/// // This will parse query strings like `?page=2&per_page=30` into `Pagination`\n/// // structs.\n/// async fn list_things(pagination: Query<Pagination>) {\n///     let pagination: Pagination = pagination.0;\n///\n///     // ...\n/// }\n///\n/// let app = Router::new().route(\"/list_things\", get(list_things));\n/// # let _: Router = app;\n/// ```\n///\n/// If the query string cannot be parsed it will reject the request with a `400\n/// Bad Request` response.\n#[cfg_attr(docsrs, doc(cfg(feature = \"query\")))]\n#[derive(Debug, Clone, Copy, Default)]\npub struct Query<T>(pub T);\n\nimpl<T, S> FromRequestParts<S> for Query<T>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = QueryRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        Self::try_from_uri(&parts.uri)\n    }\n}\n\nimpl<T> Query<T>\nwhere\n    T: DeserializeOwned,\n{\n    /// Attempts to construct a [`Query`] from a reference to a [`Uri`].\n    ///\n    /// # Example\n    /// ```\n    /// use axum::extract::Query;\n    /// use http::Uri;\n    /// use serde::Deserialize;\n    ///\n    /// #[derive(Deserialize)]\n    /// struct ExampleParams {\n    ///     foo: String,\n    ///     bar: u32,\n    /// }\n    ///\n    /// let uri: Uri = \"http://example.com/path?foo=hello&bar=42\".parse().unwrap();\n    /// let result: Query<ExampleParams> = Query::try_from_uri(&uri).unwrap();\n    /// assert_eq!(result.foo, String::from(\"hello\"));\n    /// assert_eq!(result.bar, 42);\n    /// ```\n    pub fn try_from_uri(value: &Uri) -> Result<Self, QueryRejection> {\n        let query = value.query().unwrap_or_default();\n        let deserializer =\n            serde_html_form::Deserializer::new(form_urlencoded::parse(query.as_bytes()));\n        let params = serde_path_to_error::deserialize(deserializer)\n            .map_err(FailedToDeserializeQueryString::from_err)?;\n        Ok(Self(params))\n    }\n}\n\naxum_core::__impl_deref!(Query);\n\n#[cfg(test)]\nmod tests {\n    use crate::{routing::get, test_helpers::TestClient, Router};\n\n    use super::*;\n    use axum_core::{body::Body, extract::FromRequest};\n    use http::{Request, StatusCode};\n    use serde::Deserialize;\n    use std::fmt::Debug;\n\n    async fn check<T>(uri: impl AsRef<str>, value: T)\n    where\n        T: DeserializeOwned + PartialEq + Debug,\n    {\n        let req = Request::builder()\n            .uri(uri.as_ref())\n            .body(Body::empty())\n            .unwrap();\n        assert_eq!(Query::<T>::from_request(req, &()).await.unwrap().0, value);\n    }\n\n    #[crate::test]\n    async fn test_query() {\n        #[derive(Debug, PartialEq, Deserialize)]\n        struct Pagination {\n            size: Option<u64>,\n            page: Option<u64>,\n        }\n\n        check(\n            \"http://example.com/test\",\n            Pagination {\n                size: None,\n                page: None,\n            },\n        )\n        .await;\n\n        check(\n            \"http://example.com/test?size=10\",\n            Pagination {\n                size: Some(10),\n                page: None,\n            },\n        )\n        .await;\n\n        check(\n            \"http://example.com/test?size=10&page=20\",\n            Pagination {\n                size: Some(10),\n                page: Some(20),\n            },\n        )\n        .await;\n    }\n\n    #[crate::test]\n    async fn correct_rejection_status_code() {\n        #[derive(Deserialize)]\n        #[allow(dead_code)]\n        struct Params {\n            n: i32,\n        }\n\n        async fn handler(_: Query<Params>) {}\n\n        let app = Router::new().route(\"/\", get(handler));\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/?n=hi\").await;\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n        assert_eq!(\n            res.text().await,\n            \"Failed to deserialize query string: n: invalid digit found in string\"\n        );\n    }\n\n    #[test]\n    fn test_try_from_uri() {\n        #[derive(Deserialize)]\n        struct TestQueryParams {\n            foo: String,\n            bar: u32,\n        }\n        let uri: Uri = \"http://example.com/path?foo=hello&bar=42\".parse().unwrap();\n        let result: Query<TestQueryParams> = Query::try_from_uri(&uri).unwrap();\n        assert_eq!(result.foo, String::from(\"hello\"));\n        assert_eq!(result.bar, 42);\n    }\n\n    #[test]\n    fn test_try_from_uri_with_invalid_query() {\n        #[derive(Deserialize)]\n        struct TestQueryParams {\n            _foo: String,\n            _bar: u32,\n        }\n        let uri: Uri = \"http://example.com/path?foo=hello&bar=invalid\"\n            .parse()\n            .unwrap();\n        let result: Result<Query<TestQueryParams>, _> = Query::try_from_uri(&uri);\n\n        assert!(result.is_err());\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/raw_form.rs",
    "content": "use axum_core::extract::{FromRequest, Request};\nuse bytes::Bytes;\nuse http::Method;\n\nuse super::{\n    has_content_type,\n    rejection::{InvalidFormContentType, RawFormRejection},\n};\n\n/// Extractor that extracts raw form requests.\n///\n/// For `GET` requests it will extract the raw query. For other methods it extracts the raw\n/// `application/x-www-form-urlencoded` encoded request body.\n///\n/// # Example\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::RawForm,\n///     routing::get,\n///     Router\n/// };\n///\n/// async fn handler(RawForm(form): RawForm) {}\n///\n/// let app = Router::new().route(\"/\", get(handler));\n/// # let _: Router = app;\n/// ```\n#[derive(Debug)]\npub struct RawForm(pub Bytes);\n\nimpl<S> FromRequest<S> for RawForm\nwhere\n    S: Send + Sync,\n{\n    type Rejection = RawFormRejection;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        if req.method() == Method::GET {\n            if let Some(query) = req.uri().query() {\n                return Ok(Self(Bytes::copy_from_slice(query.as_bytes())));\n            }\n\n            Ok(Self(Bytes::new()))\n        } else {\n            if !has_content_type(req.headers(), &mime::APPLICATION_WWW_FORM_URLENCODED) {\n                return Err(InvalidFormContentType.into());\n            }\n\n            Ok(Self(Bytes::from_request(req, state).await?))\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use axum_core::body::Body;\n    use http::{header::CONTENT_TYPE, Request};\n\n    use super::{InvalidFormContentType, RawForm, RawFormRejection};\n\n    use crate::extract::FromRequest;\n\n    async fn check_query(uri: &str, value: &[u8]) {\n        let req = Request::builder().uri(uri).body(Body::empty()).unwrap();\n\n        assert_eq!(RawForm::from_request(req, &()).await.unwrap().0, value);\n    }\n\n    async fn check_body(body: &'static [u8]) {\n        let req = Request::post(\"http://example.com/test\")\n            .header(CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref())\n            .body(Body::from(body))\n            .unwrap();\n\n        assert_eq!(RawForm::from_request(req, &()).await.unwrap().0, body);\n    }\n\n    #[crate::test]\n    async fn test_from_query() {\n        check_query(\"http://example.com/test\", b\"\").await;\n\n        check_query(\"http://example.com/test?page=0&size=10\", b\"page=0&size=10\").await;\n    }\n\n    #[crate::test]\n    async fn test_from_body() {\n        check_body(b\"\").await;\n\n        check_body(b\"username=user&password=secure%20password\").await;\n    }\n\n    #[crate::test]\n    async fn test_incorrect_content_type() {\n        let req = Request::post(\"http://example.com/test\")\n            .body(Body::from(\"page=0&size=10\"))\n            .unwrap();\n\n        assert!(matches!(\n            RawForm::from_request(req, &()).await.unwrap_err(),\n            RawFormRejection::InvalidFormContentType(InvalidFormContentType)\n        ))\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/raw_query.rs",
    "content": "use super::FromRequestParts;\nuse http::request::Parts;\nuse std::convert::Infallible;\n\n/// Extractor that extracts the raw query string, without parsing it.\n///\n/// # Example\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract::RawQuery,\n///     routing::get,\n///     Router,\n/// };\n/// use futures_util::StreamExt;\n///\n/// async fn handler(RawQuery(query): RawQuery) {\n///     // ...\n/// }\n///\n/// let app = Router::new().route(\"/users\", get(handler));\n/// # let _: Router = app;\n/// ```\n#[derive(Debug)]\npub struct RawQuery(pub Option<String>);\n\nimpl<S> FromRequestParts<S> for RawQuery\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        let query = parts.uri.query().map(|query| query.to_owned());\n        Ok(Self(query))\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/rejection.rs",
    "content": "//! Rejection response types.\n\nuse axum_core::__composite_rejection as composite_rejection;\nuse axum_core::__define_rejection as define_rejection;\n\npub use crate::extract::path::{FailedToDeserializePathParams, InvalidUtf8InPathParam};\npub use axum_core::extract::rejection::*;\n\n#[cfg(feature = \"json\")]\ndefine_rejection! {\n    #[status = UNPROCESSABLE_ENTITY]\n    #[body = \"Failed to deserialize the JSON body into the target type\"]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json\")))]\n    /// Rejection type for [`Json`](super::Json).\n    ///\n    /// This rejection is used if the request body is syntactically valid JSON but couldn't be\n    /// deserialized into the target type.\n    pub struct JsonDataError(Error);\n}\n\n#[cfg(feature = \"json\")]\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Failed to parse the request body as JSON\"]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json\")))]\n    /// Rejection type for [`Json`](super::Json).\n    ///\n    /// This rejection is used if the request body didn't contain syntactically valid JSON.\n    pub struct JsonSyntaxError(Error);\n}\n\n#[cfg(feature = \"json\")]\ndefine_rejection! {\n    #[status = UNSUPPORTED_MEDIA_TYPE]\n    #[body = \"Expected request with `Content-Type: application/json`\"]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json\")))]\n    /// Rejection type for [`Json`](super::Json) used if the `Content-Type`\n    /// header is missing.\n    pub struct MissingJsonContentType;\n}\n\ndefine_rejection! {\n    #[status = INTERNAL_SERVER_ERROR]\n    #[body = \"Missing request extension\"]\n    /// Rejection type for [`Extension`](super::Extension) if an expected\n    /// request extension was not found.\n    pub struct MissingExtension(Error);\n}\n\ndefine_rejection! {\n    #[status = INTERNAL_SERVER_ERROR]\n    #[body = \"No paths parameters found for matched route\"]\n    /// Rejection type used if axum's internal representation of path parameters\n    /// is missing. This is commonly caused by extracting `Request<_>`. `Path`\n    /// must be extracted first.\n    pub struct MissingPathParams;\n}\n\ndefine_rejection! {\n    #[status = UNSUPPORTED_MEDIA_TYPE]\n    #[body = \"Form requests must have `Content-Type: application/x-www-form-urlencoded`\"]\n    /// Rejection type for [`Form`](super::Form) or [`RawForm`](super::RawForm)\n    /// used if the `Content-Type` header is missing\n    /// or its value is not `application/x-www-form-urlencoded`.\n    pub struct InvalidFormContentType;\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Failed to deserialize form\"]\n    /// Rejection type used if the [`Form`](super::Form) extractor is unable to\n    /// deserialize the form into the target type.\n    pub struct FailedToDeserializeForm(Error);\n}\n\ndefine_rejection! {\n    #[status = UNPROCESSABLE_ENTITY]\n    #[body = \"Failed to deserialize form body\"]\n    /// Rejection type used if the [`Form`](super::Form) extractor is unable to\n    /// deserialize the form body into the target type.\n    pub struct FailedToDeserializeFormBody(Error);\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Failed to deserialize query string\"]\n    /// Rejection type used if the [`Query`](super::Query) extractor is unable to\n    /// deserialize the query string into the target type.\n    pub struct FailedToDeserializeQueryString(Error);\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Query`](super::Query).\n    ///\n    /// Contains one variant for each way the [`Query`](super::Query) extractor\n    /// can fail.\n    pub enum QueryRejection {\n        FailedToDeserializeQueryString,\n    }\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Form`](super::Form).\n    ///\n    /// Contains one variant for each way the [`Form`](super::Form) extractor\n    /// can fail.\n    pub enum FormRejection {\n        InvalidFormContentType,\n        FailedToDeserializeForm,\n        FailedToDeserializeFormBody,\n        BytesRejection,\n    }\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`RawForm`](super::RawForm).\n    ///\n    /// Contains one variant for each way the [`RawForm`](super::RawForm) extractor\n    /// can fail.\n    pub enum RawFormRejection {\n        InvalidFormContentType,\n        BytesRejection,\n    }\n}\n\n#[cfg(feature = \"json\")]\ncomposite_rejection! {\n    /// Rejection used for [`Json`](super::Json).\n    ///\n    /// Contains one variant for each way the [`Json`](super::Json) extractor\n    /// can fail.\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json\")))]\n    pub enum JsonRejection {\n        JsonDataError,\n        JsonSyntaxError,\n        MissingJsonContentType,\n        BytesRejection,\n    }\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Extension`](super::Extension).\n    ///\n    /// Contains one variant for each way the [`Extension`](super::Extension) extractor\n    /// can fail.\n    pub enum ExtensionRejection {\n        MissingExtension,\n    }\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Path`](super::Path).\n    ///\n    /// Contains one variant for each way the [`Path`](super::Path) extractor\n    /// can fail.\n    pub enum PathRejection {\n        FailedToDeserializePathParams,\n        MissingPathParams,\n    }\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`RawPathParams`](super::RawPathParams).\n    ///\n    /// Contains one variant for each way the [`RawPathParams`](super::RawPathParams) extractor\n    /// can fail.\n    pub enum RawPathParamsRejection {\n        InvalidUtf8InPathParam,\n        MissingPathParams,\n    }\n}\n\n#[cfg(feature = \"matched-path\")]\ndefine_rejection! {\n    #[status = INTERNAL_SERVER_ERROR]\n    #[body = \"No matched path found\"]\n    /// Rejection if no matched path could be found.\n    ///\n    /// See [`MatchedPath`](super::MatchedPath) for more details.\n    #[cfg_attr(docsrs, doc(cfg(feature = \"matched-path\")))]\n    pub struct MatchedPathMissing;\n}\n\n#[cfg(feature = \"matched-path\")]\ncomposite_rejection! {\n    /// Rejection used for [`MatchedPath`](super::MatchedPath).\n    #[cfg_attr(docsrs, doc(cfg(feature = \"matched-path\")))]\n    pub enum MatchedPathRejection {\n        MatchedPathMissing,\n    }\n}\n\ndefine_rejection! {\n    #[status = INTERNAL_SERVER_ERROR]\n    #[body = \"The matched route is not nested\"]\n    /// Rejection type for [`NestedPath`](super::NestedPath).\n    ///\n    /// This rejection is used if the matched route wasn't nested.\n    pub struct NestedPathRejection;\n}\n"
  },
  {
    "path": "axum/src/extract/state.rs",
    "content": "use axum_core::extract::{FromRef, FromRequestParts};\nuse http::request::Parts;\nuse std::{\n    convert::Infallible,\n    ops::{Deref, DerefMut},\n};\n\n/// Extractor for state.\n///\n/// See [\"Accessing state in middleware\"][state-from-middleware] for how to\n/// access state in middleware.\n///\n/// State is global and used in every request a router with state receives.\n/// For accessing data derived from requests, such as authorization data, see [`Extension`].\n///\n/// [state-from-middleware]: crate::middleware#accessing-state-in-middleware\n/// [`Extension`]: crate::Extension\n///\n/// # With `Router`\n///\n/// ```\n/// use axum::{Router, routing::get, extract::State};\n///\n/// // the application state\n/// //\n/// // here you can put configuration, database connection pools, or whatever\n/// // state you need\n/// #[derive(Clone)]\n/// struct AppState {}\n///\n/// let state = AppState {};\n///\n/// // create a `Router` that holds our state\n/// let app = Router::new()\n///     .route(\"/\", get(handler))\n///     // provide the state so the router can access it\n///     .with_state(state);\n///\n/// async fn handler(\n///     // access the state via the `State` extractor\n///     // extracting a state of the wrong type results in a compile error\n///     State(state): State<AppState>,\n/// ) {\n///     // use `state`...\n/// }\n/// # let _: axum::Router = app;\n/// ```\n///\n/// Note that `State` is an extractor, so be sure to put it before any body\n/// extractors, see [\"the order of extractors\"][order-of-extractors].\n///\n/// [order-of-extractors]: crate::extract#the-order-of-extractors\n///\n/// ## Combining stateful routers\n///\n/// Multiple [`Router`]s can be combined with [`Router::nest`] or [`Router::merge`]\n/// When combining [`Router`]s with one of these methods, the [`Router`]s must have\n/// the same state type. Generally, this can be inferred automatically:\n///\n/// ```\n/// use axum::{Router, routing::get, extract::State};\n///\n/// #[derive(Clone)]\n/// struct AppState {}\n///\n/// let state = AppState {};\n///\n/// // create a `Router` that will be nested within another\n/// let api = Router::new()\n///     .route(\"/posts\", get(posts_handler));\n///\n/// let app = Router::new()\n///     .nest(\"/api\", api)\n///     .with_state(state);\n///\n/// async fn posts_handler(State(state): State<AppState>) {\n///     // use `state`...\n/// }\n/// # let _: axum::Router = app;\n/// ```\n///\n/// However, if you are composing [`Router`]s that are defined in separate scopes,\n/// you may need to annotate the [`State`] type explicitly:\n///\n/// ```\n/// use axum::{Router, routing::get, extract::State};\n///\n/// #[derive(Clone)]\n/// struct AppState {}\n///\n/// fn make_app() -> Router {\n///     let state = AppState {};\n///\n///     Router::new()\n///         .nest(\"/api\", make_api())\n///         .with_state(state) // the outer Router's state is inferred\n/// }\n///\n/// // the inner Router must specify its state type to compose with the\n/// // outer router\n/// fn make_api() -> Router<AppState> {\n///     Router::new()\n///         .route(\"/posts\", get(posts_handler))\n/// }\n///\n/// async fn posts_handler(State(state): State<AppState>) {\n///     // use `state`...\n/// }\n/// # let _: axum::Router = make_app();\n/// ```\n///\n/// In short, a [`Router`]'s generic state type defaults to `()`\n/// (no state) unless [`Router::with_state`] is called or the value\n/// of the generic type is given explicitly.\n///\n/// [`Router`]: crate::Router\n/// [`Router::merge`]: crate::Router::merge\n/// [`Router::nest`]: crate::Router::nest\n/// [`Router::with_state`]: crate::Router::with_state\n///\n/// # With `MethodRouter`\n///\n/// ```\n/// use axum::{routing::get, extract::State};\n///\n/// #[derive(Clone)]\n/// struct AppState {}\n///\n/// let state = AppState {};\n///\n/// let method_router_with_state = get(handler)\n///     // provide the state so the handler can access it\n///     .with_state(state);\n/// # let _: axum::routing::MethodRouter = method_router_with_state;\n///\n/// async fn handler(State(state): State<AppState>) {\n///     // use `state`...\n/// }\n/// ```\n///\n/// # With `Handler`\n///\n/// ```\n/// use axum::{routing::get, handler::Handler, extract::State};\n///\n/// #[derive(Clone)]\n/// struct AppState {}\n///\n/// let state = AppState {};\n///\n/// async fn handler(State(state): State<AppState>) {\n///     // use `state`...\n/// }\n///\n/// // provide the state so the handler can access it\n/// let handler_with_state = handler.with_state(state);\n///\n/// # async {\n/// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n/// axum::serve(listener, handler_with_state.into_make_service()).await;\n/// # };\n/// ```\n///\n/// # Substates\n///\n/// [`State`] only allows a single state type but you can use [`FromRef`] to extract \"substates\":\n///\n/// ```\n/// use axum::{Router, routing::get, extract::{State, FromRef}};\n///\n/// // the application state\n/// #[derive(Clone)]\n/// struct AppState {\n///     // that holds some api specific state\n///     api_state: ApiState,\n/// }\n///\n/// // the api specific state\n/// #[derive(Clone)]\n/// struct ApiState {}\n///\n/// // support converting an `AppState` in an `ApiState`\n/// impl FromRef<AppState> for ApiState {\n///     fn from_ref(app_state: &AppState) -> ApiState {\n///         app_state.api_state.clone()\n///     }\n/// }\n///\n/// let state = AppState {\n///     api_state: ApiState {},\n/// };\n///\n/// let app = Router::new()\n///     .route(\"/\", get(handler))\n///     .route(\"/api/users\", get(api_users))\n///     .with_state(state);\n///\n/// async fn api_users(\n///     // access the api specific state\n///     State(api_state): State<ApiState>,\n/// ) {\n/// }\n///\n/// async fn handler(\n///     // we can still access to top level state\n///     State(state): State<AppState>,\n/// ) {\n/// }\n/// # let _: axum::Router = app;\n/// ```\n///\n/// For convenience `FromRef` can also be derived using `#[derive(FromRef)]`.\n///\n/// # For library authors\n///\n/// If you're writing a library that has an extractor that needs state, this is the recommended way\n/// to do it:\n///\n/// ```rust\n/// use axum_core::extract::{FromRequestParts, FromRef};\n/// use http::request::Parts;\n/// use std::convert::Infallible;\n///\n/// // the extractor your library provides\n/// struct MyLibraryExtractor;\n///\n/// impl<S> FromRequestParts<S> for MyLibraryExtractor\n/// where\n///     // keep `S` generic but require that it can produce a `MyLibraryState`\n///     // this means users will have to implement `FromRef<UserState> for MyLibraryState`\n///     MyLibraryState: FromRef<S>,\n///     S: Send + Sync,\n/// {\n///     type Rejection = Infallible;\n///\n///     async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n///         // get a `MyLibraryState` from a reference to the state\n///         let state = MyLibraryState::from_ref(state);\n///\n///         // ...\n///         # todo!()\n///     }\n/// }\n///\n/// // the state your library needs\n/// struct MyLibraryState {\n///     // ...\n/// }\n/// ```\n///\n/// # Shared mutable state\n///\n/// [As state is global within a `Router`][global] you can't directly get a mutable reference to\n/// the state.\n///\n/// The most basic solution is to use an `Arc<Mutex<_>>`. Which kind of mutex you need depends on\n/// your use case. See [the tokio docs] for more details.\n///\n/// Note that holding a locked `std::sync::Mutex` across `.await` points will result in `!Send`\n/// futures which are incompatible with axum. If you need to hold a mutex across `.await` points,\n/// consider using a `tokio::sync::Mutex` instead.\n///\n/// ## Example\n///\n/// ```\n/// use axum::{Router, routing::get, extract::State};\n/// use std::sync::{Arc, Mutex};\n///\n/// #[derive(Clone)]\n/// struct AppState {\n///     data: Arc<Mutex<String>>,\n/// }\n///\n/// async fn handler(State(state): State<AppState>) {\n///     {\n///         let mut data = state.data.lock().expect(\"mutex was poisoned\");\n///         *data = \"updated foo\".to_owned();\n///     }\n///\n///     // ...\n/// }\n///\n/// let state = AppState {\n///     data: Arc::new(Mutex::new(\"foo\".to_owned())),\n/// };\n///\n/// let app = Router::new()\n///     .route(\"/\", get(handler))\n///     .with_state(state);\n/// # let _: Router = app;\n/// ```\n///\n/// [global]: crate::Router::with_state\n/// [the tokio docs]: https://docs.rs/tokio/1.25.0/tokio/sync/struct.Mutex.html#which-kind-of-mutex-should-you-use\n#[derive(Debug, Default, Clone, Copy)]\npub struct State<S>(pub S);\n\nimpl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>\nwhere\n    InnerState: FromRef<OuterState>,\n    OuterState: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(\n        _parts: &mut Parts,\n        state: &OuterState,\n    ) -> Result<Self, Self::Rejection> {\n        let inner_state = InnerState::from_ref(state);\n        Ok(Self(inner_state))\n    }\n}\n\nimpl<S> Deref for State<S> {\n    type Target = S;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<S> DerefMut for State<S> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n"
  },
  {
    "path": "axum/src/extract/ws.rs",
    "content": "//! Handle WebSocket connections.\n//!\n//! # Example\n//!\n//! ```\n//! use axum::{\n//!     extract::ws::{WebSocketUpgrade, WebSocket},\n//!     routing::any,\n//!     response::{IntoResponse, Response},\n//!     Router,\n//! };\n//!\n//! let app = Router::new().route(\"/ws\", any(handler));\n//!\n//! async fn handler(ws: WebSocketUpgrade) -> Response {\n//!     ws.on_upgrade(handle_socket)\n//! }\n//!\n//! async fn handle_socket(mut socket: WebSocket) {\n//!     while let Some(msg) = socket.recv().await {\n//!         let msg = if let Ok(msg) = msg {\n//!             msg\n//!         } else {\n//!             // client disconnected\n//!             return;\n//!         };\n//!\n//!         if socket.send(msg).await.is_err() {\n//!             // client disconnected\n//!             return;\n//!         }\n//!     }\n//! }\n//! # let _: Router = app;\n//! ```\n//!\n//! # Passing data and/or state to an `on_upgrade` callback\n//!\n//! ```\n//! use axum::{\n//!     extract::{ws::{WebSocketUpgrade, WebSocket}, State},\n//!     response::Response,\n//!     routing::any,\n//!     Router,\n//! };\n//!\n//! #[derive(Clone)]\n//! struct AppState {\n//!     // ...\n//! }\n//!\n//! async fn handler(ws: WebSocketUpgrade, State(state): State<AppState>) -> Response {\n//!     ws.on_upgrade(|socket| handle_socket(socket, state))\n//! }\n//!\n//! async fn handle_socket(socket: WebSocket, state: AppState) {\n//!     // ...\n//! }\n//!\n//! let app = Router::new()\n//!     .route(\"/ws\", any(handler))\n//!     .with_state(AppState { /* ... */ });\n//! # let _: Router = app;\n//! ```\n//!\n//! # Read and write concurrently\n//!\n//! If you need to read and write concurrently from a [`WebSocket`] you can use\n//! [`StreamExt::split`]:\n//!\n//! ```rust,no_run\n//! use axum::{Error, extract::ws::{WebSocket, Message}};\n//! use futures_util::{sink::SinkExt, stream::{StreamExt, SplitSink, SplitStream}};\n//!\n//! async fn handle_socket(mut socket: WebSocket) {\n//!     let (mut sender, mut receiver) = socket.split();\n//!\n//!     tokio::spawn(write(sender));\n//!     tokio::spawn(read(receiver));\n//! }\n//!\n//! async fn read(receiver: SplitStream<WebSocket>) {\n//!     // ...\n//! }\n//!\n//! async fn write(sender: SplitSink<WebSocket, Message>) {\n//!     // ...\n//! }\n//! ```\n//!\n//! [`StreamExt::split`]: https://docs.rs/futures/0.3.17/futures/stream/trait.StreamExt.html#method.split\n\nuse self::rejection::*;\nuse super::FromRequestParts;\nuse crate::{body::Bytes, response::Response, Error};\nuse axum_core::body::Body;\nuse futures_core::{FusedStream, Stream};\nuse futures_sink::Sink;\nuse futures_util::{sink::SinkExt, stream::StreamExt};\nuse http::{\n    header::{self, HeaderMap, HeaderName, HeaderValue},\n    request::Parts,\n    Method, StatusCode, Version,\n};\nuse hyper_util::rt::TokioIo;\nuse sha1::{Digest, Sha1};\nuse std::{\n    borrow::Cow,\n    collections::BTreeSet,\n    future::Future,\n    pin::Pin,\n    str,\n    task::{ready, Context, Poll},\n};\nuse tokio_tungstenite::{\n    tungstenite::{\n        self as ts,\n        protocol::{self, WebSocketConfig},\n    },\n    WebSocketStream,\n};\n\n/// Extractor for establishing WebSocket connections.\n///\n/// For HTTP/1.1 requests, this extractor requires the request method to be `GET`;\n/// in later versions, `CONNECT` is used instead.\n/// To support both, it should be used with [`any`](crate::routing::any).\n///\n/// See the [module docs](self) for an example.\n///\n/// [`MethodFilter`]: crate::routing::MethodFilter\n#[cfg_attr(docsrs, doc(cfg(feature = \"ws\")))]\n#[must_use]\npub struct WebSocketUpgrade<F = DefaultOnFailedUpgrade> {\n    config: WebSocketConfig,\n    /// The chosen protocol sent in the `Sec-WebSocket-Protocol` header of the response.\n    protocol: Option<HeaderValue>,\n    /// `None` if HTTP/2+ WebSockets are used.\n    sec_websocket_key: Option<HeaderValue>,\n    on_upgrade: hyper::upgrade::OnUpgrade,\n    on_failed_upgrade: F,\n    sec_websocket_protocol: BTreeSet<HeaderValue>,\n}\n\nimpl<F> std::fmt::Debug for WebSocketUpgrade<F> {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.debug_struct(\"WebSocketUpgrade\")\n            .field(\"config\", &self.config)\n            .field(\"protocol\", &self.protocol)\n            .field(\"sec_websocket_key\", &self.sec_websocket_key)\n            .field(\"sec_websocket_protocol\", &self.sec_websocket_protocol)\n            .finish_non_exhaustive()\n    }\n}\n\nimpl<F> WebSocketUpgrade<F> {\n    /// Read buffer capacity. The default value is 128KiB\n    pub fn read_buffer_size(mut self, size: usize) -> Self {\n        self.config.read_buffer_size = size;\n        self\n    }\n\n    /// The target minimum size of the write buffer to reach before writing the data\n    /// to the underlying stream.\n    ///\n    /// The default value is 128 KiB.\n    ///\n    /// If set to `0` each message will be eagerly written to the underlying stream.\n    /// It is often more optimal to allow them to buffer a little, hence the default value.\n    ///\n    /// Note: [`flush`](SinkExt::flush) will always fully write the buffer regardless.\n    pub fn write_buffer_size(mut self, size: usize) -> Self {\n        self.config.write_buffer_size = size;\n        self\n    }\n\n    /// The max size of the write buffer in bytes. Setting this can provide backpressure\n    /// in the case the write buffer is filling up due to write errors.\n    ///\n    /// The default value is unlimited.\n    ///\n    /// Note: The write buffer only builds up past [`write_buffer_size`](Self::write_buffer_size)\n    /// when writes to the underlying stream are failing. So the **write buffer can not\n    /// fill up if you are not observing write errors even if not flushing**.\n    ///\n    /// Note: Should always be at least [`write_buffer_size + 1 message`](Self::write_buffer_size)\n    /// and probably a little more depending on error handling strategy.\n    pub fn max_write_buffer_size(mut self, max: usize) -> Self {\n        self.config.max_write_buffer_size = max;\n        self\n    }\n\n    /// Set the maximum message size (defaults to 64 megabytes)\n    pub fn max_message_size(mut self, max: usize) -> Self {\n        self.config.max_message_size = Some(max);\n        self\n    }\n\n    /// Set the maximum frame size (defaults to 16 megabytes)\n    pub fn max_frame_size(mut self, max: usize) -> Self {\n        self.config.max_frame_size = Some(max);\n        self\n    }\n\n    /// Allow server to accept unmasked frames (defaults to false)\n    pub fn accept_unmasked_frames(mut self, accept: bool) -> Self {\n        self.config.accept_unmasked_frames = accept;\n        self\n    }\n\n    /// Set the known protocols.\n    ///\n    /// If the protocol name specified by `Sec-WebSocket-Protocol` header\n    /// to match any of them, the upgrade response will include `Sec-WebSocket-Protocol` header and\n    /// return the protocol name.\n    ///\n    /// The protocols should be listed in decreasing order of preference: if the client offers\n    /// multiple protocols that the server could support, the server will pick the first one in\n    /// this list.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::ws::{WebSocketUpgrade, WebSocket},\n    ///     routing::any,\n    ///     response::{IntoResponse, Response},\n    ///     Router,\n    /// };\n    ///\n    /// let app = Router::new().route(\"/ws\", any(handler));\n    ///\n    /// async fn handler(ws: WebSocketUpgrade) -> Response {\n    ///     ws.protocols([\"graphql-ws\", \"graphql-transport-ws\"])\n    ///         .on_upgrade(|socket| async {\n    ///             // ...\n    ///         })\n    /// }\n    /// # let _: Router = app;\n    /// ```\n    pub fn protocols<I>(mut self, protocols: I) -> Self\n    where\n        I: IntoIterator,\n        I::Item: Into<Cow<'static, str>>,\n    {\n        self.protocol = protocols\n            .into_iter()\n            .map(Into::into)\n            .find(|proto| {\n                // FIXME: When https://github.com/hyperium/http/pull/814\n                //        is merged + released, we can look use\n                //        `contains(proto.as_bytes())` without converting\n                //        to `HeaderValue` first.\n                let Ok(proto) = HeaderValue::from_str(proto) else {\n                    return false;\n                };\n                self.sec_websocket_protocol.contains(&proto)\n            })\n            .map(|protocol| match protocol {\n                Cow::Owned(s) => HeaderValue::from_str(&s).unwrap(),\n                Cow::Borrowed(s) => HeaderValue::from_static(s),\n            });\n\n        self\n    }\n\n    /// Return the WebSocket subprotocols requested by the client.\n    ///\n    /// # Examples\n    ///\n    /// If the client sends the following HTTP header in the WebSocket upgrade request:\n    ///\n    /// ```txt\n    /// Sec-WebSocket-Protocol: soap, wamp\n    /// ```\n    ///\n    /// this method returns an iterator yielding `\"soap\"` and `\"wamp\"`.\n    pub fn requested_protocols(&self) -> impl Iterator<Item = &HeaderValue> {\n        self.sec_websocket_protocol.iter()\n    }\n\n    /// Set the chosen WebSocket subprotocol.\n    ///\n    /// Another method, [`protocols()`][Self::protocols], also sets the chosen WebSocket\n    /// subprotocol. If both methods are called, only the latter call takes effect.\n    ///\n    /// # Notes\n    ///\n    /// - The chosen protocol is echoed back in the WebSocket upgrade\n    ///   response as required by RFC 6455. Some browsers may reject a\n    ///   value that was not present in the client's request.\n    pub fn set_selected_protocol(&mut self, protocol: HeaderValue) {\n        self.protocol = Some(protocol);\n    }\n\n    /// Return the selected WebSocket subprotocol, if one has been chosen.\n    ///\n    /// If [`protocols()`][Self::protocols] selects a matching protocol, or\n    /// [`set_selected_protocol()`][Self::set_selected_protocol] has been called, the return\n    /// value will be `Some` containing the selected protocol. Otherwise, it will be `None`.\n    pub fn selected_protocol(&self) -> Option<&HeaderValue> {\n        self.protocol.as_ref()\n    }\n\n    /// Provide a callback to call if upgrading the connection fails.\n    ///\n    /// The connection upgrade is performed in a background task. If that fails this callback\n    /// will be called.\n    ///\n    /// By default any errors will be silently ignored.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::{WebSocketUpgrade},\n    ///     response::Response,\n    /// };\n    ///\n    /// async fn handler(ws: WebSocketUpgrade) -> Response {\n    ///     ws.on_failed_upgrade(|error| {\n    ///         report_error(error);\n    ///     })\n    ///     .on_upgrade(|socket| async { /* ... */ })\n    /// }\n    /// #\n    /// # fn report_error(_: axum::Error) {}\n    /// ```\n    pub fn on_failed_upgrade<C>(self, callback: C) -> WebSocketUpgrade<C>\n    where\n        C: OnFailedUpgrade,\n    {\n        WebSocketUpgrade {\n            config: self.config,\n            protocol: self.protocol,\n            sec_websocket_key: self.sec_websocket_key,\n            on_upgrade: self.on_upgrade,\n            on_failed_upgrade: callback,\n            sec_websocket_protocol: self.sec_websocket_protocol,\n        }\n    }\n\n    /// Finalize upgrading the connection and call the provided callback with\n    /// the stream.\n    #[must_use = \"to set up the WebSocket connection, this response must be returned\"]\n    pub fn on_upgrade<C, Fut>(self, callback: C) -> Response\n    where\n        C: FnOnce(WebSocket) -> Fut + Send + 'static,\n        Fut: Future<Output = ()> + Send + 'static,\n        F: OnFailedUpgrade,\n    {\n        let on_upgrade = self.on_upgrade;\n        let config = self.config;\n        let on_failed_upgrade = self.on_failed_upgrade;\n\n        let protocol = self.protocol.clone();\n\n        tokio::spawn(async move {\n            let upgraded = match on_upgrade.await {\n                Ok(upgraded) => upgraded,\n                Err(err) => {\n                    on_failed_upgrade.call(Error::new(err));\n                    return;\n                }\n            };\n            let upgraded = TokioIo::new(upgraded);\n\n            let socket =\n                WebSocketStream::from_raw_socket(upgraded, protocol::Role::Server, Some(config))\n                    .await;\n            let socket = WebSocket {\n                inner: socket,\n                protocol,\n            };\n            callback(socket).await;\n        });\n\n        let mut response = if let Some(sec_websocket_key) = &self.sec_websocket_key {\n            // If `sec_websocket_key` was `Some`, we are using HTTP/1.1.\n\n            #[allow(clippy::declare_interior_mutable_const)]\n            const UPGRADE: HeaderValue = HeaderValue::from_static(\"upgrade\");\n            #[allow(clippy::declare_interior_mutable_const)]\n            const WEBSOCKET: HeaderValue = HeaderValue::from_static(\"websocket\");\n\n            Response::builder()\n                .status(StatusCode::SWITCHING_PROTOCOLS)\n                .header(header::CONNECTION, UPGRADE)\n                .header(header::UPGRADE, WEBSOCKET)\n                .header(\n                    header::SEC_WEBSOCKET_ACCEPT,\n                    sign(sec_websocket_key.as_bytes()),\n                )\n                .body(Body::empty())\n                .unwrap()\n        } else {\n            // Otherwise, we are HTTP/2+. As established in RFC 9113 section 8.5, we just respond\n            // with a 2XX with an empty body:\n            // <https://datatracker.ietf.org/doc/html/rfc9113#name-the-connect-method>.\n            Response::new(Body::empty())\n        };\n\n        if let Some(protocol) = self.protocol {\n            response\n                .headers_mut()\n                .insert(header::SEC_WEBSOCKET_PROTOCOL, protocol);\n        }\n\n        response\n    }\n}\n\n/// What to do when a connection upgrade fails.\n///\n/// See [`WebSocketUpgrade::on_failed_upgrade`] for more details.\npub trait OnFailedUpgrade: Send + 'static {\n    /// Call the callback.\n    fn call(self, error: Error);\n}\n\nimpl<F> OnFailedUpgrade for F\nwhere\n    F: FnOnce(Error) + Send + 'static,\n{\n    fn call(self, error: Error) {\n        self(error)\n    }\n}\n\n/// The default `OnFailedUpgrade` used by `WebSocketUpgrade`.\n///\n/// It simply ignores the error.\n#[non_exhaustive]\n#[derive(Debug)]\npub struct DefaultOnFailedUpgrade;\n\nimpl OnFailedUpgrade for DefaultOnFailedUpgrade {\n    #[inline]\n    fn call(self, _error: Error) {}\n}\n\nimpl<S> FromRequestParts<S> for WebSocketUpgrade<DefaultOnFailedUpgrade>\nwhere\n    S: Send + Sync,\n{\n    type Rejection = WebSocketUpgradeRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        let sec_websocket_key = if parts.version <= Version::HTTP_11 {\n            if parts.method != Method::GET {\n                return Err(MethodNotGet.into());\n            }\n\n            if !header_contains(&parts.headers, &header::CONNECTION, \"upgrade\") {\n                return Err(InvalidConnectionHeader.into());\n            }\n\n            if !header_eq(&parts.headers, &header::UPGRADE, \"websocket\") {\n                return Err(InvalidUpgradeHeader.into());\n            }\n\n            Some(\n                parts\n                    .headers\n                    .get(header::SEC_WEBSOCKET_KEY)\n                    .ok_or(WebSocketKeyHeaderMissing)?\n                    .clone(),\n            )\n        } else {\n            if parts.method != Method::CONNECT {\n                return Err(MethodNotConnect.into());\n            }\n\n            // if this feature flag is disabled, we won’t be receiving an HTTP/2 request to begin\n            // with.\n            #[cfg(feature = \"http2\")]\n            if parts\n                .extensions\n                .get::<hyper::ext::Protocol>()\n                .map_or(true, |p| p.as_str() != \"websocket\")\n            {\n                return Err(InvalidProtocolPseudoheader.into());\n            }\n\n            None\n        };\n\n        if !header_eq(&parts.headers, &header::SEC_WEBSOCKET_VERSION, \"13\") {\n            return Err(InvalidWebSocketVersionHeader.into());\n        }\n\n        let on_upgrade = parts\n            .extensions\n            .remove::<hyper::upgrade::OnUpgrade>()\n            .ok_or(ConnectionNotUpgradable)?;\n\n        let sec_websocket_protocol = parts\n            .headers\n            .get_all(header::SEC_WEBSOCKET_PROTOCOL)\n            .iter()\n            .flat_map(|val| val.as_bytes().split(|&b| b == b','))\n            .map(|proto| {\n                HeaderValue::from_bytes(proto.trim_ascii())\n                    .expect(\"substring of HeaderValue is valid HeaderValue\")\n            })\n            .collect();\n\n        Ok(Self {\n            config: Default::default(),\n            protocol: None,\n            sec_websocket_key,\n            on_upgrade,\n            sec_websocket_protocol,\n            on_failed_upgrade: DefaultOnFailedUpgrade,\n        })\n    }\n}\n\nfn header_eq(headers: &HeaderMap, key: &HeaderName, value: &'static str) -> bool {\n    if let Some(header) = headers.get(key) {\n        header.as_bytes().eq_ignore_ascii_case(value.as_bytes())\n    } else {\n        false\n    }\n}\n\nfn header_contains(headers: &HeaderMap, key: &HeaderName, value: &'static str) -> bool {\n    let Some(header) = headers.get(key) else {\n        return false;\n    };\n\n    if let Ok(header) = std::str::from_utf8(header.as_bytes()) {\n        header.to_ascii_lowercase().contains(value)\n    } else {\n        false\n    }\n}\n\n/// A stream of WebSocket messages.\n///\n/// See [the module level documentation](self) for more details.\n#[derive(Debug)]\npub struct WebSocket {\n    inner: WebSocketStream<TokioIo<hyper::upgrade::Upgraded>>,\n    protocol: Option<HeaderValue>,\n}\n\nimpl WebSocket {\n    /// Receive another message.\n    ///\n    /// Returns `None` if the stream has closed.\n    pub async fn recv(&mut self) -> Option<Result<Message, Error>> {\n        self.next().await\n    }\n\n    /// Send a message.\n    pub async fn send(&mut self, msg: Message) -> Result<(), Error> {\n        self.inner\n            .send(msg.into_tungstenite())\n            .await\n            .map_err(Error::new)\n    }\n\n    /// Return the selected WebSocket subprotocol, if one has been chosen.\n    pub fn protocol(&self) -> Option<&HeaderValue> {\n        self.protocol.as_ref()\n    }\n}\n\nimpl FusedStream for WebSocket {\n    /// Returns true if the websocket has been terminated.\n    fn is_terminated(&self) -> bool {\n        self.inner.is_terminated()\n    }\n}\n\nimpl Stream for WebSocket {\n    type Item = Result<Message, Error>;\n\n    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {\n        loop {\n            match ready!(self.inner.poll_next_unpin(cx)) {\n                Some(Ok(msg)) => {\n                    if let Some(msg) = Message::from_tungstenite(msg) {\n                        return Poll::Ready(Some(Ok(msg)));\n                    }\n                }\n                Some(Err(err)) => return Poll::Ready(Some(Err(Error::new(err)))),\n                None => return Poll::Ready(None),\n            }\n        }\n    }\n}\n\nimpl Sink<Message> for WebSocket {\n    type Error = Error;\n\n    fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Pin::new(&mut self.inner).poll_ready(cx).map_err(Error::new)\n    }\n\n    fn start_send(mut self: Pin<&mut Self>, item: Message) -> Result<(), Self::Error> {\n        Pin::new(&mut self.inner)\n            .start_send(item.into_tungstenite())\n            .map_err(Error::new)\n    }\n\n    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Pin::new(&mut self.inner).poll_flush(cx).map_err(Error::new)\n    }\n\n    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Pin::new(&mut self.inner).poll_close(cx).map_err(Error::new)\n    }\n}\n\n/// UTF-8 wrapper for [Bytes].\n///\n/// An [Utf8Bytes] is always guaranteed to contain valid UTF-8.\n#[derive(Debug, Clone, PartialEq, Eq, Default)]\npub struct Utf8Bytes(ts::Utf8Bytes);\n\nimpl Utf8Bytes {\n    /// Creates from a static str.\n    #[inline]\n    #[must_use]\n    pub const fn from_static(str: &'static str) -> Self {\n        Self(ts::Utf8Bytes::from_static(str))\n    }\n\n    /// Returns as a string slice.\n    #[inline]\n    pub fn as_str(&self) -> &str {\n        self.0.as_str()\n    }\n\n    fn into_tungstenite(self) -> ts::Utf8Bytes {\n        self.0\n    }\n}\n\nimpl std::ops::Deref for Utf8Bytes {\n    type Target = str;\n\n    /// ```\n    /// /// Example fn that takes a str slice\n    /// fn a(s: &str) {}\n    ///\n    /// let data = axum::extract::ws::Utf8Bytes::from_static(\"foo123\");\n    ///\n    /// // auto-deref as arg\n    /// a(&data);\n    ///\n    /// // deref to str methods\n    /// assert_eq!(data.len(), 6);\n    /// ```\n    #[inline]\n    fn deref(&self) -> &Self::Target {\n        self.as_str()\n    }\n}\n\nimpl std::fmt::Display for Utf8Bytes {\n    #[inline]\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_str(self.as_str())\n    }\n}\n\nimpl TryFrom<Bytes> for Utf8Bytes {\n    type Error = std::str::Utf8Error;\n\n    #[inline]\n    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {\n        Ok(Self(bytes.try_into()?))\n    }\n}\n\nimpl TryFrom<Vec<u8>> for Utf8Bytes {\n    type Error = std::str::Utf8Error;\n\n    #[inline]\n    fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {\n        Ok(Self(v.try_into()?))\n    }\n}\n\nimpl From<String> for Utf8Bytes {\n    #[inline]\n    fn from(s: String) -> Self {\n        Self(s.into())\n    }\n}\n\nimpl From<&str> for Utf8Bytes {\n    #[inline]\n    fn from(s: &str) -> Self {\n        Self(s.into())\n    }\n}\n\nimpl From<&String> for Utf8Bytes {\n    #[inline]\n    fn from(s: &String) -> Self {\n        Self(s.into())\n    }\n}\n\nimpl From<Utf8Bytes> for Bytes {\n    #[inline]\n    fn from(Utf8Bytes(bytes): Utf8Bytes) -> Self {\n        bytes.into()\n    }\n}\n\nimpl<T> PartialEq<T> for Utf8Bytes\nwhere\n    for<'a> &'a str: PartialEq<T>,\n{\n    /// ```\n    /// let payload = axum::extract::ws::Utf8Bytes::from_static(\"foo123\");\n    /// assert_eq!(payload, \"foo123\");\n    /// assert_eq!(payload, \"foo123\".to_string());\n    /// assert_eq!(payload, &\"foo123\".to_string());\n    /// assert_eq!(payload, std::borrow::Cow::from(\"foo123\"));\n    /// ```\n    #[inline]\n    fn eq(&self, other: &T) -> bool {\n        self.as_str() == *other\n    }\n}\n\n/// Status code used to indicate why an endpoint is closing the WebSocket connection.\npub type CloseCode = u16;\n\n/// A struct representing the close command.\n#[derive(Debug, Clone, Eq, PartialEq)]\npub struct CloseFrame {\n    /// The reason as a code.\n    pub code: CloseCode,\n    /// The reason as text string.\n    pub reason: Utf8Bytes,\n}\n\n/// A WebSocket message.\n//\n// This code comes from https://github.com/snapview/tungstenite-rs/blob/master/src/protocol/message.rs and is under following license:\n// Copyright (c) 2017 Alexey Galakhov\n// Copyright (c) 2016 Jason Housley\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n#[derive(Debug, Eq, PartialEq, Clone)]\npub enum Message {\n    /// A text WebSocket message\n    Text(Utf8Bytes),\n    /// A binary WebSocket message\n    Binary(Bytes),\n    /// A ping message with the specified payload\n    ///\n    /// The payload here must have a length less than 125 bytes.\n    ///\n    /// Ping messages will be automatically responded to by the server, so you do not have to worry\n    /// about dealing with them yourself.\n    Ping(Bytes),\n    /// A pong message with the specified payload\n    ///\n    /// The payload here must have a length less than 125 bytes.\n    ///\n    /// Pong messages will be automatically sent to the client if a ping message is received, so\n    /// you do not have to worry about constructing them yourself unless you want to implement a\n    /// [unidirectional heartbeat](https://tools.ietf.org/html/rfc6455#section-5.5.3).\n    Pong(Bytes),\n    /// A close message with the optional close frame.\n    ///\n    /// You may \"uncleanly\" close a WebSocket connection at any time\n    /// by simply dropping the [`WebSocket`].\n    /// However, you may also use the graceful closing protocol, in which\n    /// 1. peer A sends a close frame, and does not send any further messages;\n    /// 2. peer B responds with a close frame, and does not send any further messages;\n    /// 3. peer A processes the remaining messages sent by peer B, before finally\n    /// 4. both peers close the connection.\n    ///\n    /// After sending a close frame,\n    /// you may still read messages,\n    /// but attempts to send another message will error.\n    /// After receiving a close frame,\n    /// axum will automatically respond with a close frame if necessary\n    /// (you do not have to deal with this yourself).\n    /// Since no further messages will be received,\n    /// you may either do nothing\n    /// or explicitly drop the connection.\n    Close(Option<CloseFrame>),\n}\n\nimpl Message {\n    fn into_tungstenite(self) -> ts::Message {\n        match self {\n            Self::Text(text) => ts::Message::Text(text.into_tungstenite()),\n            Self::Binary(binary) => ts::Message::Binary(binary),\n            Self::Ping(ping) => ts::Message::Ping(ping),\n            Self::Pong(pong) => ts::Message::Pong(pong),\n            Self::Close(Some(close)) => ts::Message::Close(Some(ts::protocol::CloseFrame {\n                code: ts::protocol::frame::coding::CloseCode::from(close.code),\n                reason: close.reason.into_tungstenite(),\n            })),\n            Self::Close(None) => ts::Message::Close(None),\n        }\n    }\n\n    fn from_tungstenite(message: ts::Message) -> Option<Self> {\n        match message {\n            ts::Message::Text(text) => Some(Self::Text(Utf8Bytes(text))),\n            ts::Message::Binary(binary) => Some(Self::Binary(binary)),\n            ts::Message::Ping(ping) => Some(Self::Ping(ping)),\n            ts::Message::Pong(pong) => Some(Self::Pong(pong)),\n            ts::Message::Close(Some(close)) => Some(Self::Close(Some(CloseFrame {\n                code: close.code.into(),\n                reason: Utf8Bytes(close.reason),\n            }))),\n            ts::Message::Close(None) => Some(Self::Close(None)),\n            // we can ignore `Frame` frames as recommended by the tungstenite maintainers\n            // https://github.com/snapview/tungstenite-rs/issues/268\n            ts::Message::Frame(_) => None,\n        }\n    }\n\n    /// Consume the WebSocket and return it as binary data.\n    pub fn into_data(self) -> Bytes {\n        match self {\n            Self::Text(string) => Bytes::from(string),\n            Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => data,\n            Self::Close(None) => Bytes::new(),\n            Self::Close(Some(frame)) => Bytes::from(frame.reason),\n        }\n    }\n\n    /// Attempt to consume the WebSocket message and convert it to a Utf8Bytes.\n    pub fn into_text(self) -> Result<Utf8Bytes, Error> {\n        match self {\n            Self::Text(string) => Ok(string),\n            Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => {\n                Ok(Utf8Bytes::try_from(data).map_err(Error::new)?)\n            }\n            Self::Close(None) => Ok(Utf8Bytes::default()),\n            Self::Close(Some(frame)) => Ok(frame.reason),\n        }\n    }\n\n    /// Attempt to get a &str from the WebSocket message,\n    /// this will try to convert binary data to utf8.\n    pub fn to_text(&self) -> Result<&str, Error> {\n        match *self {\n            Self::Text(ref string) => Ok(string.as_str()),\n            Self::Binary(ref data) | Self::Ping(ref data) | Self::Pong(ref data) => {\n                Ok(std::str::from_utf8(data).map_err(Error::new)?)\n            }\n            Self::Close(None) => Ok(\"\"),\n            Self::Close(Some(ref frame)) => Ok(&frame.reason),\n        }\n    }\n\n    /// Create a new text WebSocket message from a stringable.\n    pub fn text<S>(string: S) -> Self\n    where\n        S: Into<Utf8Bytes>,\n    {\n        Self::Text(string.into())\n    }\n\n    /// Create a new binary WebSocket message by converting to `Bytes`.\n    pub fn binary<B>(bin: B) -> Self\n    where\n        B: Into<Bytes>,\n    {\n        Self::Binary(bin.into())\n    }\n}\n\nimpl From<String> for Message {\n    fn from(string: String) -> Self {\n        Self::Text(string.into())\n    }\n}\n\nimpl<'s> From<&'s str> for Message {\n    fn from(string: &'s str) -> Self {\n        Self::Text(string.into())\n    }\n}\n\nimpl<'b> From<&'b [u8]> for Message {\n    fn from(data: &'b [u8]) -> Self {\n        Self::Binary(Bytes::copy_from_slice(data))\n    }\n}\n\nimpl From<Bytes> for Message {\n    fn from(data: Bytes) -> Self {\n        Self::Binary(data)\n    }\n}\n\nimpl From<Vec<u8>> for Message {\n    fn from(data: Vec<u8>) -> Self {\n        Self::Binary(data.into())\n    }\n}\n\nimpl From<Message> for Vec<u8> {\n    fn from(msg: Message) -> Self {\n        msg.into_data().to_vec()\n    }\n}\n\nfn sign(key: &[u8]) -> HeaderValue {\n    use base64::engine::Engine as _;\n\n    let mut sha1 = Sha1::default();\n    sha1.update(key);\n    sha1.update(&b\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\"[..]);\n    let b64 = Bytes::from(base64::engine::general_purpose::STANDARD.encode(sha1.finalize()));\n    HeaderValue::from_maybe_shared(b64).expect(\"base64 is a valid value\")\n}\n\npub mod rejection {\n    //! WebSocket specific rejections.\n\n    use axum_core::__composite_rejection as composite_rejection;\n    use axum_core::__define_rejection as define_rejection;\n\n    define_rejection! {\n        #[status = METHOD_NOT_ALLOWED]\n        #[body = \"Request method must be `GET`\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        pub struct MethodNotGet;\n    }\n\n    define_rejection! {\n        #[status = METHOD_NOT_ALLOWED]\n        #[body = \"Request method must be `CONNECT`\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        pub struct MethodNotConnect;\n    }\n\n    define_rejection! {\n        #[status = BAD_REQUEST]\n        #[body = \"Connection header did not include 'upgrade'\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        pub struct InvalidConnectionHeader;\n    }\n\n    define_rejection! {\n        #[status = BAD_REQUEST]\n        #[body = \"`Upgrade` header did not include 'websocket'\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        pub struct InvalidUpgradeHeader;\n    }\n\n    define_rejection! {\n        #[status = BAD_REQUEST]\n        #[body = \"`:protocol` pseudo-header did not include 'websocket'\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        pub struct InvalidProtocolPseudoheader;\n    }\n\n    define_rejection! {\n        #[status = BAD_REQUEST]\n        #[body = \"`Sec-WebSocket-Version` header did not include '13'\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        pub struct InvalidWebSocketVersionHeader;\n    }\n\n    define_rejection! {\n        #[status = BAD_REQUEST]\n        #[body = \"`Sec-WebSocket-Key` header missing\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        pub struct WebSocketKeyHeaderMissing;\n    }\n\n    define_rejection! {\n        #[status = UPGRADE_REQUIRED]\n        #[body = \"WebSocket request couldn't be upgraded since no upgrade state was present\"]\n        /// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        ///\n        /// This rejection is returned if the connection cannot be upgraded for example if the\n        /// request is HTTP/1.0.\n        ///\n        /// See [MDN] for more details about connection upgrades.\n        ///\n        /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade\n        pub struct ConnectionNotUpgradable;\n    }\n\n    composite_rejection! {\n        /// Rejection used for [`WebSocketUpgrade`](super::WebSocketUpgrade).\n        ///\n        /// Contains one variant for each way the [`WebSocketUpgrade`](super::WebSocketUpgrade)\n        /// extractor can fail.\n        pub enum WebSocketUpgradeRejection {\n            MethodNotGet,\n            MethodNotConnect,\n            InvalidConnectionHeader,\n            InvalidUpgradeHeader,\n            InvalidProtocolPseudoheader,\n            InvalidWebSocketVersionHeader,\n            WebSocketKeyHeaderMissing,\n            ConnectionNotUpgradable,\n        }\n    }\n}\n\npub mod close_code {\n    //! Constants for [`CloseCode`]s.\n    //!\n    //! [`CloseCode`]: super::CloseCode\n\n    /// Indicates a normal closure, meaning that the purpose for which the connection was\n    /// established has been fulfilled.\n    pub const NORMAL: u16 = 1000;\n\n    /// Indicates that an endpoint is \"going away\", such as a server going down or a browser having\n    /// navigated away from a page.\n    pub const AWAY: u16 = 1001;\n\n    /// Indicates that an endpoint is terminating the connection due to a protocol error.\n    pub const PROTOCOL: u16 = 1002;\n\n    /// Indicates that an endpoint is terminating the connection because it has received a type of\n    /// data that it cannot accept.\n    ///\n    /// For example, an endpoint MAY send this if it understands only text data, but receives a binary message.\n    pub const UNSUPPORTED: u16 = 1003;\n\n    /// Indicates that no status code was included in a closing frame.\n    pub const STATUS: u16 = 1005;\n\n    /// Indicates an abnormal closure.\n    pub const ABNORMAL: u16 = 1006;\n\n    /// Indicates that an endpoint is terminating the connection because it has received data\n    /// within a message that was not consistent with the type of the message.\n    ///\n    /// For example, an endpoint received non-UTF-8 RFC3629 data within a text message.\n    pub const INVALID: u16 = 1007;\n\n    /// Indicates that an endpoint is terminating the connection because it has received a message\n    /// that violates its policy.\n    ///\n    /// This is a generic status code that can be returned when there is\n    /// no other more suitable status code (e.g., `UNSUPPORTED` or `SIZE`) or if there is a need to\n    /// hide specific details about the policy.\n    pub const POLICY: u16 = 1008;\n\n    /// Indicates that an endpoint is terminating the connection because it has received a message\n    /// that is too big for it to process.\n    pub const SIZE: u16 = 1009;\n\n    /// Indicates that an endpoint (client) is terminating the connection because the server\n    /// did not respond to extension negotiation correctly.\n    ///\n    /// Specifically, the client has expected the server to negotiate one or more extension(s),\n    /// but the server didn't return them in the response message of the WebSocket handshake.\n    /// The list of extensions that are needed should be given as the reason for closing.\n    /// Note that this status code is not used by the server,\n    /// because it can fail the WebSocket handshake instead.\n    pub const EXTENSION: u16 = 1010;\n\n    /// Indicates that a server is terminating the connection because it encountered an unexpected\n    /// condition that prevented it from fulfilling the request.\n    pub const ERROR: u16 = 1011;\n\n    /// Indicates that the server is restarting.\n    pub const RESTART: u16 = 1012;\n\n    /// Indicates that the server is overloaded and the client should either connect to a different\n    /// IP (when multiple targets exist), or reconnect to the same IP when a user has performed an\n    /// action.\n    pub const AGAIN: u16 = 1013;\n}\n\n#[cfg(test)]\nmod tests {\n    use std::future::ready;\n\n    use super::*;\n    use crate::{routing::any, test_helpers::spawn_service, Router};\n    use http::{Request, Version};\n    use http_body_util::BodyExt as _;\n    use hyper_util::rt::TokioExecutor;\n    use tokio::io::{AsyncRead, AsyncWrite};\n    use tokio::net::TcpStream;\n    use tokio_tungstenite::tungstenite;\n    use tower::ServiceExt;\n\n    #[crate::test]\n    async fn rejects_http_1_0_requests() {\n        let svc = any(|ws: Result<WebSocketUpgrade, WebSocketUpgradeRejection>| {\n            let rejection = ws.unwrap_err();\n            assert!(matches!(\n                rejection,\n                WebSocketUpgradeRejection::ConnectionNotUpgradable(_)\n            ));\n            std::future::ready(())\n        });\n\n        let req = Request::builder()\n            .version(Version::HTTP_10)\n            .method(Method::GET)\n            .header(\"upgrade\", \"websocket\")\n            .header(\"connection\", \"Upgrade\")\n            .header(\"sec-websocket-key\", \"6D69KGBOr4Re+Nj6zx9aQA==\")\n            .header(\"sec-websocket-version\", \"13\")\n            .body(Body::empty())\n            .unwrap();\n\n        let res = svc.oneshot(req).await.unwrap();\n\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[allow(dead_code)]\n    fn default_on_failed_upgrade() {\n        async fn handler(ws: WebSocketUpgrade) -> Response {\n            ws.on_upgrade(|_| async {})\n        }\n        let _: Router = Router::new().route(\"/\", any(handler));\n    }\n\n    #[allow(dead_code)]\n    fn on_failed_upgrade() {\n        async fn handler(ws: WebSocketUpgrade) -> Response {\n            ws.on_failed_upgrade(|_error: Error| println!(\"oops!\"))\n                .on_upgrade(|_| async {})\n        }\n        let _: Router = Router::new().route(\"/\", any(handler));\n    }\n\n    #[crate::test]\n    async fn integration_test() {\n        let addr = spawn_service(echo_app());\n        let uri = format!(\"ws://{addr}/echo\").try_into().unwrap();\n        let req = tungstenite::client::ClientRequestBuilder::new(uri)\n            .with_sub_protocol(TEST_ECHO_APP_REQ_SUBPROTO);\n        let (socket, response) = tokio_tungstenite::connect_async(req).await.unwrap();\n        test_echo_app(socket, response.headers()).await;\n    }\n\n    #[crate::test]\n    #[cfg(feature = \"http2\")]\n    async fn http2() {\n        let addr = spawn_service(echo_app());\n        let io = TokioIo::new(TcpStream::connect(addr).await.unwrap());\n        let (mut send_request, conn) =\n            hyper::client::conn::http2::Builder::new(TokioExecutor::new())\n                .handshake(io)\n                .await\n                .unwrap();\n\n        // Wait a little for the SETTINGS frame to go through…\n        for _ in 0..10 {\n            tokio::task::yield_now().await;\n        }\n        assert!(conn.is_extended_connect_protocol_enabled());\n        tokio::spawn(async {\n            conn.await.unwrap();\n        });\n\n        let req = Request::builder()\n            .method(Method::CONNECT)\n            .extension(hyper::ext::Protocol::from_static(\"websocket\"))\n            .uri(\"/echo\")\n            .header(\"sec-websocket-version\", \"13\")\n            .header(\"sec-websocket-protocol\", TEST_ECHO_APP_REQ_SUBPROTO)\n            .header(\"Host\", \"server.example.com\")\n            .body(Body::empty())\n            .unwrap();\n\n        let mut response = send_request.send_request(req).await.unwrap();\n        let status = response.status();\n        if status != 200 {\n            let body = response.into_body().collect().await.unwrap().to_bytes();\n            let body = std::str::from_utf8(&body).unwrap();\n            panic!(\"response status was {status}: {body}\");\n        }\n        let upgraded = hyper::upgrade::on(&mut response).await.unwrap();\n        let upgraded = TokioIo::new(upgraded);\n        let socket = WebSocketStream::from_raw_socket(upgraded, protocol::Role::Client, None).await;\n        test_echo_app(socket, response.headers()).await;\n    }\n\n    fn echo_app() -> Router {\n        async fn handle_socket(mut socket: WebSocket) {\n            assert_eq!(socket.protocol().unwrap(), \"echo\");\n            while let Some(Ok(msg)) = socket.recv().await {\n                match msg {\n                    Message::Text(_) | Message::Binary(_) | Message::Close(_) => {\n                        if socket.send(msg).await.is_err() {\n                            break;\n                        }\n                    }\n                    Message::Ping(_) | Message::Pong(_) => {\n                        // tungstenite will respond to pings automatically\n                    }\n                }\n            }\n        }\n\n        Router::new().route(\n            \"/echo\",\n            any(|ws: WebSocketUpgrade| {\n                let ws = ws.protocols([\"echo2\", \"echo\"]);\n                assert_eq!(ws.selected_protocol().unwrap(), \"echo\");\n                ready(ws.on_upgrade(handle_socket))\n            }),\n        )\n    }\n\n    const TEST_ECHO_APP_REQ_SUBPROTO: &str = \"echo3, echo\";\n    async fn test_echo_app<S: AsyncRead + AsyncWrite + Unpin>(\n        mut socket: WebSocketStream<S>,\n        headers: &http::HeaderMap,\n    ) {\n        assert_eq!(headers[http::header::SEC_WEBSOCKET_PROTOCOL], \"echo\");\n\n        let input = tungstenite::Message::Text(tungstenite::Utf8Bytes::from_static(\"foobar\"));\n        socket.send(input.clone()).await.unwrap();\n        let output = socket.next().await.unwrap().unwrap();\n        assert_eq!(input, output);\n\n        socket\n            .send(tungstenite::Message::Ping(Bytes::from_static(b\"ping\")))\n            .await\n            .unwrap();\n        let output = socket.next().await.unwrap().unwrap();\n        assert_eq!(\n            output,\n            tungstenite::Message::Pong(Bytes::from_static(b\"ping\"))\n        );\n    }\n}\n"
  },
  {
    "path": "axum/src/form.rs",
    "content": "use crate::extract::Request;\nuse crate::extract::{rejection::*, FromRequest, RawForm};\nuse axum_core::response::{IntoResponse, IntoResponseFailed, Response};\nuse axum_core::RequestExt;\nuse http::header::CONTENT_TYPE;\nuse http::StatusCode;\nuse serde_core::{de::DeserializeOwned, Serialize};\n\n/// URL encoded extractor and response.\n///\n/// # As extractor\n///\n/// If used as an extractor, `Form` will deserialize form data from the request,\n/// specifically:\n///\n/// - If the request has a method of `GET` or `HEAD`, the form data will be read\n///   from the query string (same as with [`Query`])\n/// - If the request has a different method, the form will be read from the body\n///   of the request. It must have a `content-type` of\n///   `application/x-www-form-urlencoded` for this to work. If you want to parse\n///   `multipart/form-data` request bodies, use [`Multipart`] instead.\n///\n/// This matches how HTML forms are sent by browsers by default.\n/// In both cases, the inner type `T` must implement [`serde::Deserialize`].\n///\n/// ⚠️ Since parsing form data might require consuming the request body, the `Form` extractor must be\n/// *last* if there are multiple extractors in a handler. See [\"the order of\n/// extractors\"][order-of-extractors]\n///\n/// [order-of-extractors]: crate::extract#the-order-of-extractors\n///\n/// ```rust\n/// use axum::Form;\n/// use serde::Deserialize;\n///\n/// #[derive(Deserialize)]\n/// struct SignUp {\n///     username: String,\n///     password: String,\n/// }\n///\n/// async fn accept_form(Form(sign_up): Form<SignUp>) {\n///     // ...\n/// }\n/// ```\n///\n/// # As response\n///\n/// `Form` can also be used to encode any type that implements\n/// [`serde::Serialize`] as `application/x-www-form-urlencoded`\n///\n/// ```rust\n/// use axum::Form;\n/// use serde::Serialize;\n///\n/// #[derive(Serialize)]\n/// struct Payload {\n///     value: String,\n/// }\n///\n/// async fn handler() -> Form<Payload> {\n///     Form(Payload { value: \"foo\".to_owned() })\n/// }\n/// ```\n///\n/// [`Query`]: crate::extract::Query\n/// [`Multipart`]: crate::extract::Multipart\n#[cfg_attr(docsrs, doc(cfg(feature = \"form\")))]\n#[derive(Debug, Clone, Copy, Default)]\n#[must_use]\npub struct Form<T>(pub T);\n\nimpl<T, S> FromRequest<S> for Form<T>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = FormRejection;\n\n    async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        let is_get_or_head =\n            req.method() == http::Method::GET || req.method() == http::Method::HEAD;\n\n        match req.extract().await {\n            Ok(RawForm(bytes)) => {\n                let deserializer =\n                    serde_html_form::Deserializer::new(form_urlencoded::parse(&bytes));\n                let value = serde_path_to_error::deserialize(deserializer).map_err(\n                    |err| -> FormRejection {\n                        if is_get_or_head {\n                            FailedToDeserializeForm::from_err(err).into()\n                        } else {\n                            FailedToDeserializeFormBody::from_err(err).into()\n                        }\n                    },\n                )?;\n                Ok(Self(value))\n            }\n            Err(RawFormRejection::BytesRejection(r)) => Err(FormRejection::BytesRejection(r)),\n            Err(RawFormRejection::InvalidFormContentType(r)) => {\n                Err(FormRejection::InvalidFormContentType(r))\n            }\n        }\n    }\n}\n\nimpl<T> IntoResponse for Form<T>\nwhere\n    T: Serialize,\n{\n    fn into_response(self) -> Response {\n        // Extracted into separate fn so it's only compiled once for all T.\n        fn make_response(ser_result: Result<String, serde_html_form::ser::Error>) -> Response {\n            match ser_result {\n                Ok(body) => (\n                    [(CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref())],\n                    body,\n                )\n                    .into_response(),\n                Err(err) => (\n                    StatusCode::INTERNAL_SERVER_ERROR,\n                    IntoResponseFailed,\n                    err.to_string(),\n                )\n                    .into_response(),\n            }\n        }\n\n        make_response(serde_html_form::to_string(&self.0))\n    }\n}\naxum_core::__impl_deref!(Form);\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        routing::{on, MethodFilter},\n        test_helpers::TestClient,\n        Router,\n    };\n\n    use super::*;\n    use axum_core::body::Body;\n    use http::{Method, Request};\n    use mime::APPLICATION_WWW_FORM_URLENCODED;\n    use serde::{Deserialize, Serialize};\n    use std::fmt::Debug;\n\n    #[derive(Debug, PartialEq, Serialize, Deserialize)]\n    struct Pagination {\n        size: Option<u64>,\n        page: Option<u64>,\n    }\n\n    async fn check_query<T: DeserializeOwned + PartialEq + Debug>(uri: impl AsRef<str>, value: T) {\n        let req = Request::builder()\n            .uri(uri.as_ref())\n            .body(Body::empty())\n            .unwrap();\n        assert_eq!(Form::<T>::from_request(req, &()).await.unwrap().0, value);\n    }\n\n    async fn check_body<T: Serialize + DeserializeOwned + PartialEq + Debug>(value: T) {\n        let req = Request::builder()\n            .uri(\"http://example.com/test\")\n            .method(Method::POST)\n            .header(CONTENT_TYPE, APPLICATION_WWW_FORM_URLENCODED.as_ref())\n            .body(Body::from(serde_html_form::to_string(&value).unwrap()))\n            .unwrap();\n        assert_eq!(Form::<T>::from_request(req, &()).await.unwrap().0, value);\n    }\n\n    #[crate::test]\n    async fn test_form_query() {\n        check_query(\n            \"http://example.com/test\",\n            Pagination {\n                size: None,\n                page: None,\n            },\n        )\n        .await;\n\n        check_query(\n            \"http://example.com/test?size=10\",\n            Pagination {\n                size: Some(10),\n                page: None,\n            },\n        )\n        .await;\n\n        check_query(\n            \"http://example.com/test?size=10&page=20\",\n            Pagination {\n                size: Some(10),\n                page: Some(20),\n            },\n        )\n        .await;\n    }\n\n    #[crate::test]\n    async fn test_form_body() {\n        check_body(Pagination {\n            size: None,\n            page: None,\n        })\n        .await;\n\n        check_body(Pagination {\n            size: Some(10),\n            page: None,\n        })\n        .await;\n\n        check_body(Pagination {\n            size: Some(10),\n            page: Some(20),\n        })\n        .await;\n    }\n\n    #[crate::test]\n    async fn test_incorrect_content_type() {\n        let req = Request::builder()\n            .uri(\"http://example.com/test\")\n            .method(Method::POST)\n            .header(CONTENT_TYPE, mime::APPLICATION_JSON.as_ref())\n            .body(Body::from(\n                serde_html_form::to_string(&Pagination {\n                    size: Some(10),\n                    page: None,\n                })\n                .unwrap(),\n            ))\n            .unwrap();\n        assert!(matches!(\n            Form::<Pagination>::from_request(req, &())\n                .await\n                .unwrap_err(),\n            FormRejection::InvalidFormContentType(InvalidFormContentType)\n        ));\n    }\n\n    #[tokio::test]\n    async fn deserialize_error_status_codes() {\n        #[allow(dead_code)]\n        #[derive(Deserialize)]\n        struct Payload {\n            a: i32,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            on(\n                MethodFilter::GET.or(MethodFilter::POST),\n                |_: Form<Payload>| async {},\n            ),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/?a=false\").await;\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n        assert_eq!(\n            res.text().await,\n            \"Failed to deserialize form: a: invalid digit found in string\"\n        );\n\n        let res = client\n            .post(\"/\")\n            .header(CONTENT_TYPE, APPLICATION_WWW_FORM_URLENCODED.as_ref())\n            .body(\"a=false\")\n            .await;\n        assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);\n        assert_eq!(\n            res.text().await,\n            \"Failed to deserialize form body: a: invalid digit found in string\"\n        );\n    }\n}\n"
  },
  {
    "path": "axum/src/handler/future.rs",
    "content": "//! Handler future types.\n\nuse crate::response::Response;\nuse axum_core::extract::Request;\nuse futures_util::future::Map;\nuse pin_project_lite::pin_project;\nuse std::{convert::Infallible, future::Future, pin::Pin, task::Context};\nuse tower::util::Oneshot;\nuse tower_service::Service;\n\nopaque_future! {\n    /// The response future for [`IntoService`](super::IntoService).\n    pub type IntoServiceFuture<F> =\n        Map<\n            F,\n            fn(Response) -> Result<Response, Infallible>,\n        >;\n}\n\npin_project! {\n    /// The response future for [`Layered`](super::Layered).\n    pub struct LayeredFuture<S>\n    where\n        S: Service<Request>,\n    {\n        #[pin]\n        inner: Map<Oneshot<S, Request>, fn(Result<S::Response, S::Error>) -> Response>,\n    }\n}\n\nimpl<S> LayeredFuture<S>\nwhere\n    S: Service<Request>,\n{\n    pub(super) fn new(\n        inner: Map<Oneshot<S, Request>, fn(Result<S::Response, S::Error>) -> Response>,\n    ) -> Self {\n        Self { inner }\n    }\n}\n\nimpl<S> Future for LayeredFuture<S>\nwhere\n    S: Service<Request>,\n{\n    type Output = Response;\n\n    #[inline]\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> std::task::Poll<Self::Output> {\n        self.project().inner.poll(cx)\n    }\n}\n"
  },
  {
    "path": "axum/src/handler/mod.rs",
    "content": "//! Async functions that can be used to handle requests.\n//!\n#![doc = include_str!(\"../docs/handlers_intro.md\")]\n//!\n//! Some examples of handlers:\n//!\n//! ```rust\n//! use axum::{body::Bytes, http::StatusCode};\n//!\n//! // Handler that immediately returns an empty `200 OK` response.\n//! async fn unit_handler() {}\n//!\n//! // Handler that immediately returns a `200 OK` response with a plain text\n//! // body.\n//! async fn string_handler() -> String {\n//!     \"Hello, World!\".to_string()\n//! }\n//!\n//! // Handler that buffers the request body and returns it.\n//! //\n//! // This works because `Bytes` implements `FromRequest`\n//! // and therefore can be used as an extractor.\n//! //\n//! // `String` and `StatusCode` both implement `IntoResponse` and\n//! // therefore `Result<String, StatusCode>` also implements `IntoResponse`\n//! async fn echo(body: Bytes) -> Result<String, StatusCode> {\n//!     if let Ok(string) = String::from_utf8(body.to_vec()) {\n//!         Ok(string)\n//!     } else {\n//!         Err(StatusCode::BAD_REQUEST)\n//!     }\n//! }\n//! ```\n//!\n//! Instead of a direct `StatusCode`, it makes sense to use intermediate error type\n//! that can ultimately be converted to `Response`. This allows using `?` operator\n//! in handlers. See those examples:\n//!\n//! * [`anyhow-error-response`][anyhow] for generic boxed errors\n//! * [`error-handling`][error-handling] for application-specific detailed errors\n//!\n//! [anyhow]: https://github.com/tokio-rs/axum/blob/main/examples/anyhow-error-response/src/main.rs\n//! [error-handling]: https://github.com/tokio-rs/axum/blob/main/examples/error-handling/src/main.rs\n//!\n#![doc = include_str!(\"../docs/debugging_handler_type_errors.md\")]\n\n#[cfg(feature = \"tokio\")]\nuse crate::extract::connect_info::IntoMakeServiceWithConnectInfo;\nuse crate::{\n    extract::{FromRequest, FromRequestParts, Request},\n    response::{IntoResponse, Response},\n    routing::IntoMakeService,\n};\nuse std::{convert::Infallible, fmt, future::Future, marker::PhantomData, pin::Pin};\nuse tower::ServiceExt;\nuse tower_layer::Layer;\nuse tower_service::Service;\n\npub mod future;\nmod service;\n\npub use self::service::HandlerService;\n\n/// Trait for async functions that can be used to handle requests.\n///\n/// You shouldn't need to depend on this trait directly. It is automatically\n/// implemented to closures of the right types.\n///\n/// See the [module docs](crate::handler) for more details.\n///\n/// # Converting `Handler`s into [`Service`]s\n///\n/// To convert `Handler`s into [`Service`]s you have to call either\n/// [`HandlerWithoutStateExt::into_service`] or [`Handler::with_state`]:\n///\n/// ```\n/// use tower::Service;\n/// use axum::{\n///     extract::{State, Request},\n///     body::Body,\n///     handler::{HandlerWithoutStateExt, Handler},\n/// };\n///\n/// // this handler doesn't require any state\n/// async fn one() {}\n/// // so it can be converted to a service with `HandlerWithoutStateExt::into_service`\n/// assert_service(one.into_service());\n///\n/// // this handler requires state\n/// async fn two(_: State<String>) {}\n/// // so we have to provide it\n/// let handler_with_state = two.with_state(String::new());\n/// // which gives us a `Service`\n/// assert_service(handler_with_state);\n///\n/// // helper to check that a value implements `Service`\n/// fn assert_service<S>(service: S)\n/// where\n///     S: Service<Request>,\n/// {}\n/// ```\n#[doc = include_str!(\"../docs/debugging_handler_type_errors.md\")]\n///\n/// # Handlers that aren't functions\n///\n/// The `Handler` trait is also implemented for `T: IntoResponse`. That allows easily returning\n/// fixed data for routes:\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::{get, post},\n///     Json,\n///     http::StatusCode,\n/// };\n/// use serde_json::json;\n///\n/// let app = Router::new()\n///     // respond with a fixed string\n///     .route(\"/\", get(\"Hello, World!\"))\n///     // or return some mock data\n///     .route(\"/users\", post((\n///         StatusCode::CREATED,\n///         Json(json!({ \"id\": 1, \"username\": \"alice\" })),\n///     )));\n/// # let _: Router = app;\n/// ```\n///\n/// # About type parameter `T`\n///\n/// **Generally you shouldn't need to worry about `T`**; when calling methods such as\n/// [`post`](crate::routing::method_routing::post) it will be automatically inferred and this is\n/// the intended way for this parameter to be provided in application code.\n///\n/// If you are implementing your own methods that accept implementations of `Handler` as\n/// arguments, then the following may be useful:\n///\n/// The type parameter `T` is a workaround for trait coherence rules, allowing us to\n/// write blanket implementations of `Handler` over many types of handler functions\n/// with different numbers of arguments, without the compiler forbidding us from doing\n/// so because one type `F` can in theory implement both `Fn(A) -> X` and `Fn(A, B) -> Y`.\n/// `T` is a placeholder taking on a representation of the parameters of the handler function,\n/// as well as other similar 'coherence rule workaround' discriminators,\n/// allowing us to select one function signature to use as a `Handler`.\n#[diagnostic::on_unimplemented(\n    note = \"Consider using `#[axum::debug_handler]` to improve the error message\"\n)]\npub trait Handler<T, S>: Clone + Send + Sync + Sized + 'static {\n    /// The type of future calling this handler returns.\n    type Future: Future<Output = Response> + Send + 'static;\n\n    /// Call the handler with the given request.\n    fn call(self, req: Request, state: S) -> Self::Future;\n\n    /// Apply a [`tower::Layer`] to the handler.\n    ///\n    /// All requests to the handler will be processed by the layer's\n    /// corresponding middleware.\n    ///\n    /// This can be used to add additional processing to a request for a single\n    /// handler.\n    ///\n    /// Note this differs from [`routing::Router::layer`](crate::routing::Router::layer)\n    /// which adds a middleware to a group of routes.\n    ///\n    /// If you're applying middleware that produces errors you have to handle the errors\n    /// so they're converted into responses. You can learn more about doing that\n    /// [here](crate::error_handling).\n    ///\n    /// # Example\n    ///\n    /// Adding the [`tower::limit::ConcurrencyLimit`] middleware to a handler\n    /// can be done like so:\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     routing::get,\n    ///     handler::Handler,\n    ///     Router,\n    /// };\n    /// use tower::limit::{ConcurrencyLimitLayer, ConcurrencyLimit};\n    ///\n    /// async fn handler() { /* ... */ }\n    ///\n    /// let layered_handler = handler.layer(ConcurrencyLimitLayer::new(64));\n    /// let app = Router::new().route(\"/\", get(layered_handler));\n    /// # let _: Router = app;\n    /// ```\n    fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>\n    where\n        L: Layer<HandlerService<Self, T, S>> + Clone,\n        L::Service: Service<Request>,\n    {\n        Layered {\n            layer,\n            handler: self,\n            _marker: PhantomData,\n        }\n    }\n\n    /// Convert the handler into a [`Service`] by providing the state\n    fn with_state(self, state: S) -> HandlerService<Self, T, S> {\n        HandlerService::new(self, state)\n    }\n}\n\n#[diagnostic::do_not_recommend]\nimpl<F, Fut, Res, S> Handler<((),), S> for F\nwhere\n    F: FnOnce() -> Fut + Clone + Send + Sync + 'static,\n    Fut: Future<Output = Res> + Send,\n    Res: IntoResponse,\n{\n    type Future = Pin<Box<dyn Future<Output = Response> + Send>>;\n\n    fn call(self, _req: Request, _state: S) -> Self::Future {\n        Box::pin(async move { self().await.into_response() })\n    }\n}\n\nmacro_rules! impl_handler {\n    (\n        [$($ty:ident),*], $last:ident\n    ) => {\n        #[diagnostic::do_not_recommend]\n        #[allow(non_snake_case, unused_mut)]\n        impl<F, Fut, S, Res, M, $($ty,)* $last> Handler<(M, $($ty,)* $last,), S> for F\n        where\n            F: FnOnce($($ty,)* $last,) -> Fut + Clone + Send + Sync + 'static,\n            Fut: Future<Output = Res> + Send,\n            S: Send + Sync + 'static,\n            Res: IntoResponse,\n            $( $ty: FromRequestParts<S> + Send, )*\n            $last: FromRequest<S, M> + Send,\n        {\n            type Future = Pin<Box<dyn Future<Output = Response> + Send>>;\n\n            fn call(self, req: Request, state: S) -> Self::Future {\n                let (mut parts, body) = req.into_parts();\n                Box::pin(async move {\n                    $(\n                        let $ty = match $ty::from_request_parts(&mut parts, &state).await {\n                            Ok(value) => value,\n                            Err(rejection) => return rejection.into_response(),\n                        };\n                    )*\n\n                    let req = Request::from_parts(parts, body);\n\n                    let $last = match $last::from_request(req, &state).await {\n                        Ok(value) => value,\n                        Err(rejection) => return rejection.into_response(),\n                    };\n\n                    self($($ty,)* $last,).await.into_response()\n                })\n            }\n        }\n    };\n}\n\nall_the_tuples!(impl_handler);\n\nmod private {\n    // Marker type for `impl<T: IntoResponse> Handler for T`\n    #[allow(missing_debug_implementations)]\n    pub enum IntoResponseHandler {}\n}\n\n#[diagnostic::do_not_recommend]\nimpl<T, S> Handler<private::IntoResponseHandler, S> for T\nwhere\n    T: IntoResponse + Clone + Send + Sync + 'static,\n{\n    type Future = std::future::Ready<Response>;\n\n    fn call(self, _req: Request, _state: S) -> Self::Future {\n        std::future::ready(self.into_response())\n    }\n}\n\n/// A [`Service`] created from a [`Handler`] by applying a Tower middleware.\n///\n/// Created with [`Handler::layer`]. See that method for more details.\npub struct Layered<L, H, T, S> {\n    layer: L,\n    handler: H,\n    _marker: PhantomData<fn() -> (T, S)>,\n}\n\nimpl<L, H, T, S> fmt::Debug for Layered<L, H, T, S>\nwhere\n    L: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Layered\")\n            .field(\"layer\", &self.layer)\n            .finish()\n    }\n}\n\nimpl<L, H, T, S> Clone for Layered<L, H, T, S>\nwhere\n    L: Clone,\n    H: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            layer: self.layer.clone(),\n            handler: self.handler.clone(),\n            _marker: PhantomData,\n        }\n    }\n}\n\n#[diagnostic::do_not_recommend]\nimpl<H, S, T, L> Handler<T, S> for Layered<L, H, T, S>\nwhere\n    L: Layer<HandlerService<H, T, S>> + Clone + Send + Sync + 'static,\n    H: Handler<T, S>,\n    L::Service: Service<Request, Error = Infallible> + Clone + Send + 'static,\n    <L::Service as Service<Request>>::Response: IntoResponse,\n    <L::Service as Service<Request>>::Future: Send,\n    T: 'static,\n    S: 'static,\n{\n    type Future = future::LayeredFuture<L::Service>;\n\n    fn call(self, req: Request, state: S) -> Self::Future {\n        use futures_util::future::{FutureExt, Map};\n\n        let svc = self.handler.with_state(state);\n        let svc = self.layer.layer(svc);\n\n        let future: Map<\n            _,\n            fn(\n                Result<\n                    <L::Service as Service<Request>>::Response,\n                    <L::Service as Service<Request>>::Error,\n                >,\n            ) -> _,\n        > = svc.oneshot(req).map(|result| match result {\n            Ok(res) => res.into_response(),\n            Err(err) => match err {},\n        });\n\n        future::LayeredFuture::new(future)\n    }\n}\n\n/// Extension trait for [`Handler`]s that don't have state.\n///\n/// This provides convenience methods to convert the [`Handler`] into a [`Service`] or [`MakeService`].\n///\n/// [`MakeService`]: tower::make::MakeService\npub trait HandlerWithoutStateExt<T>: Handler<T, ()> {\n    /// Convert the handler into a [`Service`] and no state.\n    fn into_service(self) -> HandlerService<Self, T, ()>;\n\n    /// Convert the handler into a [`MakeService`] and no state.\n    ///\n    /// See [`HandlerService::into_make_service`] for more details.\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    fn into_make_service(self) -> IntoMakeService<HandlerService<Self, T, ()>>;\n\n    /// Convert the handler into a [`MakeService`] which stores information\n    /// about the incoming connection and has no state.\n    ///\n    /// See [`HandlerService::into_make_service_with_connect_info`] for more details.\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    #[cfg(feature = \"tokio\")]\n    fn into_make_service_with_connect_info<C>(\n        self,\n    ) -> IntoMakeServiceWithConnectInfo<HandlerService<Self, T, ()>, C>;\n}\n\nimpl<H, T> HandlerWithoutStateExt<T> for H\nwhere\n    H: Handler<T, ()>,\n{\n    fn into_service(self) -> HandlerService<Self, T, ()> {\n        self.with_state(())\n    }\n\n    fn into_make_service(self) -> IntoMakeService<HandlerService<Self, T, ()>> {\n        self.into_service().into_make_service()\n    }\n\n    #[cfg(feature = \"tokio\")]\n    fn into_make_service_with_connect_info<C>(\n        self,\n    ) -> IntoMakeServiceWithConnectInfo<HandlerService<Self, T, ()>, C> {\n        self.into_service().into_make_service_with_connect_info()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{extract::State, test_helpers::*};\n    use axum_core::body::Body;\n    use http::StatusCode;\n    use std::time::Duration;\n    use tower_http::{\n        limit::RequestBodyLimitLayer, map_request_body::MapRequestBodyLayer,\n        map_response_body::MapResponseBodyLayer, timeout::TimeoutLayer,\n    };\n\n    #[crate::test]\n    async fn handler_into_service() {\n        async fn handle(body: String) -> impl IntoResponse {\n            format!(\"you said: {body}\")\n        }\n\n        let client = TestClient::new(handle.into_service());\n\n        let res = client.post(\"/\").body(\"hi there!\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"you said: hi there!\");\n    }\n\n    #[crate::test]\n    async fn with_layer_that_changes_request_body_and_state() {\n        async fn handle(State(state): State<&'static str>) -> &'static str {\n            state\n        }\n\n        let svc = handle\n            .layer((\n                RequestBodyLimitLayer::new(1024),\n                TimeoutLayer::with_status_code(\n                    StatusCode::REQUEST_TIMEOUT,\n                    Duration::from_secs(10),\n                ),\n                MapResponseBodyLayer::new(Body::new),\n            ))\n            .layer(MapRequestBodyLayer::new(Body::new))\n            .with_state(\"foo\");\n\n        let client = TestClient::new(svc);\n        let res = client.get(\"/\").await;\n        assert_eq!(res.text().await, \"foo\");\n    }\n}\n"
  },
  {
    "path": "axum/src/handler/service.rs",
    "content": "use super::Handler;\nuse crate::body::{Body, Bytes, HttpBody};\n#[cfg(feature = \"tokio\")]\nuse crate::extract::connect_info::IntoMakeServiceWithConnectInfo;\nuse crate::response::Response;\nuse crate::routing::IntoMakeService;\nuse crate::BoxError;\nuse http::Request;\nuse std::{\n    convert::Infallible,\n    fmt,\n    marker::PhantomData,\n    task::{Context, Poll},\n};\nuse tower_service::Service;\n\n/// An adapter that makes a [`Handler`] into a [`Service`].\n///\n/// Created with [`Handler::with_state`] or [`HandlerWithoutStateExt::into_service`].\n///\n/// [`HandlerWithoutStateExt::into_service`]: super::HandlerWithoutStateExt::into_service\npub struct HandlerService<H, T, S> {\n    handler: H,\n    state: S,\n    _marker: PhantomData<fn() -> T>,\n}\n\nimpl<H, T, S> HandlerService<H, T, S> {\n    /// Get a reference to the state.\n    pub fn state(&self) -> &S {\n        &self.state\n    }\n\n    /// Convert the handler into a [`MakeService`].\n    ///\n    /// This allows you to serve a single handler if you don't need any routing:\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     handler::Handler,\n    ///     extract::State,\n    ///     http::{Uri, Method},\n    ///     response::IntoResponse,\n    /// };\n    /// use std::net::SocketAddr;\n    ///\n    /// #[derive(Clone)]\n    /// struct AppState {}\n    ///\n    /// async fn handler(State(state): State<AppState>) {\n    ///     // ...\n    /// }\n    ///\n    /// let app = handler.with_state(AppState {});\n    ///\n    /// # async {\n    /// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    /// axum::serve(listener, app.into_make_service()).await;\n    /// # };\n    /// ```\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    pub fn into_make_service(self) -> IntoMakeService<Self> {\n        IntoMakeService::new(self)\n    }\n\n    /// Convert the handler into a [`MakeService`] which stores information\n    /// about the incoming connection.\n    ///\n    /// See [`Router::into_make_service_with_connect_info`] for more details.\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     handler::Handler,\n    ///     response::IntoResponse,\n    ///     extract::{ConnectInfo, State},\n    /// };\n    /// use std::net::SocketAddr;\n    ///\n    /// #[derive(Clone)]\n    /// struct AppState {};\n    ///\n    /// async fn handler(\n    ///     ConnectInfo(addr): ConnectInfo<SocketAddr>,\n    ///     State(state): State<AppState>,\n    /// ) -> String {\n    ///     format!(\"Hello {addr}\")\n    /// }\n    ///\n    /// let app = handler.with_state(AppState {});\n    ///\n    /// # async {\n    /// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    /// axum::serve(\n    ///     listener,\n    ///     app.into_make_service_with_connect_info::<SocketAddr>(),\n    /// ).await;\n    /// # };\n    /// ```\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    /// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info\n    #[cfg(feature = \"tokio\")]\n    pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {\n        IntoMakeServiceWithConnectInfo::new(self)\n    }\n}\n\n#[test]\nfn traits() {\n    use crate::test_helpers::*;\n    assert_send::<HandlerService<(), NotSendSync, ()>>();\n    assert_sync::<HandlerService<(), NotSendSync, ()>>();\n}\n\nimpl<H, T, S> HandlerService<H, T, S> {\n    pub(super) fn new(handler: H, state: S) -> Self {\n        Self {\n            handler,\n            state,\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl<H, T, S> fmt::Debug for HandlerService<H, T, S> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"IntoService\").finish_non_exhaustive()\n    }\n}\n\nimpl<H, T, S> Clone for HandlerService<H, T, S>\nwhere\n    H: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            handler: self.handler.clone(),\n            state: self.state.clone(),\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl<H, T, S, B> Service<Request<B>> for HandlerService<H, T, S>\nwhere\n    H: Handler<T, S> + Clone + Send + 'static,\n    B: HttpBody<Data = Bytes> + Send + 'static,\n    B::Error: Into<BoxError>,\n    S: Clone + Send + Sync,\n{\n    type Response = Response;\n    type Error = Infallible;\n    type Future = super::future::IntoServiceFuture<H::Future>;\n\n    #[inline]\n    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        // `IntoService` can only be constructed from async functions which are always ready, or\n        // from `Layered` which buffers in `<Layered as Handler>::call` and is therefore\n        // also always ready.\n        Poll::Ready(Ok(()))\n    }\n\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        use futures_util::future::FutureExt;\n\n        let req = req.map(Body::new);\n\n        let handler = self.handler.clone();\n        let future = Handler::call(handler, req, self.state.clone());\n        let future = future.map(Ok as _);\n\n        super::future::IntoServiceFuture::new(future)\n    }\n}\n\n// for `axum::serve(listener, handler)`\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nconst _: () = {\n    use crate::serve;\n\n    impl<H, T, S, L> Service<serve::IncomingStream<'_, L>> for HandlerService<H, T, S>\n    where\n        H: Clone,\n        S: Clone,\n        L: serve::Listener,\n    {\n        type Response = Self;\n        type Error = Infallible;\n        type Future = std::future::Ready<Result<Self::Response, Self::Error>>;\n\n        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n            Poll::Ready(Ok(()))\n        }\n\n        fn call(&mut self, _req: serve::IncomingStream<'_, L>) -> Self::Future {\n            std::future::ready(Ok(self.clone()))\n        }\n    }\n};\n"
  },
  {
    "path": "axum/src/json.rs",
    "content": "use crate::extract::Request;\nuse crate::extract::{rejection::*, FromRequest};\nuse axum_core::extract::OptionalFromRequest;\nuse axum_core::response::{IntoResponse, IntoResponseFailed, Response};\nuse bytes::{BufMut, Bytes, BytesMut};\nuse http::{\n    header::{self, HeaderMap, HeaderValue},\n    StatusCode,\n};\nuse serde_core::{de::DeserializeOwned, Serialize};\n\n/// JSON Extractor / Response.\n///\n/// When used as an extractor, it can deserialize request bodies into some type that\n/// implements [`serde::de::DeserializeOwned`]. The request will be rejected (and a [`JsonRejection`] will\n/// be returned) if:\n///\n/// - The request doesn't have a `Content-Type: application/json` (or similar) header.\n/// - The body doesn't contain syntactically valid JSON.\n/// - The body contains syntactically valid JSON, but it couldn't be deserialized into the target type.\n/// - Buffering the request body fails.\n///\n/// ⚠️ Since parsing JSON requires consuming the request body, the `Json` extractor must be\n/// *last* if there are multiple extractors in a handler.\n/// See [\"the order of extractors\"][order-of-extractors]\n///\n/// [order-of-extractors]: crate::extract#the-order-of-extractors\n///\n/// See [`JsonRejection`] for more details.\n///\n/// # Extractor example\n///\n/// ```rust,no_run\n/// use axum::{\n///     extract,\n///     routing::post,\n///     Router,\n/// };\n/// use serde::Deserialize;\n///\n/// #[derive(Deserialize)]\n/// struct CreateUser {\n///     email: String,\n///     password: String,\n/// }\n///\n/// async fn create_user(extract::Json(payload): extract::Json<CreateUser>) {\n///     // payload is a `CreateUser`\n/// }\n///\n/// let app = Router::new().route(\"/users\", post(create_user));\n/// # let _: Router = app;\n/// ```\n///\n/// When used as a response, it can serialize any type that implements [`serde::Serialize`] to\n/// `JSON`, and will automatically set `Content-Type: application/json` header.\n///\n/// If the [`Serialize`] implementation decides to fail\n/// or if a map with non-string keys is used,\n/// a 500 response will be issued\n/// whose body is the error message in UTF-8.\n///\n/// # Response example\n///\n/// ```\n/// use axum::{\n///     extract::Path,\n///     routing::get,\n///     Router,\n///     Json,\n/// };\n/// use serde::Serialize;\n/// use uuid::Uuid;\n///\n/// #[derive(Serialize)]\n/// struct User {\n///     id: Uuid,\n///     username: String,\n/// }\n///\n/// async fn get_user(Path(user_id) : Path<Uuid>) -> Json<User> {\n///     let user = find_user(user_id).await;\n///     Json(user)\n/// }\n///\n/// async fn find_user(user_id: Uuid) -> User {\n///     // ...\n///     # unimplemented!()\n/// }\n///\n/// let app = Router::new().route(\"/users/{id}\", get(get_user));\n/// # let _: Router = app;\n/// ```\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(docsrs, doc(cfg(feature = \"json\")))]\n#[must_use]\npub struct Json<T>(pub T);\n\nimpl<T, S> FromRequest<S> for Json<T>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = JsonRejection;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        if !json_content_type(req.headers()) {\n            return Err(MissingJsonContentType.into());\n        }\n\n        let bytes = Bytes::from_request(req, state).await?;\n        Self::from_bytes(&bytes)\n    }\n}\n\nimpl<T, S> OptionalFromRequest<S> for Json<T>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = JsonRejection;\n\n    async fn from_request(req: Request, state: &S) -> Result<Option<Self>, Self::Rejection> {\n        let headers = req.headers();\n        if headers.get(header::CONTENT_TYPE).is_some() {\n            if json_content_type(headers) {\n                let bytes = Bytes::from_request(req, state).await?;\n                Ok(Some(Self::from_bytes(&bytes)?))\n            } else {\n                Err(MissingJsonContentType.into())\n            }\n        } else {\n            Ok(None)\n        }\n    }\n}\n\nfn json_content_type(headers: &HeaderMap) -> bool {\n    headers\n        .get(header::CONTENT_TYPE)\n        .and_then(|content_type| content_type.to_str().ok())\n        .and_then(|content_type| content_type.parse::<mime::Mime>().ok())\n        .is_some_and(|mime| {\n            mime.type_() == \"application\"\n                && (mime.subtype() == \"json\" || mime.suffix().is_some_and(|name| name == \"json\"))\n        })\n}\n\naxum_core::__impl_deref!(Json);\n\nimpl<T> From<T> for Json<T> {\n    fn from(inner: T) -> Self {\n        Self(inner)\n    }\n}\n\nimpl<T> Json<T>\nwhere\n    T: DeserializeOwned,\n{\n    /// Construct a `Json<T>` from a byte slice. Most users should prefer to use the `FromRequest` impl\n    /// but special cases may require first extracting a `Request` into `Bytes` then optionally\n    /// constructing a `Json<T>`.\n    pub fn from_bytes(bytes: &[u8]) -> Result<Self, JsonRejection> {\n        // Extracted into separate fn so it's only compiled once for all T.\n        fn make_rejection(err: serde_path_to_error::Error<serde_json::Error>) -> JsonRejection {\n            match err.inner().classify() {\n                serde_json::error::Category::Data => JsonDataError::from_err(err).into(),\n                serde_json::error::Category::Syntax | serde_json::error::Category::Eof => {\n                    JsonSyntaxError::from_err(err).into()\n                }\n                serde_json::error::Category::Io => {\n                    if cfg!(debug_assertions) {\n                        // we don't use `serde_json::from_reader` and instead always buffer\n                        // bodies first, so we shouldn't encounter any IO errors\n                        unreachable!()\n                    } else {\n                        JsonSyntaxError::from_err(err).into()\n                    }\n                }\n            }\n        }\n\n        let mut deserializer = serde_json::Deserializer::from_slice(bytes);\n\n        serde_path_to_error::deserialize(&mut deserializer)\n            .map_err(make_rejection)\n            .and_then(|value| {\n                deserializer\n                    .end()\n                    .map(|()| Self(value))\n                    .map_err(|err| JsonSyntaxError::from_err(err).into())\n            })\n    }\n}\n\nimpl<T> IntoResponse for Json<T>\nwhere\n    T: Serialize,\n{\n    fn into_response(self) -> Response {\n        // Extracted into separate fn so it's only compiled once for all T.\n        fn make_response(buf: BytesMut, ser_result: serde_json::Result<()>) -> Response {\n            match ser_result {\n                Ok(()) => (\n                    [(\n                        header::CONTENT_TYPE,\n                        HeaderValue::from_static(mime::APPLICATION_JSON.as_ref()),\n                    )],\n                    buf.freeze(),\n                )\n                    .into_response(),\n                Err(err) => (\n                    StatusCode::INTERNAL_SERVER_ERROR,\n                    [(\n                        header::CONTENT_TYPE,\n                        HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),\n                    )],\n                    IntoResponseFailed,\n                    err.to_string(),\n                )\n                    .into_response(),\n            }\n        }\n\n        // Use a small initial capacity of 128 bytes like serde_json::to_vec\n        // https://docs.rs/serde_json/1.0.82/src/serde_json/ser.rs.html#2189\n        let mut buf = BytesMut::with_capacity(128).writer();\n        let res = serde_json::to_writer(&mut buf, &self.0);\n        make_response(buf.into_inner(), res)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{routing::post, test_helpers::*, Router};\n    use serde::Deserialize;\n    use serde_json::{json, Value};\n\n    #[crate::test]\n    async fn deserialize_body() {\n        #[derive(Debug, Deserialize)]\n        struct Input {\n            foo: String,\n        }\n\n        let app = Router::new().route(\"/\", post(|input: Json<Input>| async { input.0.foo }));\n\n        let client = TestClient::new(app);\n        let res = client.post(\"/\").json(&json!({ \"foo\": \"bar\" })).await;\n        let body = res.text().await;\n\n        assert_eq!(body, \"bar\");\n    }\n\n    #[crate::test]\n    async fn consume_body_to_json_requires_json_content_type() {\n        #[derive(Debug, Deserialize)]\n        struct Input {\n            foo: String,\n        }\n\n        let app = Router::new().route(\"/\", post(|input: Json<Input>| async { input.0.foo }));\n\n        let client = TestClient::new(app);\n        let res = client.post(\"/\").body(r#\"{ \"foo\": \"bar\" }\"#).await;\n\n        let status = res.status();\n\n        assert_eq!(status, StatusCode::UNSUPPORTED_MEDIA_TYPE);\n    }\n\n    #[crate::test]\n    async fn json_content_types() {\n        async fn valid_json_content_type(content_type: &str) -> bool {\n            println!(\"testing {content_type:?}\");\n\n            let app = Router::new().route(\"/\", post(|Json(_): Json<Value>| async {}));\n\n            let res = TestClient::new(app)\n                .post(\"/\")\n                .header(\"content-type\", content_type)\n                .body(\"{}\")\n                .await;\n\n            res.status() == StatusCode::OK\n        }\n\n        assert!(valid_json_content_type(\"application/json\").await);\n        assert!(valid_json_content_type(\"application/json; charset=utf-8\").await);\n        assert!(valid_json_content_type(\"application/json;charset=utf-8\").await);\n        assert!(valid_json_content_type(\"application/cloudevents+json\").await);\n        assert!(!valid_json_content_type(\"text/json\").await);\n    }\n\n    #[crate::test]\n    async fn invalid_json_syntax() {\n        let app = Router::new().route(\"/\", post(|_: Json<serde_json::Value>| async {}));\n\n        let client = TestClient::new(app);\n        let res = client\n            .post(\"/\")\n            .body(\"{\")\n            .header(\"content-type\", \"application/json\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n    }\n\n    #[crate::test]\n    async fn extra_chars_after_valid_json_syntax() {\n        #[derive(Debug, Deserialize)]\n        struct Input {\n            foo: String,\n        }\n\n        let app = Router::new().route(\"/\", post(|input: Json<Input>| async { input.0.foo }));\n\n        let client = TestClient::new(app);\n        let res = client\n            .post(\"/\")\n            .body(r#\"{ \"foo\": \"bar\" } baz \"#)\n            .header(\"content-type\", \"application/json\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n        let body_text = res.text().await;\n        assert_eq!(\n            body_text,\n            \"Failed to parse the request body as JSON: trailing characters at line 1 column 18\"\n        );\n    }\n\n    #[derive(Deserialize)]\n    struct Foo {\n        #[allow(dead_code)]\n        a: i32,\n        #[allow(dead_code)]\n        b: Vec<Bar>,\n    }\n\n    #[derive(Deserialize)]\n    struct Bar {\n        #[allow(dead_code)]\n        x: i32,\n        #[allow(dead_code)]\n        y: i32,\n    }\n\n    #[crate::test]\n    async fn invalid_json_data() {\n        let app = Router::new().route(\"/\", post(|_: Json<Foo>| async {}));\n\n        let client = TestClient::new(app);\n        let res = client\n            .post(\"/\")\n            .body(\"{\\\"a\\\": 1, \\\"b\\\": [{\\\"x\\\": 2}]}\")\n            .header(\"content-type\", \"application/json\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);\n        let body_text = res.text().await;\n        assert_eq!(\n            body_text,\n            \"Failed to deserialize the JSON body into the target type: b[0]: missing field `y` at line 1 column 23\"\n        );\n    }\n}\n"
  },
  {
    "path": "axum/src/lib.rs",
    "content": "//! axum is an HTTP routing and request-handling library that focuses on ergonomics and modularity.\n//!\n//! # High-level features\n//!\n//! - Route requests to handlers with a macro-free API.\n//! - Declaratively parse requests using extractors.\n//! - Simple and predictable error handling model.\n//! - Generate responses with minimal boilerplate.\n//! - Take full advantage of the [`tower`] and [`tower-http`] ecosystem of\n//!   middleware, services, and utilities.\n//!\n//! In particular, the last point is what sets `axum` apart from other libraries / frameworks.\n//! `axum` doesn't have its own middleware system but instead uses\n//! [`tower::Service`]. This means `axum` gets timeouts, tracing, compression,\n//! authorization, and more, for free. It also enables you to share middleware with\n//! applications written using [`hyper`] or [`tonic`].\n//!\n//! # Compatibility\n//!\n//! axum is designed to work with [tokio] and [hyper]. Runtime and\n//! transport layer independence is not a goal, at least for the time being.\n//!\n//! # Example\n//!\n//! The \"Hello, World!\" of axum is:\n//!\n//! ```rust,no_run\n//! use axum::{\n//!     routing::get,\n//!     Router,\n//! };\n//!\n//! #[tokio::main]\n//! async fn main() {\n//!     // build our application with a single route\n//!     let app = Router::new().route(\"/\", get(|| async { \"Hello, World!\" }));\n//!\n//!     // run our app with hyper, listening globally on port 3000\n//!     let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n//!     axum::serve(listener, app).await;\n//! }\n//! ```\n//!\n//! Note using `#[tokio::main]` requires you enable tokio's `macros` and `rt-multi-thread` features\n//! or just `full` to enable all features (`cargo add tokio --features macros,rt-multi-thread`).\n//!\n//! # Routing\n//!\n//! [`Router`] is used to set up which paths go to which services:\n//!\n//! ```rust\n//! use axum::{Router, routing::get};\n//!\n//! // our router\n//! let app = Router::new()\n//!     .route(\"/\", get(root))\n//!     .route(\"/foo\", get(get_foo).post(post_foo))\n//!     .route(\"/foo/bar\", get(foo_bar));\n//!\n//! // which calls one of these handlers\n//! async fn root() {}\n//! async fn get_foo() {}\n//! async fn post_foo() {}\n//! async fn foo_bar() {}\n//! # let _: Router = app;\n//! ```\n//!\n//! See [`Router`] for more details on routing.\n//!\n//! # Handlers\n//!\n#![doc = include_str!(\"docs/handlers_intro.md\")]\n//!\n//! See [`handler`](crate::handler) for more details on handlers.\n//!\n//! # Extractors\n//!\n//! An extractor is a type that implements [`FromRequest`] or [`FromRequestParts`]. Extractors are\n//! how you pick apart the incoming request to get the parts your handler needs.\n//!\n//! ```rust\n//! use axum::extract::{Path, Query, Json};\n//! use std::collections::HashMap;\n//!\n//! // `Path` gives you the path parameters and deserializes them.\n//! async fn path(Path(user_id): Path<u32>) {}\n//!\n//! // `Query` gives you the query parameters and deserializes them.\n//! async fn query(Query(params): Query<HashMap<String, String>>) {}\n//!\n//! // Buffer the request body and deserialize it as JSON into a\n//! // `serde_json::Value`. `Json` supports any type that implements\n//! // `serde::Deserialize`.\n//! async fn json(Json(payload): Json<serde_json::Value>) {}\n//! ```\n//!\n//! See [`extract`](crate::extract) for more details on extractors.\n//!\n//! # Responses\n//!\n//! Anything that implements [`IntoResponse`] can be returned from handlers.\n//!\n//! ```rust,no_run\n//! use axum::{\n//!     body::Body,\n//!     routing::get,\n//!     response::Json,\n//!     Router,\n//! };\n//! use serde_json::{Value, json};\n//!\n//! // `&'static str` becomes a `200 OK` with `content-type: text/plain; charset=utf-8`\n//! async fn plain_text() -> &'static str {\n//!     \"foo\"\n//! }\n//!\n//! // `Json` gives a content-type of `application/json` and works with any type\n//! // that implements `serde::Serialize`\n//! async fn json() -> Json<Value> {\n//!     Json(json!({ \"data\": 42 }))\n//! }\n//!\n//! let app = Router::new()\n//!     .route(\"/plain_text\", get(plain_text))\n//!     .route(\"/json\", get(json));\n//! # let _: Router = app;\n//! ```\n//!\n//! See [`response`](crate::response) for more details on building responses.\n//!\n//! # Error handling\n//!\n//! axum aims to have a simple and predictable error handling model. That means\n//! it is simple to convert errors into responses and you are guaranteed that\n//! all errors are handled.\n//!\n//! See [`error_handling`] for more details on axum's\n//! error handling model and how to handle errors gracefully.\n//!\n//! # Middleware\n//!\n//! There are several different ways to write middleware for axum. See\n//! [`middleware`] for more details.\n//!\n//! # Sharing state with handlers\n//!\n//! It is common to share some state between handlers. For example, a\n//! pool of database connections or clients to other services may need to\n//! be shared.\n//!\n//! The four most common ways of doing that are:\n//!\n//! - Using the [`State`] extractor\n//! - Using request extensions\n//! - Using closure captures\n//! - Using task-local variables\n//!\n//! ## Using the [`State`] extractor\n//!\n//! ```rust,no_run\n//! use axum::{\n//!     extract::State,\n//!     routing::get,\n//!     Router,\n//! };\n//! use std::sync::Arc;\n//!\n//! struct AppState {\n//!     // ...\n//! }\n//!\n//! let shared_state = Arc::new(AppState { /* ... */ });\n//!\n//! let app = Router::new()\n//!     .route(\"/\", get(handler))\n//!     .with_state(shared_state);\n//!\n//! async fn handler(\n//!     State(state): State<Arc<AppState>>,\n//! ) {\n//!     // ...\n//! }\n//! # let _: Router = app;\n//! ```\n//!\n//! You should prefer using [`State`] if possible since it's more type safe. The downside is that\n//! it's less dynamic than task-local variables and request extensions.\n//!\n//! See [`State`] for more details about accessing state.\n//!\n//! ## Using request extensions\n//!\n//! Another way to share state with handlers is using [`Extension`] as\n//! layer and extractor:\n//!\n//! ```rust,no_run\n//! use axum::{\n//!     extract::Extension,\n//!     routing::get,\n//!     Router,\n//! };\n//! use std::sync::Arc;\n//!\n//! struct AppState {\n//!     // ...\n//! }\n//!\n//! let shared_state = Arc::new(AppState { /* ... */ });\n//!\n//! let app = Router::new()\n//!     .route(\"/\", get(handler))\n//!     .layer(Extension(shared_state));\n//!\n//! async fn handler(\n//!     Extension(state): Extension<Arc<AppState>>,\n//! ) {\n//!     // ...\n//! }\n//! # let _: Router = app;\n//! ```\n//!\n//! The downside to this approach is that you'll get runtime errors\n//! (specifically a `500 Internal Server Error` response) if you try and extract\n//! an extension that doesn't exist, perhaps because you forgot to add the\n//! middleware or because you're extracting the wrong type.\n//!\n//! ## Using closure captures\n//!\n//! State can also be passed directly to handlers using closure captures:\n//!\n//! ```rust,no_run\n//! use axum::{\n//!     Json,\n//!     extract::{Extension, Path},\n//!     routing::{get, post},\n//!     Router,\n//! };\n//! use std::sync::Arc;\n//! use serde::Deserialize;\n//!\n//! struct AppState {\n//!     // ...\n//! }\n//!\n//! let shared_state = Arc::new(AppState { /* ... */ });\n//!\n//! let app = Router::new()\n//!     .route(\n//!         \"/users\",\n//!         post({\n//!             let shared_state = Arc::clone(&shared_state);\n//!             move |body| create_user(body, shared_state)\n//!         }),\n//!     )\n//!     .route(\n//!         \"/users/{id}\",\n//!         get({\n//!             let shared_state = Arc::clone(&shared_state);\n//!             move |path| get_user(path, shared_state)\n//!         }),\n//!     );\n//!\n//! async fn get_user(Path(user_id): Path<String>, state: Arc<AppState>) {\n//!     // ...\n//! }\n//!\n//! async fn create_user(Json(payload): Json<CreateUserPayload>, state: Arc<AppState>) {\n//!     // ...\n//! }\n//!\n//! #[derive(Deserialize)]\n//! struct CreateUserPayload {\n//!     // ...\n//! }\n//! # let _: Router = app;\n//! ```\n//!\n//! The downside to this approach is that it's the most verbose approach.\n//!\n//! ## Using task-local variables\n//!\n//! This also allows to share state with `IntoResponse` implementations:\n//!\n//! ```rust,no_run\n//! use axum::{\n//!     extract::Request,\n//!     http::{header, StatusCode},\n//!     middleware::{self, Next},\n//!     response::{IntoResponse, Response},\n//!     routing::get,\n//!     Router,\n//! };\n//! use tokio::task_local;\n//!\n//! #[derive(Clone)]\n//! struct CurrentUser {\n//!     name: String,\n//! }\n//! task_local! {\n//!     pub static USER: CurrentUser;\n//! }\n//!\n//! async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {\n//!     let auth_header = req\n//!         .headers()\n//!         .get(header::AUTHORIZATION)\n//!         .and_then(|header| header.to_str().ok())\n//!         .ok_or(StatusCode::UNAUTHORIZED)?;\n//!     if let Some(current_user) = authorize_current_user(auth_header).await {\n//!         // State is setup here in the middleware\n//!         Ok(USER.scope(current_user, next.run(req)).await)\n//!     } else {\n//!         Err(StatusCode::UNAUTHORIZED)\n//!     }\n//! }\n//! async fn authorize_current_user(auth_token: &str) -> Option<CurrentUser> {\n//!     Some(CurrentUser {\n//!         name: auth_token.to_string(),\n//!     })\n//! }\n//!\n//! struct UserResponse;\n//!\n//! impl IntoResponse for UserResponse {\n//!     fn into_response(self) -> Response {\n//!         // State is accessed here in the IntoResponse implementation\n//!         let current_user = USER.with(|u| u.clone());\n//!         (StatusCode::OK, current_user.name).into_response()\n//!     }\n//! }\n//!\n//! async fn handler() -> UserResponse {\n//!     UserResponse\n//! }\n//!\n//! let app: Router = Router::new()\n//!     .route(\"/\", get(handler))\n//!     .route_layer(middleware::from_fn(auth));\n//! ```\n//!\n//! The main downside to this approach is that it only works when the async executor being used\n//! has the concept of task-local variables. The example above uses\n//! [tokio's `task_local` macro](https://docs.rs/tokio/1/tokio/macro.task_local.html).\n//! smol does not yet offer equivalent functionality at the time of writing (see\n//! [this GitHub issue](https://github.com/smol-rs/async-executor/issues/139)).\n//!\n//! # Building integrations for axum\n//!\n//! Libraries authors that want to provide [`FromRequest`], [`FromRequestParts`], or\n//! [`IntoResponse`] implementations should depend on the [`axum-core`] crate, instead of `axum` if\n//! possible. [`axum-core`] contains core types and traits and is less likely to receive breaking\n//! changes.\n//!\n//! # Required dependencies\n//!\n//! To use axum there are a few dependencies you have to pull in as well:\n//!\n//! ```toml\n//! [dependencies]\n//! axum = \"<latest-version>\"\n//! tokio = { version = \"<latest-version>\", features = [\"full\"] }\n//! tower = \"<latest-version>\"\n//! ```\n//!\n//! The `\"full\"` feature for tokio isn't necessary but it's the easiest way to get started.\n//!\n//! Tower isn't strictly necessary either but helpful for testing. See the\n//! testing example in the repo to learn more about testing axum apps.\n//!\n//! # Examples\n//!\n//! The axum repo contains [a number of examples][examples] that show how to put all the\n//! pieces together.\n//!\n//! # Feature flags\n//!\n//! axum uses a set of [feature flags] to reduce the amount of compiled and\n//! optional dependencies.\n//!\n//! The following optional features are available:\n//!\n//! Name | Description | Default?\n//! ---|---|---\n//! `http1` | Enables hyper's `http1` feature | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `http2` | Enables hyper's `http2` feature |\n//! `json` | Enables the [`Json`] type and some similar convenience functionality | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `macros` | Enables optional utility macros |\n//! `matched-path` | Enables capturing of every request's router path and the [`MatchedPath`] extractor | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `multipart` | Enables parsing `multipart/form-data` requests with [`Multipart`] |\n//! `original-uri` | Enables capturing of every request's original URI and the [`OriginalUri`] extractor | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `tokio` | Enables `tokio` as a dependency and `axum::serve`, `SSE` and `extract::connect_info` types. | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `tower-log` | Enables `tower`'s `log` feature | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `tracing` | Log rejections from built-in extractors | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `ws` | Enables WebSockets support via [`extract::ws`] |\n//! `form` | Enables the `Form` extractor | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `query` | Enables the `Query` extractor | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//!\n//! [`MatchedPath`]: crate::extract::MatchedPath\n//! [`Multipart`]: crate::extract::Multipart\n//! [`OriginalUri`]: crate::extract::OriginalUri\n//! [`tower`]: https://crates.io/crates/tower\n//! [`tower-http`]: https://crates.io/crates/tower-http\n//! [`tokio`]: http://crates.io/crates/tokio\n//! [`hyper`]: http://crates.io/crates/hyper\n//! [`tonic`]: http://crates.io/crates/tonic\n//! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html#the-features-section\n//! [`IntoResponse`]: crate::response::IntoResponse\n//! [`Timeout`]: tower::timeout::Timeout\n//! [examples]: https://github.com/tokio-rs/axum/tree/main/examples\n//! [`Router::merge`]: crate::routing::Router::merge\n//! [`Service`]: tower::Service\n//! [`Service::poll_ready`]: tower::Service::poll_ready\n//! [`Service`'s]: tower::Service\n//! [`tower::Service`]: tower::Service\n//! [tower-guides]: https://github.com/tower-rs/tower/tree/master/guides\n//! [`Uuid`]: https://docs.rs/uuid/latest/uuid/\n//! [`FromRequest`]: crate::extract::FromRequest\n//! [`FromRequestParts`]: crate::extract::FromRequestParts\n//! [`HeaderMap`]: http::header::HeaderMap\n//! [`Request`]: http::Request\n//! [customize-extractor-error]: https://github.com/tokio-rs/axum/blob/main/examples/customize-extractor-error/src/main.rs\n//! [axum-macros]: https://docs.rs/axum-macros\n//! [`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html\n//! [`Handler`]: crate::handler::Handler\n//! [`Infallible`]: std::convert::Infallible\n//! [load shed]: tower::load_shed\n//! [`axum-core`]: http://crates.io/crates/axum-core\n//! [`State`]: crate::extract::State\n\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(test, allow(clippy::float_cmp))]\n#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]\n\n#[macro_use]\npub(crate) mod macros;\n\nmod boxed;\nmod extension;\n#[cfg(feature = \"form\")]\nmod form;\n#[cfg(feature = \"json\")]\nmod json;\nmod service_ext;\nmod util;\n\npub mod body;\npub mod error_handling;\npub mod extract;\npub mod handler;\npub mod middleware;\npub mod response;\npub mod routing;\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\npub mod serve;\n\n#[cfg(any(test, feature = \"__private\"))]\n#[allow(missing_docs, missing_debug_implementations, clippy::print_stdout)]\n#[doc(hidden)]\npub mod test_helpers;\n\n#[doc(no_inline)]\npub use http;\n\n#[doc(inline)]\npub use self::extension::Extension;\n#[doc(inline)]\n#[cfg(feature = \"json\")]\npub use self::json::Json;\n#[doc(inline)]\npub use self::routing::Router;\n\n#[doc(inline)]\n#[cfg(feature = \"form\")]\npub use self::form::Form;\n\n#[doc(inline)]\npub use axum_core::{BoxError, Error, RequestExt, RequestPartsExt};\n\n#[cfg(feature = \"macros\")]\npub use axum_macros::{debug_handler, debug_middleware};\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\n#[doc(inline)]\npub use self::serve::serve;\n\npub use self::service_ext::ServiceExt;\n\n#[cfg(test)]\nuse axum_macros::__private_axum_test as test;\n"
  },
  {
    "path": "axum/src/macros.rs",
    "content": "//! Internal macros\n\nmacro_rules! opaque_future {\n    ($(#[$m:meta])* pub type $name:ident = $actual:ty;) => {\n        opaque_future! {\n            $(#[$m])*\n            pub type $name<> = $actual;\n        }\n    };\n\n    ($(#[$m:meta])* pub type $name:ident<$($param:ident),*> = $actual:ty;) => {\n        pin_project_lite::pin_project! {\n            $(#[$m])*\n            pub struct $name<$($param),*> {\n                #[pin] future: $actual,\n            }\n        }\n\n        impl<$($param),*> $name<$($param),*> {\n            pub(crate) fn new(future: $actual) -> Self {\n                Self { future }\n            }\n        }\n\n        impl<$($param),*> std::fmt::Debug for $name<$($param),*> {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                f.debug_struct(stringify!($name)).finish_non_exhaustive()\n            }\n        }\n\n        impl<$($param),*> std::future::Future for $name<$($param),*>\n        where\n            $actual: std::future::Future,\n        {\n            type Output = <$actual as std::future::Future>::Output;\n\n            #[inline]\n            fn poll(\n                self: std::pin::Pin<&mut Self>,\n                cx: &mut std::task::Context<'_>,\n            ) -> std::task::Poll<Self::Output> {\n                self.project().future.poll(cx)\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmacro_rules! all_the_tuples {\n    ($name:ident) => {\n        $name!([], T1);\n        $name!([T1], T2);\n        $name!([T1, T2], T3);\n        $name!([T1, T2, T3], T4);\n        $name!([T1, T2, T3, T4], T5);\n        $name!([T1, T2, T3, T4, T5], T6);\n        $name!([T1, T2, T3, T4, T5, T6], T7);\n        $name!([T1, T2, T3, T4, T5, T6, T7], T8);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8], T9);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9], T10);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], T11);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], T12);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], T13);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], T14);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], T15);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], T16);\n    };\n}\n\n#[cfg(feature = \"tracing\")]\n#[allow(unused_macros)]\nmacro_rules! trace {\n    ($($tt:tt)*) => {\n        tracing::trace!($($tt)*)\n    }\n}\n\n#[cfg(feature = \"tracing\")]\n#[allow(unused_macros)]\nmacro_rules! error {\n    ($($tt:tt)*) => {\n        tracing::error!($($tt)*)\n    };\n}\n\n#[cfg(not(feature = \"tracing\"))]\n#[allow(unused_macros)]\nmacro_rules! trace {\n    ($($tt:tt)*) => {};\n}\n\n#[cfg(not(feature = \"tracing\"))]\n#[allow(unused_macros)]\nmacro_rules! error {\n    ($($tt:tt)*) => {};\n}\n"
  },
  {
    "path": "axum/src/middleware/from_extractor.rs",
    "content": "use crate::{\n    extract::FromRequestParts,\n    response::{IntoResponse, Response},\n};\nuse futures_core::future::BoxFuture;\nuse http::Request;\nuse pin_project_lite::pin_project;\nuse std::{\n    fmt,\n    future::Future,\n    marker::PhantomData,\n    pin::Pin,\n    task::{ready, Context, Poll},\n};\nuse tower_layer::Layer;\nuse tower_service::Service;\n\n/// Create a middleware from an extractor.\n///\n/// If the extractor succeeds the value will be discarded and the inner service\n/// will be called. If the extractor fails the rejection will be returned and\n/// the inner service will _not_ be called.\n///\n/// This can be used to perform validation of requests if the validation doesn't\n/// produce any useful output, and run the extractor for several handlers\n/// without repeating it in the function signature.\n///\n/// Note that if the extractor consumes the request body, as `String` or\n/// [`Bytes`] does, an empty body will be left in its place. Thus won't be\n/// accessible to subsequent extractors or handlers.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     extract::FromRequestParts,\n///     middleware::from_extractor,\n///     routing::{get, post},\n///     Router,\n///     http::{header, StatusCode, request::Parts},\n/// };\n///\n/// // An extractor that performs authorization.\n/// struct RequireAuth;\n///\n/// impl<S> FromRequestParts<S> for RequireAuth\n/// where\n///     S: Send + Sync,\n/// {\n///     type Rejection = StatusCode;\n///\n///     async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n///         let auth_header = parts\n///             .headers\n///             .get(header::AUTHORIZATION)\n///             .and_then(|value| value.to_str().ok());\n///\n///         match auth_header {\n///             Some(auth_header) if token_is_valid(auth_header) => {\n///                 Ok(Self)\n///             }\n///             _ => Err(StatusCode::UNAUTHORIZED),\n///         }\n///     }\n/// }\n///\n/// fn token_is_valid(token: &str) -> bool {\n///     // ...\n///     # false\n/// }\n///\n/// async fn handler() {\n///     // If we get here the request has been authorized\n/// }\n///\n/// async fn other_handler() {\n///     // If we get here the request has been authorized\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(handler))\n///     .route(\"/foo\", post(other_handler))\n///     // The extractor will run before all routes\n///     .route_layer(from_extractor::<RequireAuth>());\n/// # let _: Router = app;\n/// ```\n///\n/// [`Bytes`]: bytes::Bytes\npub fn from_extractor<E>() -> FromExtractorLayer<E, ()> {\n    from_extractor_with_state(())\n}\n\n/// Create a middleware from an extractor with the given state.\n///\n/// See [`State`](crate::extract::State) for more details about accessing state.\npub fn from_extractor_with_state<E, S>(state: S) -> FromExtractorLayer<E, S> {\n    FromExtractorLayer {\n        state,\n        _marker: PhantomData,\n    }\n}\n\n/// [`Layer`] that applies [`FromExtractor`] that runs an extractor and\n/// discards the value.\n///\n/// See [`from_extractor`] for more details.\n///\n/// [`Layer`]: tower::Layer\n#[must_use]\npub struct FromExtractorLayer<E, S> {\n    state: S,\n    _marker: PhantomData<fn() -> E>,\n}\n\nimpl<E, S> Clone for FromExtractorLayer<E, S>\nwhere\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            state: self.state.clone(),\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl<E, S> fmt::Debug for FromExtractorLayer<E, S>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"FromExtractorLayer\")\n            .field(\"state\", &self.state)\n            .field(\"extractor\", &format_args!(\"{}\", std::any::type_name::<E>()))\n            .finish()\n    }\n}\n\nimpl<E, T, S> Layer<T> for FromExtractorLayer<E, S>\nwhere\n    S: Clone,\n{\n    type Service = FromExtractor<T, E, S>;\n\n    fn layer(&self, inner: T) -> Self::Service {\n        FromExtractor {\n            inner,\n            state: self.state.clone(),\n            _extractor: PhantomData,\n        }\n    }\n}\n\n/// Middleware that runs an extractor and discards the value.\n///\n/// See [`from_extractor`] for more details.\npub struct FromExtractor<T, E, S> {\n    inner: T,\n    state: S,\n    _extractor: PhantomData<fn() -> E>,\n}\n\n#[test]\nfn traits() {\n    use crate::test_helpers::*;\n    assert_send::<FromExtractor<(), NotSendSync, ()>>();\n    assert_sync::<FromExtractor<(), NotSendSync, ()>>();\n}\n\nimpl<T, E, S> Clone for FromExtractor<T, E, S>\nwhere\n    T: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            inner: self.inner.clone(),\n            state: self.state.clone(),\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<T, E, S> fmt::Debug for FromExtractor<T, E, S>\nwhere\n    T: fmt::Debug,\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"FromExtractor\")\n            .field(\"inner\", &self.inner)\n            .field(\"state\", &self.state)\n            .field(\"extractor\", &format_args!(\"{}\", std::any::type_name::<E>()))\n            .finish()\n    }\n}\n\nimpl<T, E, B, S> Service<Request<B>> for FromExtractor<T, E, S>\nwhere\n    E: FromRequestParts<S> + 'static,\n    B: Send + 'static,\n    T: Service<Request<B>> + Clone,\n    T::Response: IntoResponse,\n    S: Clone + Send + Sync + 'static,\n{\n    type Response = Response;\n    type Error = T::Error;\n    type Future = ResponseFuture<B, T, E, S>;\n\n    #[inline]\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        let state = self.state.clone();\n        let (mut parts, body) = req.into_parts();\n\n        let extract_future = Box::pin(async move {\n            let extracted = E::from_request_parts(&mut parts, &state).await;\n            let req = Request::from_parts(parts, body);\n            (req, extracted)\n        });\n\n        ResponseFuture {\n            state: State::Extracting {\n                future: extract_future,\n            },\n            svc: Some(self.inner.clone()),\n        }\n    }\n}\n\npin_project! {\n    /// Response future for [`FromExtractor`].\n    #[allow(missing_debug_implementations)]\n    pub struct ResponseFuture<B, T, E, S>\n    where\n        E: FromRequestParts<S>,\n        T: Service<Request<B>>,\n    {\n        #[pin]\n        state: State<B, T, E, S>,\n        svc: Option<T>,\n    }\n}\n\npin_project! {\n    #[project = StateProj]\n    enum State<B, T, E, S>\n    where\n        E: FromRequestParts<S>,\n        T: Service<Request<B>>,\n    {\n        Extracting {\n            future: BoxFuture<'static, (Request<B>, Result<E, E::Rejection>)>,\n        },\n        Call { #[pin] future: T::Future },\n    }\n}\n\nimpl<B, T, E, S> Future for ResponseFuture<B, T, E, S>\nwhere\n    E: FromRequestParts<S>,\n    T: Service<Request<B>>,\n    T::Response: IntoResponse,\n{\n    type Output = Result<Response, T::Error>;\n\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        loop {\n            let mut this = self.as_mut().project();\n\n            let new_state = match this.state.as_mut().project() {\n                StateProj::Extracting { future } => {\n                    let (req, extracted) = ready!(future.as_mut().poll(cx));\n\n                    match extracted {\n                        Ok(_) => {\n                            let mut svc = this.svc.take().expect(\"future polled after completion\");\n                            let future = svc.call(req);\n                            State::Call { future }\n                        }\n                        Err(err) => {\n                            let res = err.into_response();\n                            return Poll::Ready(Ok(res));\n                        }\n                    }\n                }\n                StateProj::Call { future } => {\n                    return future\n                        .poll(cx)\n                        .map(|result| result.map(IntoResponse::into_response));\n                }\n            };\n\n            this.state.set(new_state);\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{handler::Handler, routing::get, test_helpers::*, Router};\n    use axum_core::extract::FromRef;\n    use http::{header, request::Parts, StatusCode};\n    use tower_http::limit::RequestBodyLimitLayer;\n\n    #[crate::test]\n    async fn test_from_extractor() {\n        #[derive(Clone)]\n        struct Secret(&'static str);\n\n        struct RequireAuth;\n\n        impl<S> FromRequestParts<S> for RequireAuth\n        where\n            S: Send + Sync,\n            Secret: FromRef<S>,\n        {\n            type Rejection = StatusCode;\n\n            async fn from_request_parts(\n                parts: &mut Parts,\n                state: &S,\n            ) -> Result<Self, Self::Rejection> {\n                let Secret(secret) = Secret::from_ref(state);\n                if let Some(auth) = parts\n                    .headers\n                    .get(header::AUTHORIZATION)\n                    .and_then(|v| v.to_str().ok())\n                {\n                    if auth == secret {\n                        return Ok(Self);\n                    }\n                }\n\n                Err(StatusCode::UNAUTHORIZED)\n            }\n        }\n\n        async fn handler() {}\n\n        let state = Secret(\"secret\");\n        let app = Router::new().route(\n            \"/\",\n            get(handler.layer(from_extractor_with_state::<RequireAuth, _>(state))),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n        assert_eq!(res.status(), StatusCode::UNAUTHORIZED);\n\n        let res = client\n            .get(\"/\")\n            .header(http::header::AUTHORIZATION, \"secret\")\n            .await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    // just needs to compile\n    #[allow(dead_code)]\n    fn works_with_request_body_limit() {\n        struct MyExtractor;\n\n        impl<S> FromRequestParts<S> for MyExtractor\n        where\n            S: Send + Sync,\n        {\n            type Rejection = std::convert::Infallible;\n\n            async fn from_request_parts(\n                _parts: &mut Parts,\n                _state: &S,\n            ) -> Result<Self, Self::Rejection> {\n                unimplemented!()\n            }\n        }\n\n        let _: Router = Router::new()\n            .layer(from_extractor::<MyExtractor>())\n            .layer(RequestBodyLimitLayer::new(1));\n    }\n}\n"
  },
  {
    "path": "axum/src/middleware/from_fn.rs",
    "content": "use axum_core::extract::{FromRequest, FromRequestParts, Request};\nuse futures_core::future::BoxFuture;\nuse std::{\n    any::type_name,\n    convert::Infallible,\n    fmt,\n    future::Future,\n    marker::PhantomData,\n    pin::Pin,\n    task::{Context, Poll},\n};\nuse tower::util::BoxCloneSyncService;\nuse tower_layer::Layer;\nuse tower_service::Service;\n\nuse crate::{\n    response::{IntoResponse, Response},\n    util::MapIntoResponse,\n};\n\n/// Create a middleware from an async function.\n///\n/// `from_fn` requires the function given to\n///\n/// 1. Be an `async fn`.\n/// 2. Take zero or more [`FromRequestParts`] extractors.\n/// 3. Take exactly one [`FromRequest`] extractor as the second to last argument.\n/// 4. Take [`Next`](Next) as the last argument.\n/// 5. Return something that implements [`IntoResponse`].\n///\n/// Note that this function doesn't support extracting [`State`]. For that, use [`from_fn_with_state`].\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     http,\n///     routing::get,\n///     response::Response,\n///     middleware::{self, Next},\n///     extract::Request,\n/// };\n///\n/// async fn my_middleware(\n///     request: Request,\n///     next: Next,\n/// ) -> Response {\n///     // do something with `request`...\n///\n///     let response = next.run(request).await;\n///\n///     // do something with `response`...\n///\n///     response\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .layer(middleware::from_fn(my_middleware));\n/// # let app: Router = app;\n/// ```\n///\n/// # Running extractors\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     extract::Request,\n///     http::{StatusCode, HeaderMap},\n///     middleware::{self, Next},\n///     response::Response,\n///     routing::get,\n/// };\n///\n/// async fn auth(\n///     // run the `HeaderMap` extractor\n///     headers: HeaderMap,\n///     // you can also add more extractors here but the last\n///     // extractor must implement `FromRequest` which\n///     // `Request` does\n///     request: Request,\n///     next: Next,\n/// ) -> Result<Response, StatusCode> {\n///     match get_token(&headers) {\n///         Some(token) if token_is_valid(token) => {\n///             let response = next.run(request).await;\n///             Ok(response)\n///         }\n///         _ => {\n///             Err(StatusCode::UNAUTHORIZED)\n///         }\n///     }\n/// }\n///\n/// fn get_token(headers: &HeaderMap) -> Option<&str> {\n///     // ...\n///     # None\n/// }\n///\n/// fn token_is_valid(token: &str) -> bool {\n///     // ...\n///     # false\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .route_layer(middleware::from_fn(auth));\n/// # let app: Router = app;\n/// ```\n///\n/// [extractors]: crate::extract::FromRequest\n/// [`State`]: crate::extract::State\npub fn from_fn<F, T>(f: F) -> FromFnLayer<F, (), T> {\n    from_fn_with_state((), f)\n}\n\n/// Create a middleware from an async function with the given state.\n///\n/// For the requirements for the function supplied see [`from_fn`].\n///\n/// See [`State`](crate::extract::State) for more details about accessing state.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     http::StatusCode,\n///     routing::get,\n///     response::{IntoResponse, Response},\n///     middleware::{self, Next},\n///     extract::{Request, State},\n/// };\n///\n/// #[derive(Clone)]\n/// struct AppState { /* ... */ }\n///\n/// async fn my_middleware(\n///     State(state): State<AppState>,\n///     // you can add more extractors here but the last\n///     // extractor must implement `FromRequest` which\n///     // `Request` does\n///     request: Request,\n///     next: Next,\n/// ) -> Response {\n///     // do something with `request`...\n///\n///     let response = next.run(request).await;\n///\n///     // do something with `response`...\n///\n///     response\n/// }\n///\n/// let state = AppState { /* ... */ };\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .route_layer(middleware::from_fn_with_state(state.clone(), my_middleware))\n///     .with_state(state);\n/// # let _: axum::Router = app;\n/// ```\npub fn from_fn_with_state<F, S, T>(state: S, f: F) -> FromFnLayer<F, S, T> {\n    FromFnLayer {\n        f,\n        state,\n        _extractor: PhantomData,\n    }\n}\n\n/// A [`tower::Layer`] from an async function.\n///\n/// [`tower::Layer`] is used to apply middleware to [`Router`](crate::Router)'s.\n///\n/// Created with [`from_fn`] or [`from_fn_with_state`]. See those functions for more details.\n#[must_use]\npub struct FromFnLayer<F, S, T> {\n    f: F,\n    state: S,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<F, S, T> Clone for FromFnLayer<F, S, T>\nwhere\n    F: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            f: self.f.clone(),\n            state: self.state.clone(),\n            _extractor: self._extractor,\n        }\n    }\n}\n\nimpl<S, I, F, T> Layer<I> for FromFnLayer<F, S, T>\nwhere\n    F: Clone,\n    S: Clone,\n{\n    type Service = FromFn<F, S, I, T>;\n\n    fn layer(&self, inner: I) -> Self::Service {\n        FromFn {\n            f: self.f.clone(),\n            state: self.state.clone(),\n            inner,\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<F, S, T> fmt::Debug for FromFnLayer<F, S, T>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"FromFnLayer\")\n            // Write out the type name, without quoting it as `&type_name::<F>()` would\n            .field(\"f\", &format_args!(\"{}\", type_name::<F>()))\n            .field(\"state\", &self.state)\n            .finish()\n    }\n}\n\n/// A middleware created from an async function.\n///\n/// Created with [`from_fn`] or [`from_fn_with_state`]. See those functions for more details.\npub struct FromFn<F, S, I, T> {\n    f: F,\n    inner: I,\n    state: S,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<F, S, I, T> Clone for FromFn<F, S, I, T>\nwhere\n    F: Clone,\n    I: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            f: self.f.clone(),\n            inner: self.inner.clone(),\n            state: self.state.clone(),\n            _extractor: self._extractor,\n        }\n    }\n}\n\nmacro_rules! impl_service {\n    (\n        [$($ty:ident),*], $last:ident\n    ) => {\n        #[allow(non_snake_case, unused_mut)]\n        impl<F, Fut, Out, S, I, $($ty,)* $last> Service<Request> for FromFn<F, S, I, ($($ty,)* $last,)>\n        where\n            F: FnMut($($ty,)* $last, Next) -> Fut + Clone + Send + 'static,\n            $( $ty: FromRequestParts<S> + Send, )*\n            $last: FromRequest<S> + Send,\n            Fut: Future<Output = Out> + Send + 'static,\n            Out: IntoResponse + 'static,\n            I: Service<Request, Error = Infallible>\n                + Clone\n                + Send\n                + Sync\n                + 'static,\n            I::Response: IntoResponse,\n            I::Future: Send + 'static,\n            S: Clone + Send + Sync + 'static,\n        {\n            type Response = Response;\n            type Error = Infallible;\n            type Future = ResponseFuture;\n\n            fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n                self.inner.poll_ready(cx)\n            }\n\n            fn call(&mut self, req: Request) -> Self::Future {\n                let not_ready_inner = self.inner.clone();\n                let ready_inner = std::mem::replace(&mut self.inner, not_ready_inner);\n\n                let mut f = self.f.clone();\n                let state = self.state.clone();\n                let (mut parts, body) = req.into_parts();\n\n                let future = Box::pin(async move {\n                    $(\n                        let $ty = match $ty::from_request_parts(&mut parts, &state).await {\n                            Ok(value) => value,\n                            Err(rejection) => return rejection.into_response(),\n                        };\n                    )*\n\n                    let req = Request::from_parts(parts, body);\n\n                    let $last = match $last::from_request(req, &state).await {\n                        Ok(value) => value,\n                        Err(rejection) => return rejection.into_response(),\n                    };\n\n                    let inner = BoxCloneSyncService::new(MapIntoResponse::new(ready_inner));\n                    let next = Next { inner };\n\n                    f($($ty,)* $last, next).await.into_response()\n                });\n\n                ResponseFuture {\n                    inner: future\n                }\n            }\n        }\n    };\n}\n\nall_the_tuples!(impl_service);\n\nimpl<F, S, I, T> fmt::Debug for FromFn<F, S, I, T>\nwhere\n    S: fmt::Debug,\n    I: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"FromFnLayer\")\n            .field(\"f\", &format_args!(\"{}\", type_name::<F>()))\n            .field(\"inner\", &self.inner)\n            .field(\"state\", &self.state)\n            .finish()\n    }\n}\n\n/// The remainder of a middleware stack, including the handler.\n#[derive(Debug, Clone)]\npub struct Next {\n    inner: BoxCloneSyncService<Request, Response, Infallible>,\n}\n\nimpl Next {\n    /// Execute the remaining middleware stack.\n    pub async fn run(mut self, req: Request) -> Response {\n        match self.inner.call(req).await {\n            Ok(res) => res,\n            Err(err) => match err {},\n        }\n    }\n}\n\nimpl Service<Request> for Next {\n    type Response = Response;\n    type Error = Infallible;\n    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;\n\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, req: Request) -> Self::Future {\n        self.inner.call(req)\n    }\n}\n\n/// Response future for [`FromFn`].\npub struct ResponseFuture {\n    inner: BoxFuture<'static, Response>,\n}\n\nimpl Future for ResponseFuture {\n    type Output = Result<Response, Infallible>;\n\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.inner.as_mut().poll(cx).map(Ok)\n    }\n}\n\nimpl fmt::Debug for ResponseFuture {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"ResponseFuture\").finish()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{body::Body, routing::get, Router};\n    use http::{HeaderMap, StatusCode};\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    #[crate::test]\n    async fn basic() {\n        async fn insert_header(mut req: Request, next: Next) -> impl IntoResponse {\n            req.headers_mut()\n                .insert(\"x-axum-test\", \"ok\".parse().unwrap());\n\n            next.run(req).await\n        }\n\n        async fn handle(headers: HeaderMap) -> String {\n            headers[\"x-axum-test\"].to_str().unwrap().to_owned()\n        }\n\n        let app = Router::new()\n            .route(\"/\", get(handle))\n            .layer(from_fn(insert_header));\n\n        let res = app\n            .oneshot(Request::builder().uri(\"/\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n        assert_eq!(res.status(), StatusCode::OK);\n        let body = res.collect().await.unwrap().to_bytes();\n        assert_eq!(&body[..], b\"ok\");\n    }\n}\n"
  },
  {
    "path": "axum/src/middleware/map_request.rs",
    "content": "use crate::body::{Body, Bytes, HttpBody};\nuse crate::response::{IntoResponse, Response};\nuse crate::BoxError;\nuse axum_core::extract::{FromRequest, FromRequestParts};\nuse futures_core::future::BoxFuture;\nuse http::Request;\nuse std::{\n    any::type_name,\n    convert::Infallible,\n    fmt,\n    future::Future,\n    marker::PhantomData,\n    pin::Pin,\n    task::{Context, Poll},\n};\nuse tower_layer::Layer;\nuse tower_service::Service;\n\n/// Create a middleware from an async function that transforms a request.\n///\n/// This differs from [`tower::util::MapRequest`] in that it allows you to easily run axum-specific\n/// extractors.\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::get,\n///     middleware::map_request,\n///     http::Request,\n/// };\n///\n/// async fn set_header<B>(mut request: Request<B>) -> Request<B> {\n///     request.headers_mut().insert(\"x-foo\", \"foo\".parse().unwrap());\n///     request\n/// }\n///\n/// async fn handler<B>(request: Request<B>) {\n///     // `request` will have an `x-foo` header\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(handler))\n///     .layer(map_request(set_header));\n/// # let _: Router = app;\n/// ```\n///\n/// # Rejecting the request\n///\n/// The function given to `map_request` is allowed to also return a `Result` which can be used to\n/// reject the request and return a response immediately, without calling the remaining\n/// middleware.\n///\n/// Specifically the valid return types are:\n///\n/// - `Request<B>`\n/// - `Result<Request<B>, E> where E:  IntoResponse`\n///\n/// ```\n/// use axum::{\n///     Router,\n///     http::{Request, StatusCode},\n///     routing::get,\n///     middleware::map_request,\n/// };\n///\n/// async fn auth<B>(request: Request<B>) -> Result<Request<B>, StatusCode> {\n///     let auth_header = request.headers()\n///         .get(http::header::AUTHORIZATION)\n///         .and_then(|header| header.to_str().ok());\n///\n///     match auth_header {\n///         Some(auth_header) if token_is_valid(auth_header) => Ok(request),\n///         _ => Err(StatusCode::UNAUTHORIZED),\n///     }\n/// }\n///\n/// fn token_is_valid(token: &str) -> bool {\n///     // ...\n///     # false\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .route_layer(map_request(auth));\n/// # let app: Router = app;\n/// ```\n///\n/// # Running extractors\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::get,\n///     middleware::map_request,\n///     extract::Path,\n///     http::Request,\n/// };\n/// use std::collections::HashMap;\n///\n/// async fn log_path_params<B>(\n///     Path(path_params): Path<HashMap<String, String>>,\n///     request: Request<B>,\n/// ) -> Request<B> {\n///     tracing::debug!(?path_params);\n///     request\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .layer(map_request(log_path_params));\n/// # let _: Router = app;\n/// ```\n///\n/// Note that to access state you must use either [`map_request_with_state`].\npub fn map_request<F, T>(f: F) -> MapRequestLayer<F, (), T> {\n    map_request_with_state((), f)\n}\n\n/// Create a middleware from an async function that transforms a request, with the given state.\n///\n/// See [`State`](crate::extract::State) for more details about accessing state.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     http::{Request, StatusCode},\n///     routing::get,\n///     response::IntoResponse,\n///     middleware::map_request_with_state,\n///     extract::State,\n/// };\n///\n/// #[derive(Clone)]\n/// struct AppState { /* ... */ }\n///\n/// async fn my_middleware<B>(\n///     State(state): State<AppState>,\n///     // you can add more extractors here but the last\n///     // extractor must implement `FromRequest` which\n///     // `Request` does\n///     request: Request<B>,\n/// ) -> Request<B> {\n///     // do something with `state` and `request`...\n///     request\n/// }\n///\n/// let state = AppState { /* ... */ };\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .route_layer(map_request_with_state(state.clone(), my_middleware))\n///     .with_state(state);\n/// # let _: axum::Router = app;\n/// ```\npub fn map_request_with_state<F, S, T>(state: S, f: F) -> MapRequestLayer<F, S, T> {\n    MapRequestLayer {\n        f,\n        state,\n        _extractor: PhantomData,\n    }\n}\n\n/// A [`tower::Layer`] from an async function that transforms a request.\n///\n/// Created with [`map_request`]. See that function for more details.\n#[must_use]\npub struct MapRequestLayer<F, S, T> {\n    f: F,\n    state: S,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<F, S, T> Clone for MapRequestLayer<F, S, T>\nwhere\n    F: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            f: self.f.clone(),\n            state: self.state.clone(),\n            _extractor: self._extractor,\n        }\n    }\n}\n\nimpl<S, I, F, T> Layer<I> for MapRequestLayer<F, S, T>\nwhere\n    F: Clone,\n    S: Clone,\n{\n    type Service = MapRequest<F, S, I, T>;\n\n    fn layer(&self, inner: I) -> Self::Service {\n        MapRequest {\n            f: self.f.clone(),\n            state: self.state.clone(),\n            inner,\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<F, S, T> fmt::Debug for MapRequestLayer<F, S, T>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"MapRequestLayer\")\n            // Write out the type name, without quoting it as `&type_name::<F>()` would\n            .field(\"f\", &format_args!(\"{}\", type_name::<F>()))\n            .field(\"state\", &self.state)\n            .finish()\n    }\n}\n\n/// A middleware created from an async function that transforms a request.\n///\n/// Created with [`map_request`]. See that function for more details.\npub struct MapRequest<F, S, I, T> {\n    f: F,\n    inner: I,\n    state: S,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<F, S, I, T> Clone for MapRequest<F, S, I, T>\nwhere\n    F: Clone,\n    I: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            f: self.f.clone(),\n            inner: self.inner.clone(),\n            state: self.state.clone(),\n            _extractor: self._extractor,\n        }\n    }\n}\n\nmacro_rules! impl_service {\n    (\n        [$($ty:ident),*], $last:ident\n    ) => {\n        #[allow(non_snake_case, unused_mut)]\n        impl<F, Fut, S, I, B, $($ty,)* $last> Service<Request<B>> for MapRequest<F, S, I, ($($ty,)* $last,)>\n        where\n            F: FnMut($($ty,)* $last) -> Fut + Clone + Send + 'static,\n            $( $ty: FromRequestParts<S> + Send, )*\n            $last: FromRequest<S> + Send,\n            Fut: Future + Send + 'static,\n            Fut::Output: IntoMapRequestResult<B> + Send + 'static,\n            I: Service<Request<B>, Error = Infallible>\n                + Clone\n                + Send\n                + 'static,\n            I::Response: IntoResponse,\n            I::Future: Send + 'static,\n            B: HttpBody<Data = Bytes> + Send + 'static,\n            B::Error: Into<BoxError>,\n            S: Clone + Send + Sync + 'static,\n        {\n            type Response = Response;\n            type Error = Infallible;\n            type Future = ResponseFuture;\n\n            fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n                self.inner.poll_ready(cx)\n            }\n\n            fn call(&mut self, req: Request<B>) -> Self::Future {\n                let req = req.map(Body::new);\n\n                let not_ready_inner = self.inner.clone();\n                let mut ready_inner = std::mem::replace(&mut self.inner, not_ready_inner);\n\n                let mut f = self.f.clone();\n                let state = self.state.clone();\n                let (mut parts, body) = req.into_parts();\n\n                let future = Box::pin(async move {\n                    $(\n                        let $ty = match $ty::from_request_parts(&mut parts, &state).await {\n                            Ok(value) => value,\n                            Err(rejection) => return rejection.into_response(),\n                        };\n                    )*\n\n                    let req = Request::from_parts(parts, body);\n\n                    let $last = match $last::from_request(req, &state).await {\n                        Ok(value) => value,\n                        Err(rejection) => return rejection.into_response(),\n                    };\n\n                    match f($($ty,)* $last).await.into_map_request_result() {\n                        Ok(req) => {\n                            ready_inner.call(req).await.into_response()\n                        }\n                        Err(res) => {\n                            res\n                        }\n                    }\n                });\n\n                ResponseFuture {\n                    inner: future\n                }\n            }\n        }\n    };\n}\n\nall_the_tuples!(impl_service);\n\nimpl<F, S, I, T> fmt::Debug for MapRequest<F, S, I, T>\nwhere\n    S: fmt::Debug,\n    I: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"MapRequest\")\n            .field(\"f\", &format_args!(\"{}\", type_name::<F>()))\n            .field(\"inner\", &self.inner)\n            .field(\"state\", &self.state)\n            .finish()\n    }\n}\n\n/// Response future for [`MapRequest`].\npub struct ResponseFuture {\n    inner: BoxFuture<'static, Response>,\n}\n\nimpl Future for ResponseFuture {\n    type Output = Result<Response, Infallible>;\n\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.inner.as_mut().poll(cx).map(Ok)\n    }\n}\n\nimpl fmt::Debug for ResponseFuture {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"ResponseFuture\").finish()\n    }\n}\n\nmod private {\n    use crate::{http::Request, response::IntoResponse};\n\n    pub trait Sealed<B> {}\n    impl<B, E> Sealed<B> for Result<Request<B>, E> where E: IntoResponse {}\n    impl<B> Sealed<B> for Request<B> {}\n}\n\n/// Trait implemented by types that can be returned from [`map_request`],\n/// [`map_request_with_state`].\n///\n/// This trait is sealed such that it cannot be implemented outside this crate.\npub trait IntoMapRequestResult<B>: private::Sealed<B> {\n    /// Perform the conversion.\n    #[allow(clippy::result_large_err)]\n    fn into_map_request_result(self) -> Result<Request<B>, Response>;\n}\n\nimpl<B, E> IntoMapRequestResult<B> for Result<Request<B>, E>\nwhere\n    E: IntoResponse,\n{\n    fn into_map_request_result(self) -> Result<Request<B>, Response> {\n        self.map_err(IntoResponse::into_response)\n    }\n}\n\nimpl<B> IntoMapRequestResult<B> for Request<B> {\n    fn into_map_request_result(self) -> Result<Self, Response> {\n        Ok(self)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{routing::get, test_helpers::TestClient, Router};\n    use http::{HeaderMap, StatusCode};\n\n    #[crate::test]\n    async fn works() {\n        async fn add_header<B>(mut req: Request<B>) -> Request<B> {\n            req.headers_mut().insert(\"x-foo\", \"foo\".parse().unwrap());\n            req\n        }\n\n        async fn handler(headers: HeaderMap) -> Response {\n            headers[\"x-foo\"]\n                .to_str()\n                .unwrap()\n                .to_owned()\n                .into_response()\n        }\n\n        let app = Router::new()\n            .route(\"/\", get(handler))\n            .layer(map_request(add_header));\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n\n        assert_eq!(res.text().await, \"foo\");\n    }\n\n    #[crate::test]\n    async fn works_for_short_circutting() {\n        async fn add_header<B>(_req: Request<B>) -> Result<Request<B>, (StatusCode, &'static str)> {\n            Err((StatusCode::INTERNAL_SERVER_ERROR, \"something went wrong\"))\n        }\n\n        async fn handler(_headers: HeaderMap) -> Response {\n            unreachable!()\n        }\n\n        let app = Router::new()\n            .route(\"/\", get(handler))\n            .layer(map_request(add_header));\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert_eq!(res.text().await, \"something went wrong\");\n    }\n}\n"
  },
  {
    "path": "axum/src/middleware/map_response.rs",
    "content": "use crate::response::{IntoResponse, Response};\nuse axum_core::extract::FromRequestParts;\nuse futures_core::future::BoxFuture;\nuse http::Request;\nuse std::{\n    any::type_name,\n    convert::Infallible,\n    fmt,\n    future::Future,\n    marker::PhantomData,\n    pin::Pin,\n    task::{Context, Poll},\n};\nuse tower_layer::Layer;\nuse tower_service::Service;\n\n/// Create a middleware from an async function that transforms a response.\n///\n/// This differs from [`tower::util::MapResponse`] in that it allows you to easily run axum-specific\n/// extractors.\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::get,\n///     middleware::map_response,\n///     response::Response,\n/// };\n///\n/// async fn set_header<B>(mut response: Response<B>) -> Response<B> {\n///     response.headers_mut().insert(\"x-foo\", \"foo\".parse().unwrap());\n///     response\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .layer(map_response(set_header));\n/// # let _: Router = app;\n/// ```\n///\n/// # Running extractors\n///\n/// It is also possible to run extractors that implement [`FromRequestParts`]. These will be run\n/// before calling the handler.\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::get,\n///     middleware::map_response,\n///     extract::Path,\n///     response::Response,\n/// };\n/// use std::collections::HashMap;\n///\n/// async fn log_path_params<B>(\n///     Path(path_params): Path<HashMap<String, String>>,\n///     response: Response<B>,\n/// ) -> Response<B> {\n///     tracing::debug!(?path_params);\n///     response\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .layer(map_response(log_path_params));\n/// # let _: Router = app;\n/// ```\n///\n/// Note that to access state you must use either [`map_response_with_state`].\n///\n/// # Returning any `impl IntoResponse`\n///\n/// It is also possible to return anything that implements [`IntoResponse`]\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::get,\n///     middleware::map_response,\n///     response::{Response, IntoResponse},\n/// };\n/// use std::collections::HashMap;\n///\n/// async fn set_header(response: Response) -> impl IntoResponse {\n///     (\n///         [(\"x-foo\", \"foo\")],\n///         response,\n///     )\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .layer(map_response(set_header));\n/// # let _: Router = app;\n/// ```\npub fn map_response<F, T>(f: F) -> MapResponseLayer<F, (), T> {\n    map_response_with_state((), f)\n}\n\n/// Create a middleware from an async function that transforms a response, with the given state.\n///\n/// See [`State`](crate::extract::State) for more details about accessing state.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     http::StatusCode,\n///     routing::get,\n///     response::Response,\n///     middleware::map_response_with_state,\n///     extract::State,\n/// };\n///\n/// #[derive(Clone)]\n/// struct AppState { /* ... */ }\n///\n/// async fn my_middleware<B>(\n///     State(state): State<AppState>,\n///     // you can add more extractors here but they must\n///     // all implement `FromRequestParts`\n///     // `FromRequest` is not allowed\n///     response: Response<B>,\n/// ) -> Response<B> {\n///     // do something with `state` and `response`...\n///     response\n/// }\n///\n/// let state = AppState { /* ... */ };\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async { /* ... */ }))\n///     .route_layer(map_response_with_state(state.clone(), my_middleware))\n///     .with_state(state);\n/// # let _: axum::Router = app;\n/// ```\npub fn map_response_with_state<F, S, T>(state: S, f: F) -> MapResponseLayer<F, S, T> {\n    MapResponseLayer {\n        f,\n        state,\n        _extractor: PhantomData,\n    }\n}\n\n/// A [`tower::Layer`] from an async function that transforms a response.\n///\n/// Created with [`map_response`]. See that function for more details.\n#[must_use]\npub struct MapResponseLayer<F, S, T> {\n    f: F,\n    state: S,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<F, S, T> Clone for MapResponseLayer<F, S, T>\nwhere\n    F: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            f: self.f.clone(),\n            state: self.state.clone(),\n            _extractor: self._extractor,\n        }\n    }\n}\n\nimpl<S, I, F, T> Layer<I> for MapResponseLayer<F, S, T>\nwhere\n    F: Clone,\n    S: Clone,\n{\n    type Service = MapResponse<F, S, I, T>;\n\n    fn layer(&self, inner: I) -> Self::Service {\n        MapResponse {\n            f: self.f.clone(),\n            state: self.state.clone(),\n            inner,\n            _extractor: PhantomData,\n        }\n    }\n}\n\nimpl<F, S, T> fmt::Debug for MapResponseLayer<F, S, T>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"MapResponseLayer\")\n            // Write out the type name, without quoting it as `&type_name::<F>()` would\n            .field(\"f\", &format_args!(\"{}\", type_name::<F>()))\n            .field(\"state\", &self.state)\n            .finish()\n    }\n}\n\n/// A middleware created from an async function that transforms a response.\n///\n/// Created with [`map_response`]. See that function for more details.\npub struct MapResponse<F, S, I, T> {\n    f: F,\n    inner: I,\n    state: S,\n    _extractor: PhantomData<fn() -> T>,\n}\n\nimpl<F, S, I, T> Clone for MapResponse<F, S, I, T>\nwhere\n    F: Clone,\n    I: Clone,\n    S: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            f: self.f.clone(),\n            inner: self.inner.clone(),\n            state: self.state.clone(),\n            _extractor: self._extractor,\n        }\n    }\n}\n\nmacro_rules! impl_service {\n    (\n        $($ty:ident),*\n    ) => {\n        #[allow(non_snake_case, unused_mut)]\n        impl<F, Fut, S, I, B, ResBody, $($ty,)*> Service<Request<B>> for MapResponse<F, S, I, ($($ty,)*)>\n        where\n            F: FnMut($($ty,)* Response<ResBody>) -> Fut + Clone + Send + 'static,\n            $( $ty: FromRequestParts<S> + Send, )*\n            Fut: Future + Send + 'static,\n            Fut::Output: IntoResponse + Send + 'static,\n            I: Service<Request<B>, Response = Response<ResBody>, Error = Infallible>\n                + Clone\n                + Send\n                + 'static,\n            I::Future: Send + 'static,\n            B: Send + 'static,\n            ResBody: Send + 'static,\n            S: Clone + Send + Sync + 'static,\n        {\n            type Response = Response;\n            type Error = Infallible;\n            type Future = ResponseFuture;\n\n            fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n                self.inner.poll_ready(cx)\n            }\n\n\n            fn call(&mut self, req: Request<B>) -> Self::Future {\n                let not_ready_inner = self.inner.clone();\n                let mut ready_inner = std::mem::replace(&mut self.inner, not_ready_inner);\n\n                let mut f = self.f.clone();\n                let _state = self.state.clone();\n                let (mut parts, body) = req.into_parts();\n\n                let future = Box::pin(async move {\n                    $(\n                        let $ty = match $ty::from_request_parts(&mut parts, &_state).await {\n                            Ok(value) => value,\n                            Err(rejection) => return rejection.into_response(),\n                        };\n                    )*\n\n                    let req = Request::from_parts(parts, body);\n\n                    match ready_inner.call(req).await {\n                        Ok(res) => {\n                            f($($ty,)* res).await.into_response()\n                        }\n                        Err(err) => match err {}\n                    }\n                });\n\n                ResponseFuture {\n                    inner: future\n                }\n            }\n        }\n    };\n}\n\nimpl_service!();\nimpl_service!(T1);\nimpl_service!(T1, T2);\nimpl_service!(T1, T2, T3);\nimpl_service!(T1, T2, T3, T4);\nimpl_service!(T1, T2, T3, T4, T5);\nimpl_service!(T1, T2, T3, T4, T5, T6);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);\nimpl_service!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);\n\nimpl<F, S, I, T> fmt::Debug for MapResponse<F, S, I, T>\nwhere\n    S: fmt::Debug,\n    I: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"MapResponse\")\n            .field(\"f\", &format_args!(\"{}\", type_name::<F>()))\n            .field(\"inner\", &self.inner)\n            .field(\"state\", &self.state)\n            .finish()\n    }\n}\n\n/// Response future for [`MapResponse`].\npub struct ResponseFuture {\n    inner: BoxFuture<'static, Response>,\n}\n\nimpl Future for ResponseFuture {\n    type Output = Result<Response, Infallible>;\n\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        self.inner.as_mut().poll(cx).map(Ok)\n    }\n}\n\nimpl fmt::Debug for ResponseFuture {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"ResponseFuture\").finish()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    #[allow(unused_imports)]\n    use super::*;\n    use crate::{test_helpers::TestClient, Router};\n\n    #[crate::test]\n    async fn works() {\n        async fn add_header<B>(mut res: Response<B>) -> Response<B> {\n            res.headers_mut().insert(\"x-foo\", \"foo\".parse().unwrap());\n            res\n        }\n\n        let app = Router::new().layer(map_response(add_header));\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n\n        assert_eq!(res.headers()[\"x-foo\"], \"foo\");\n    }\n}\n"
  },
  {
    "path": "axum/src/middleware/mod.rs",
    "content": "//! Utilities for writing middleware\n//!\n#![doc = include_str!(\"../docs/middleware.md\")]\n\nmod from_extractor;\nmod from_fn;\nmod map_request;\nmod map_response;\nmod response_axum_body;\n\npub use self::from_extractor::{\n    from_extractor, from_extractor_with_state, FromExtractor, FromExtractorLayer,\n};\npub use self::from_fn::{from_fn, from_fn_with_state, FromFn, FromFnLayer, Next};\npub use self::map_request::{\n    map_request, map_request_with_state, IntoMapRequestResult, MapRequest, MapRequestLayer,\n};\npub use self::map_response::{\n    map_response, map_response_with_state, MapResponse, MapResponseLayer,\n};\npub use self::response_axum_body::{\n    ResponseAxumBody, ResponseAxumBodyFuture, ResponseAxumBodyLayer,\n};\npub use crate::extension::AddExtension;\n\npub mod future {\n    //! Future types.\n\n    pub use super::from_extractor::ResponseFuture as FromExtractorResponseFuture;\n    pub use super::from_fn::ResponseFuture as FromFnResponseFuture;\n    pub use super::map_request::ResponseFuture as MapRequestResponseFuture;\n    pub use super::map_response::ResponseFuture as MapResponseResponseFuture;\n}\n"
  },
  {
    "path": "axum/src/middleware/response_axum_body.rs",
    "content": "use std::{\n    error::Error,\n    future::Future,\n    pin::Pin,\n    task::{ready, Context, Poll},\n};\n\nuse axum_core::{body::Body, response::Response};\nuse bytes::Bytes;\nuse http_body::Body as HttpBody;\nuse pin_project_lite::pin_project;\nuse tower::{Layer, Service};\n\n/// Layer that transforms the Response body to [`crate::body::Body`].\n///\n/// This is useful when another layer maps the body to some other type to convert it back.\n#[derive(Debug, Clone)]\npub struct ResponseAxumBodyLayer;\n\nimpl<S> Layer<S> for ResponseAxumBodyLayer {\n    type Service = ResponseAxumBody<S>;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        ResponseAxumBody::<S>(inner)\n    }\n}\n\n/// Service generated by [`ResponseAxumBodyLayer`].\n#[derive(Debug, Clone)]\npub struct ResponseAxumBody<S>(S);\n\nimpl<S, Request, ResBody> Service<Request> for ResponseAxumBody<S>\nwhere\n    S: Service<Request, Response = Response<ResBody>>,\n    ResBody: HttpBody<Data = Bytes> + Send + 'static,\n    <ResBody as HttpBody>::Error: Error + Send + Sync,\n{\n    type Response = Response;\n\n    type Error = S::Error;\n\n    type Future = ResponseAxumBodyFuture<S::Future>;\n\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.0.poll_ready(cx)\n    }\n\n    fn call(&mut self, req: Request) -> Self::Future {\n        ResponseAxumBodyFuture {\n            inner: self.0.call(req),\n        }\n    }\n}\n\npin_project! {\n    /// Response future for [`ResponseAxumBody`].\n    pub struct ResponseAxumBodyFuture<Fut> {\n        #[pin]\n        inner: Fut,\n    }\n}\n\nimpl<Fut, ResBody, E> Future for ResponseAxumBodyFuture<Fut>\nwhere\n    Fut: Future<Output = Result<Response<ResBody>, E>>,\n    ResBody: HttpBody<Data = Bytes> + Send + 'static,\n    <ResBody as HttpBody>::Error: Error + Send + Sync,\n{\n    type Output = Result<Response<Body>, E>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        let this = self.project();\n        let res = ready!(this.inner.poll(cx)?);\n        Poll::Ready(Ok(res.map(Body::new)))\n    }\n}\n"
  },
  {
    "path": "axum/src/response/mod.rs",
    "content": "#![doc = include_str!(\"../docs/response.md\")]\n\nuse http::{header, HeaderValue, StatusCode};\n\nmod redirect;\n\npub mod sse;\n\n#[doc(no_inline)]\n#[cfg(feature = \"json\")]\npub use crate::Json;\n\n#[cfg(feature = \"form\")]\n#[doc(no_inline)]\npub use crate::form::Form;\n\n#[doc(no_inline)]\npub use crate::Extension;\n\n#[doc(inline)]\npub use axum_core::response::{\n    AppendHeaders, ErrorResponse, IntoResponse, IntoResponseFailed, IntoResponseParts, Response,\n    ResponseParts, Result,\n};\n\n#[doc(inline)]\npub use self::redirect::Redirect;\n\n#[doc(inline)]\npub use sse::Sse;\n\n/// An HTML response.\n///\n/// Will automatically get `Content-Type: text/html`.\n#[derive(Clone, Copy, Debug)]\n#[must_use]\npub struct Html<T>(pub T);\n\nimpl<T> IntoResponse for Html<T>\nwhere\n    T: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        (\n            [(\n                header::CONTENT_TYPE,\n                HeaderValue::from_static(mime::TEXT_HTML_UTF_8.as_ref()),\n            )],\n            self.0,\n        )\n            .into_response()\n    }\n}\n\nimpl<T> From<T> for Html<T> {\n    fn from(inner: T) -> Self {\n        Self(inner)\n    }\n}\n\n/// An empty response with 204 No Content status.\n///\n/// Due to historical and implementation reasons, the `IntoResponse` implementation of `()`\n/// (unit type) returns an empty response with 200 [`StatusCode::OK`] status.\n/// If you specifically want a 204 [`StatusCode::NO_CONTENT`] status, you can use either `StatusCode` type\n/// directly, or this shortcut struct for self-documentation.\n///\n/// ```\n/// use axum::{extract::Path, response::NoContent};\n///\n/// async fn delete_user(Path(user): Path<String>) -> Result<NoContent, String> {\n///     // ...access database...\n/// # drop(user);\n///     Ok(NoContent)\n/// }\n/// ```\n#[derive(Debug, Clone, Copy)]\npub struct NoContent;\n\nimpl IntoResponse for NoContent {\n    fn into_response(self) -> Response {\n        StatusCode::NO_CONTENT.into_response()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::extract::Extension;\n    use crate::test_helpers::*;\n    use crate::Json;\n    use crate::{routing::get, Router};\n    use axum_core::response::ForceStatusCode;\n    use axum_core::response::{\n        IntoResponse, IntoResponseFailed, IntoResponseParts, Response, ResponseParts,\n    };\n    use http::HeaderMap;\n    use http::{StatusCode, Uri};\n    use std::collections::HashMap;\n\n    // just needs to compile\n    #[allow(dead_code)]\n    fn impl_trait_result_works() {\n        async fn impl_trait_ok() -> Result<impl IntoResponse, ()> {\n            Ok(())\n        }\n\n        async fn impl_trait_err() -> Result<(), impl IntoResponse> {\n            Err(())\n        }\n\n        async fn impl_trait_both(uri: Uri) -> Result<impl IntoResponse, impl IntoResponse> {\n            if uri.path() == \"/\" {\n                Ok(())\n            } else {\n                Err(())\n            }\n        }\n\n        async fn impl_trait(uri: Uri) -> impl IntoResponse {\n            if uri.path() == \"/\" {\n                Ok(())\n            } else {\n                Err(())\n            }\n        }\n\n        _ = Router::<()>::new()\n            .route(\"/\", get(impl_trait_ok))\n            .route(\"/\", get(impl_trait_err))\n            .route(\"/\", get(impl_trait_both))\n            .route(\"/\", get(impl_trait));\n    }\n\n    // just needs to compile\n    #[allow(dead_code)]\n    fn tuple_responses() {\n        async fn status() -> impl IntoResponse {\n            StatusCode::OK\n        }\n\n        async fn status_headermap() -> impl IntoResponse {\n            (StatusCode::OK, HeaderMap::new())\n        }\n\n        async fn status_header_array() -> impl IntoResponse {\n            (StatusCode::OK, [(\"content-type\", \"text/plain\")])\n        }\n\n        async fn status_headermap_body() -> impl IntoResponse {\n            (StatusCode::OK, HeaderMap::new(), String::new())\n        }\n\n        async fn status_header_array_body() -> impl IntoResponse {\n            (\n                StatusCode::OK,\n                [(\"content-type\", \"text/plain\")],\n                String::new(),\n            )\n        }\n\n        async fn status_headermap_impl_into_response() -> impl IntoResponse {\n            (StatusCode::OK, HeaderMap::new(), impl_into_response())\n        }\n\n        async fn status_header_array_impl_into_response() -> impl IntoResponse {\n            (\n                StatusCode::OK,\n                [(\"content-type\", \"text/plain\")],\n                impl_into_response(),\n            )\n        }\n\n        fn impl_into_response() -> impl IntoResponse {}\n\n        async fn status_header_array_extension_body() -> impl IntoResponse {\n            (\n                StatusCode::OK,\n                [(\"content-type\", \"text/plain\")],\n                Extension(1),\n                String::new(),\n            )\n        }\n\n        async fn status_header_array_extension_mixed_body() -> impl IntoResponse {\n            (\n                StatusCode::OK,\n                [(\"content-type\", \"text/plain\")],\n                Extension(1),\n                HeaderMap::new(),\n                String::new(),\n            )\n        }\n\n        //\n\n        async fn headermap() -> impl IntoResponse {\n            HeaderMap::new()\n        }\n\n        async fn header_array() -> impl IntoResponse {\n            [(\"content-type\", \"text/plain\")]\n        }\n\n        async fn headermap_body() -> impl IntoResponse {\n            (HeaderMap::new(), String::new())\n        }\n\n        async fn header_array_body() -> impl IntoResponse {\n            ([(\"content-type\", \"text/plain\")], String::new())\n        }\n\n        async fn headermap_impl_into_response() -> impl IntoResponse {\n            (HeaderMap::new(), impl_into_response())\n        }\n\n        async fn header_array_impl_into_response() -> impl IntoResponse {\n            ([(\"content-type\", \"text/plain\")], impl_into_response())\n        }\n\n        async fn header_array_extension_body() -> impl IntoResponse {\n            (\n                [(\"content-type\", \"text/plain\")],\n                Extension(1),\n                String::new(),\n            )\n        }\n\n        async fn header_array_extension_mixed_body() -> impl IntoResponse {\n            (\n                [(\"content-type\", \"text/plain\")],\n                Extension(1),\n                HeaderMap::new(),\n                String::new(),\n            )\n        }\n\n        _ = Router::<()>::new()\n            .route(\"/\", get(status))\n            .route(\"/\", get(status_headermap))\n            .route(\"/\", get(status_header_array))\n            .route(\"/\", get(status_headermap_body))\n            .route(\"/\", get(status_header_array_body))\n            .route(\"/\", get(status_headermap_impl_into_response))\n            .route(\"/\", get(status_header_array_impl_into_response))\n            .route(\"/\", get(status_header_array_extension_body))\n            .route(\"/\", get(status_header_array_extension_mixed_body))\n            .route(\"/\", get(headermap))\n            .route(\"/\", get(header_array))\n            .route(\"/\", get(headermap_body))\n            .route(\"/\", get(header_array_body))\n            .route(\"/\", get(headermap_impl_into_response))\n            .route(\"/\", get(header_array_impl_into_response))\n            .route(\"/\", get(header_array_extension_body))\n            .route(\"/\", get(header_array_extension_mixed_body));\n    }\n\n    #[test]\n    fn status_code_tuple_doesnt_override_error() {\n        // sanity check where there is just one status code\n        assert_eq!(\n            StatusCode::INTERNAL_SERVER_ERROR.into_response().status(),\n            StatusCode::INTERNAL_SERVER_ERROR\n        );\n        assert_eq!(\n            (StatusCode::INTERNAL_SERVER_ERROR,)\n                .into_response()\n                .status(),\n            StatusCode::INTERNAL_SERVER_ERROR\n        );\n\n        // non-5xx status should be changed\n        assert_eq!(\n            (StatusCode::SEE_OTHER, StatusCode::NO_CONTENT)\n                .into_response()\n                .status(),\n            StatusCode::SEE_OTHER\n        );\n        let res = (\n            StatusCode::SEE_OTHER,\n            [(\"location\", \"foo\")],\n            StatusCode::NO_CONTENT,\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::SEE_OTHER);\n        assert_eq!(res.headers()[\"location\"], \"foo\");\n\n        // 5xx status codes are also changed\n        assert_eq!(\n            (StatusCode::SEE_OTHER, StatusCode::INTERNAL_SERVER_ERROR)\n                .into_response()\n                .status(),\n            StatusCode::SEE_OTHER\n        );\n        let res = (\n            StatusCode::SEE_OTHER,\n            [(\"location\", \"foo\")],\n            StatusCode::INTERNAL_SERVER_ERROR,\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::SEE_OTHER);\n        assert_eq!(res.headers()[\"location\"], \"foo\");\n\n        // the status is not changed if `IntoResponseFailed` is used\n        assert_eq!(\n            (\n                StatusCode::SEE_OTHER,\n                (IntoResponseFailed, StatusCode::INTERNAL_SERVER_ERROR)\n            )\n                .into_response()\n                .status(),\n            StatusCode::INTERNAL_SERVER_ERROR\n        );\n        let res = (\n            StatusCode::SEE_OTHER,\n            [(\"location\", \"foo\")],\n            (IntoResponseFailed, StatusCode::INTERNAL_SERVER_ERROR),\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert!(res.headers().get(\"location\").is_none());\n\n        // response parts from the inner response do run\n        let res = (\n            // with status override\n            StatusCode::SEE_OTHER,\n            [(\"location\", \"foo\")],\n            (\n                [(\"x-bar\", \"bar\")],\n                IntoResponseFailed,\n                [(\"x-foo\", \"foo\")],\n                StatusCode::INTERNAL_SERVER_ERROR,\n            ),\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert!(res.headers().get(\"location\").is_none());\n        assert_eq!(res.headers()[\"x-foo\"], \"foo\");\n        assert_eq!(res.headers()[\"x-bar\"], \"bar\");\n\n        let res = (\n            // without status override\n            [(\"location\", \"foo\")],\n            (\n                [(\"x-bar\", \"bar\")],\n                IntoResponseFailed,\n                [(\"x-foo\", \"foo\")],\n                StatusCode::INTERNAL_SERVER_ERROR,\n            ),\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert!(res.headers().get(\"location\").is_none());\n        assert_eq!(res.headers()[\"x-foo\"], \"foo\");\n        assert_eq!(res.headers()[\"x-bar\"], \"bar\");\n\n        // (Parts, ...)\n        let res = (\n            Response::new(()).into_parts().0,\n            [(\"location\", \"foo\")],\n            (\n                [(\"x-bar\", \"bar\")],\n                IntoResponseFailed,\n                [(\"x-foo\", \"foo\")],\n                StatusCode::INTERNAL_SERVER_ERROR,\n            ),\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert!(res.headers().get(\"location\").is_none());\n        assert_eq!(res.headers()[\"x-foo\"], \"foo\");\n        assert_eq!(res.headers()[\"x-bar\"], \"bar\");\n\n        // (Response<()>, ...)\n        let res = (\n            Response::new(()),\n            [(\"location\", \"foo\")],\n            (\n                [(\"x-bar\", \"bar\")],\n                IntoResponseFailed,\n                [(\"x-foo\", \"foo\")],\n                StatusCode::INTERNAL_SERVER_ERROR,\n            ),\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert!(res.headers().get(\"location\").is_none());\n        assert_eq!(res.headers()[\"x-foo\"], \"foo\");\n        assert_eq!(res.headers()[\"x-bar\"], \"bar\");\n    }\n\n    #[test]\n    fn into_response_parts_failing_sets_extension() {\n        struct Fail;\n\n        impl IntoResponseParts for Fail {\n            type Error = ();\n\n            fn into_response_parts(\n                self,\n                _res: ResponseParts,\n            ) -> Result<ResponseParts, Self::Error> {\n                Err(())\n            }\n        }\n\n        impl IntoResponse for Fail {\n            fn into_response(self) -> Response {\n                (self, ()).into_response()\n            }\n        }\n\n        assert!(Fail\n            .into_response()\n            .extensions()\n            .get::<IntoResponseFailed>()\n            .is_some());\n\n        assert!((StatusCode::INTERNAL_SERVER_ERROR, Fail, ())\n            .into_response()\n            .extensions()\n            .get::<IntoResponseFailed>()\n            .is_some());\n\n        assert!((Response::new(()).into_parts().0, Fail, ())\n            .into_response()\n            .extensions()\n            .get::<IntoResponseFailed>()\n            .is_some());\n\n        assert!((Response::new(()), Fail, ())\n            .into_response()\n            .extensions()\n            .get::<IntoResponseFailed>()\n            .is_some());\n    }\n\n    #[test]\n    fn doenst_override_status_code_when_using_into_response_failed_at_same_level() {\n        assert_eq!(\n            (StatusCode::INTERNAL_SERVER_ERROR, IntoResponseFailed, ())\n                .into_response()\n                .status(),\n            StatusCode::INTERNAL_SERVER_ERROR,\n        );\n\n        #[derive(Clone)]\n        struct Thing;\n\n        let res = (\n            Response::builder()\n                .status(StatusCode::INTERNAL_SERVER_ERROR)\n                .header(\"x-foo\", \"foo\")\n                .extension(Thing)\n                .body(())\n                .unwrap()\n                .into_parts()\n                .0,\n            IntoResponseFailed,\n            (),\n        )\n            .into_response();\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        assert_eq!(res.headers()[\"x-foo\"], \"foo\");\n        assert!(res.extensions().get::<Thing>().is_some());\n\n        // just a sanity check\n        assert_eq!(\n            (IntoResponseFailed, ()).into_response().status(),\n            StatusCode::OK,\n        );\n    }\n\n    #[test]\n    fn force_overriding_status_code() {\n        assert_eq!(\n            ForceStatusCode(StatusCode::IM_A_TEAPOT)\n                .into_response()\n                .status(),\n            StatusCode::IM_A_TEAPOT\n        );\n\n        assert_eq!(\n            (ForceStatusCode(StatusCode::IM_A_TEAPOT),)\n                .into_response()\n                .status(),\n            StatusCode::IM_A_TEAPOT\n        );\n\n        assert_eq!(\n            (ForceStatusCode(StatusCode::IM_A_TEAPOT), ())\n                .into_response()\n                .status(),\n            StatusCode::IM_A_TEAPOT\n        );\n\n        assert_eq!(\n            (\n                ForceStatusCode(StatusCode::IM_A_TEAPOT),\n                IntoResponseFailed,\n                StatusCode::INTERNAL_SERVER_ERROR,\n            )\n                .into_response()\n                .status(),\n            StatusCode::IM_A_TEAPOT\n        );\n    }\n\n    #[crate::test]\n    async fn status_code_tuple_doesnt_override_error_json() {\n        let app = Router::new()\n            .route(\n                \"/\",\n                get(|| async {\n                    let not_json_compatible = HashMap::from([(Vec::from([1, 2, 3]), 123)]);\n                    (StatusCode::IM_A_TEAPOT, Json(not_json_compatible))\n                }),\n            )\n            .route(\n                \"/two\",\n                get(|| async {\n                    let not_json_compatible = HashMap::from([(Vec::from([1, 2, 3]), 123)]);\n                    (\n                        ForceStatusCode(StatusCode::IM_A_TEAPOT),\n                        Json(not_json_compatible),\n                    )\n                }),\n            );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n\n        let res = client.get(\"/two\").await;\n        assert_eq!(res.status(), StatusCode::IM_A_TEAPOT);\n    }\n\n    #[test]\n    fn no_content() {\n        assert_eq!(\n            super::NoContent.into_response().status(),\n            StatusCode::NO_CONTENT,\n        )\n    }\n}\n"
  },
  {
    "path": "axum/src/response/redirect.rs",
    "content": "use axum_core::response::{IntoResponse, Response};\nuse http::{header::LOCATION, HeaderValue, StatusCode};\n\n/// Response that redirects the request to another location.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     routing::get,\n///     response::Redirect,\n///     Router,\n/// };\n///\n/// let app = Router::new()\n///     .route(\"/old\", get(|| async { Redirect::permanent(\"/new\") }))\n///     .route(\"/new\", get(|| async { \"Hello!\" }));\n/// # let _: Router = app;\n/// ```\n#[must_use = \"needs to be returned from a handler or otherwise turned into a Response to be useful\"]\n#[derive(Debug, Clone)]\npub struct Redirect {\n    status_code: StatusCode,\n    location: String,\n}\n\nimpl Redirect {\n    /// Create a new [`Redirect`] that uses a [`303 See Other`][mdn] status code.\n    ///\n    /// This redirect instructs the client to change the method to GET for the subsequent request\n    /// to the given `uri`, which is useful after successful form submission, file upload or when\n    /// you generally don't want the redirected-to page to observe the original request method and\n    /// body (if non-empty). If you want to preserve the request method and body,\n    /// [`Redirect::temporary`] should be used instead.\n    ///\n    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303\n    pub fn to(uri: impl Into<String>) -> Self {\n        Self::with_status_code(StatusCode::SEE_OTHER, uri.into())\n    }\n\n    /// Create a new [`Redirect`] that uses a [`307 Temporary Redirect`][mdn] status code.\n    ///\n    /// This has the same behavior as [`Redirect::to`], except it will preserve the original HTTP\n    /// method and body.\n    ///\n    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307\n    pub fn temporary(uri: impl Into<String>) -> Self {\n        Self::with_status_code(StatusCode::TEMPORARY_REDIRECT, uri.into())\n    }\n\n    /// Create a new [`Redirect`] that uses a [`308 Permanent Redirect`][mdn] status code.\n    ///\n    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308\n    pub fn permanent(uri: impl Into<String>) -> Self {\n        Self::with_status_code(StatusCode::PERMANENT_REDIRECT, uri.into())\n    }\n\n    /// Returns the HTTP status code of the `Redirect`.\n    #[must_use]\n    pub fn status_code(&self) -> StatusCode {\n        self.status_code\n    }\n\n    /// Returns the `Redirect`'s URI.\n    #[must_use]\n    pub fn location(&self) -> &str {\n        &self.location\n    }\n\n    // This is intentionally not public since other kinds of redirects might not\n    // use the `Location` header, namely `304 Not Modified`.\n    //\n    // We're open to adding more constructors upon request, if they make sense :)\n    fn with_status_code(status_code: StatusCode, uri: String) -> Self {\n        assert!(\n            status_code.is_redirection(),\n            \"not a redirection status code\"\n        );\n\n        Self {\n            status_code,\n            location: uri,\n        }\n    }\n}\n\nimpl IntoResponse for Redirect {\n    fn into_response(self) -> Response {\n        match HeaderValue::try_from(self.location) {\n            Ok(location) => (self.status_code, [(LOCATION, location)]).into_response(),\n            Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::Redirect;\n    use axum_core::response::IntoResponse;\n    use http::StatusCode;\n\n    const EXAMPLE_URL: &str = \"https://example.com\";\n\n    // Tests to make sure Redirect has the correct status codes\n    // based on the way it was constructed.\n    #[test]\n    fn correct_status() {\n        assert_eq!(\n            StatusCode::SEE_OTHER,\n            Redirect::to(EXAMPLE_URL).status_code()\n        );\n\n        assert_eq!(\n            StatusCode::TEMPORARY_REDIRECT,\n            Redirect::temporary(EXAMPLE_URL).status_code()\n        );\n\n        assert_eq!(\n            StatusCode::PERMANENT_REDIRECT,\n            Redirect::permanent(EXAMPLE_URL).status_code()\n        );\n    }\n\n    #[test]\n    fn correct_location() {\n        assert_eq!(EXAMPLE_URL, Redirect::permanent(EXAMPLE_URL).location());\n\n        assert_eq!(\"/redirect\", Redirect::permanent(\"/redirect\").location())\n    }\n\n    #[test]\n    fn test_internal_error() {\n        let response = Redirect::permanent(\"Axum is awesome, \\n but newlines aren't allowed :(\")\n            .into_response();\n\n        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);\n    }\n}\n"
  },
  {
    "path": "axum/src/response/sse.rs",
    "content": "//! Server-Sent Events (SSE) responses.\n//!\n//! # Example\n//!\n//! ```\n//! use axum::{\n//!     Router,\n//!     routing::get,\n//!     response::sse::{Event, KeepAlive, Sse},\n//! };\n//! use std::{time::Duration, convert::Infallible};\n//! use tokio_stream::StreamExt as _ ;\n//! use futures_util::stream::{self, Stream};\n//!\n//! let app = Router::new().route(\"/sse\", get(sse_handler));\n//!\n//! async fn sse_handler() -> Sse<impl Stream<Item = Result<Event, Infallible>>> {\n//!     // A `Stream` that repeats an event every second\n//!     let stream = stream::repeat_with(|| Event::default().data(\"hi!\"))\n//!         .map(Ok)\n//!         .throttle(Duration::from_secs(1));\n//!\n//!     Sse::new(stream).keep_alive(KeepAlive::default())\n//! }\n//! # let _: Router = app;\n//! ```\n\nuse crate::{\n    body::{Bytes, HttpBody},\n    BoxError,\n};\nuse axum_core::{\n    body::Body,\n    response::{IntoResponse, Response},\n};\nuse bytes::{BufMut, BytesMut};\nuse futures_core::Stream;\nuse futures_util::stream::TryStream;\nuse http_body::Frame;\nuse pin_project_lite::pin_project;\nuse std::{\n    fmt::{self, Write as _},\n    io::Write as _,\n    mem,\n    pin::Pin,\n    task::{ready, Context, Poll},\n    time::Duration,\n};\nuse sync_wrapper::SyncWrapper;\n\n/// An SSE response\n#[derive(Clone)]\n#[must_use]\npub struct Sse<S> {\n    stream: S,\n}\n\nimpl<S> Sse<S> {\n    /// Create a new [`Sse`] response that will respond with the given stream of\n    /// [`Event`]s.\n    ///\n    /// See the [module docs](self) for more details.\n    pub fn new(stream: S) -> Self\n    where\n        S: TryStream<Ok = Event> + Send + 'static,\n        S::Error: Into<BoxError>,\n    {\n        Self { stream }\n    }\n\n    /// Configure the interval between keep-alive messages.\n    ///\n    /// Defaults to no keep-alive messages.\n    #[cfg(feature = \"tokio\")]\n    pub fn keep_alive(self, keep_alive: KeepAlive) -> Sse<KeepAliveStream<S>> {\n        Sse {\n            stream: KeepAliveStream::new(keep_alive, self.stream),\n        }\n    }\n}\n\nimpl<S> fmt::Debug for Sse<S> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Sse\")\n            .field(\"stream\", &format_args!(\"{}\", std::any::type_name::<S>()))\n            .finish()\n    }\n}\n\nimpl<S, E> IntoResponse for Sse<S>\nwhere\n    S: Stream<Item = Result<Event, E>> + Send + 'static,\n    E: Into<BoxError>,\n{\n    fn into_response(self) -> Response {\n        (\n            [\n                (http::header::CONTENT_TYPE, mime::TEXT_EVENT_STREAM.as_ref()),\n                (http::header::CACHE_CONTROL, \"no-cache\"),\n            ],\n            Body::new(SseBody {\n                event_stream: SyncWrapper::new(self.stream),\n            }),\n        )\n            .into_response()\n    }\n}\n\npin_project! {\n    struct SseBody<S> {\n        #[pin]\n        event_stream: SyncWrapper<S>,\n    }\n}\n\nimpl<S, E> HttpBody for SseBody<S>\nwhere\n    S: Stream<Item = Result<Event, E>>,\n{\n    type Data = Bytes;\n    type Error = E;\n\n    fn poll_frame(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {\n        let this = self.project();\n\n        match ready!(this.event_stream.get_pin_mut().poll_next(cx)) {\n            Some(Ok(event)) => Poll::Ready(Some(Ok(Frame::data(event.finalize())))),\n            Some(Err(error)) => Poll::Ready(Some(Err(error))),\n            None => Poll::Ready(None),\n        }\n    }\n}\n\n/// The state of an event's buffer.\n///\n/// This type allows creating events in a `const` context\n/// by using a finalized buffer.\n///\n/// While the buffer is active, more bytes can be written to it.\n/// Once finalized, it's immutable and cheap to clone.\n/// The buffer is active during the event building, but eventually\n/// becomes finalized to send http body frames as [`Bytes`].\n#[derive(Debug, Clone)]\nenum Buffer {\n    Active(BytesMut),\n    Finalized(Bytes),\n}\n\nimpl Buffer {\n    /// Returns a mutable reference to the internal buffer.\n    ///\n    /// If the buffer was finalized, this method creates\n    /// a new active buffer with the previous contents.\n    fn as_mut(&mut self) -> &mut BytesMut {\n        match self {\n            Self::Active(bytes_mut) => bytes_mut,\n            Self::Finalized(bytes) => {\n                *self = Self::Active(BytesMut::from(mem::take(bytes)));\n                match self {\n                    Self::Active(bytes_mut) => bytes_mut,\n                    Self::Finalized(_) => unreachable!(),\n                }\n            }\n        }\n    }\n}\n\n/// Server-sent event\n#[derive(Debug, Clone)]\n#[must_use]\npub struct Event {\n    buffer: Buffer,\n    flags: EventFlags,\n}\n\n/// Expose [`Event`] as a [`std::fmt::Write`]\n/// such that any form of data can be written as data safely.\n///\n/// This also ensures that newline characters `\\r` and `\\n`\n/// correctly trigger a split with a new `data: ` prefix.\n///\n/// # Panics\n///\n/// Panics if any `data` has already been written prior to the first write\n/// of this [`EventDataWriter`] instance.\n#[derive(Debug)]\n#[must_use]\npub struct EventDataWriter {\n    event: Event,\n\n    // Indicates if _this_ EventDataWriter has written data,\n    // this does not say anything about whether or not `event` contains\n    // data or not.\n    data_written: bool,\n}\n\nimpl Event {\n    /// Default keep-alive event\n    pub const DEFAULT_KEEP_ALIVE: Self = Self::finalized(Bytes::from_static(b\":\\n\\n\"));\n\n    const fn finalized(bytes: Bytes) -> Self {\n        Self {\n            buffer: Buffer::Finalized(bytes),\n            flags: EventFlags::from_bits(0),\n        }\n    }\n\n    /// Use this [`Event`] as a [`EventDataWriter`] to write custom data.\n    ///\n    /// - [`Self::data`] can be used as a shortcut to write `str` data\n    /// - [`Self::json_data`] can be used as a shortcut to write `json` data\n    ///\n    /// Turn it into an [`Event`] again using [`EventDataWriter::into_event`].\n    pub fn into_data_writer(self) -> EventDataWriter {\n        EventDataWriter {\n            event: self,\n            data_written: false,\n        }\n    }\n\n    /// Set the event's data data field(s) (`data: <content>`)\n    ///\n    /// Newlines in `data` will automatically be broken across `data: ` fields.\n    ///\n    /// This corresponds to [`MessageEvent`'s data field].\n    ///\n    /// Note that events with an empty data field will be ignored by the browser.\n    ///\n    /// # Panics\n    ///\n    /// Panics if any `data` has already been written before.\n    ///\n    /// [`MessageEvent`'s data field]: https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n    pub fn data<T>(self, data: T) -> Self\n    where\n        T: AsRef<str>,\n    {\n        let mut writer = self.into_data_writer();\n        let _ = writer.write_str(data.as_ref());\n        writer.into_event()\n    }\n\n    /// Set the event's data field to a value serialized as unformatted JSON (`data: <content>`).\n    ///\n    /// This corresponds to [`MessageEvent`'s data field].\n    ///\n    /// # Panics\n    ///\n    /// Panics if any `data` has already been written before.\n    ///\n    /// [`MessageEvent`'s data field]: https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data\n    #[cfg(feature = \"json\")]\n    pub fn json_data<T>(self, data: T) -> Result<Self, axum_core::Error>\n    where\n        T: serde_core::Serialize,\n    {\n        struct JsonWriter<'a>(&'a mut EventDataWriter);\n        impl std::io::Write for JsonWriter<'_> {\n            #[inline]\n            fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {\n                Ok(self.0.write_buf(buf))\n            }\n            fn flush(&mut self) -> std::io::Result<()> {\n                Ok(())\n            }\n        }\n\n        let mut writer = self.into_data_writer();\n\n        let json_writer = JsonWriter(&mut writer);\n        serde_json::to_writer(json_writer, &data).map_err(axum_core::Error::new)?;\n\n        Ok(writer.into_event())\n    }\n\n    /// Set the event's comment field (`:<comment-text>`).\n    ///\n    /// This field will be ignored by most SSE clients.\n    ///\n    /// Unlike other functions, this function can be called multiple times to add many comments.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `comment` contains any newlines or carriage returns, as they are not allowed in\n    /// comments.\n    pub fn comment<T>(mut self, comment: T) -> Self\n    where\n        T: AsRef<str>,\n    {\n        self.field(\"\", comment.as_ref());\n        self\n    }\n\n    /// Set the event's name field (`event:<event-name>`).\n    ///\n    /// This corresponds to the `type` parameter given when calling `addEventListener` on an\n    /// [`EventSource`]. For example, `.event(\"update\")` should correspond to\n    /// `.addEventListener(\"update\", ...)`. If no event type is given, browsers will fire a\n    /// [`message` event] instead.\n    ///\n    /// [`EventSource`]: https://developer.mozilla.org/en-US/docs/Web/API/EventSource\n    /// [`message` event]: https://developer.mozilla.org/en-US/docs/Web/API/EventSource/message_event\n    ///\n    /// # Panics\n    ///\n    /// - Panics if `event` contains any newlines or carriage returns.\n    /// - Panics if this function has already been called on this event.\n    pub fn event<T>(mut self, event: T) -> Self\n    where\n        T: AsRef<str>,\n    {\n        if self.flags.contains(EventFlags::HAS_EVENT) {\n            panic!(\"Called `Event::event` multiple times\");\n        }\n        self.flags.insert(EventFlags::HAS_EVENT);\n\n        self.field(\"event\", event.as_ref());\n\n        self\n    }\n\n    /// Set the event's retry timeout field (`retry: <timeout>`).\n    ///\n    /// This sets how long clients will wait before reconnecting if they are disconnected from the\n    /// SSE endpoint. Note that this is just a hint: clients are free to wait for longer if they\n    /// wish, such as if they implement exponential backoff.\n    ///\n    /// # Panics\n    ///\n    /// Panics if this function has already been called on this event.\n    pub fn retry(mut self, duration: Duration) -> Self {\n        if self.flags.contains(EventFlags::HAS_RETRY) {\n            panic!(\"Called `Event::retry` multiple times\");\n        }\n        self.flags.insert(EventFlags::HAS_RETRY);\n\n        let buffer = self.buffer.as_mut();\n        buffer.extend_from_slice(b\"retry: \");\n\n        let secs = duration.as_secs();\n        let millis = duration.subsec_millis();\n\n        if secs > 0 {\n            // format seconds\n            buffer.extend_from_slice(itoa::Buffer::new().format(secs).as_bytes());\n\n            // pad milliseconds\n            if millis < 10 {\n                buffer.extend_from_slice(b\"00\");\n            } else if millis < 100 {\n                buffer.extend_from_slice(b\"0\");\n            }\n        }\n\n        // format milliseconds\n        buffer.extend_from_slice(itoa::Buffer::new().format(millis).as_bytes());\n\n        buffer.put_u8(b'\\n');\n\n        self\n    }\n\n    /// Set the event's identifier field (`id:<identifier>`).\n    ///\n    /// This corresponds to [`MessageEvent`'s `lastEventId` field]. If no ID is in the event itself,\n    /// the browser will set that field to the last known message ID, starting with the empty\n    /// string.\n    ///\n    /// [`MessageEvent`'s `lastEventId` field]: https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/lastEventId\n    ///\n    /// # Panics\n    ///\n    /// - Panics if `id` contains any newlines, carriage returns or null characters.\n    /// - Panics if this function has already been called on this event.\n    pub fn id<T>(mut self, id: T) -> Self\n    where\n        T: AsRef<str>,\n    {\n        if self.flags.contains(EventFlags::HAS_ID) {\n            panic!(\"Called `Event::id` multiple times\");\n        }\n        self.flags.insert(EventFlags::HAS_ID);\n\n        let id = id.as_ref().as_bytes();\n        assert_eq!(\n            memchr::memchr(b'\\0', id),\n            None,\n            \"Event ID cannot contain null characters\",\n        );\n\n        self.field(\"id\", id);\n        self\n    }\n\n    fn field(&mut self, name: &str, value: impl AsRef<[u8]>) {\n        let value = value.as_ref();\n        assert_eq!(\n            memchr::memchr2(b'\\r', b'\\n', value),\n            None,\n            \"SSE field value cannot contain newlines or carriage returns\",\n        );\n\n        let buffer = self.buffer.as_mut();\n        buffer.extend_from_slice(name.as_bytes());\n        buffer.put_u8(b':');\n        buffer.put_u8(b' ');\n        buffer.extend_from_slice(value);\n        buffer.put_u8(b'\\n');\n    }\n\n    fn finalize(self) -> Bytes {\n        match self.buffer {\n            Buffer::Finalized(bytes) => bytes,\n            Buffer::Active(mut bytes_mut) => {\n                bytes_mut.put_u8(b'\\n');\n                bytes_mut.freeze()\n            }\n        }\n    }\n}\n\nimpl EventDataWriter {\n    /// Consume the [`EventDataWriter`] and return the [`Event`] once again.\n    ///\n    /// In case any data was written by this instance\n    /// it will also write the trailing `\\n` character.\n    pub fn into_event(self) -> Event {\n        let mut event = self.event;\n        if self.data_written {\n            let _ = event.buffer.as_mut().write_char('\\n');\n        }\n        event\n    }\n}\n\nimpl EventDataWriter {\n    // Assumption: underlying writer never returns an error:\n    // <https://docs.rs/bytes/latest/src/bytes/buf/writer.rs.html#79-82>\n    fn write_buf(&mut self, buf: &[u8]) -> usize {\n        if buf.is_empty() {\n            return 0;\n        }\n\n        let buffer = self.event.buffer.as_mut();\n\n        if !std::mem::replace(&mut self.data_written, true) {\n            if self.event.flags.contains(EventFlags::HAS_DATA) {\n                panic!(\"Called `Event::data*` multiple times\");\n            }\n\n            let _ = buffer.write_str(\"data: \");\n            self.event.flags.insert(EventFlags::HAS_DATA);\n        }\n\n        let mut writer = buffer.writer();\n\n        let mut last_split = 0;\n        for delimiter in memchr::memchr2_iter(b'\\n', b'\\r', buf) {\n            let _ = writer.write_all(&buf[last_split..=delimiter]);\n            let _ = writer.write_all(b\"data: \");\n            last_split = delimiter + 1;\n        }\n        let _ = writer.write_all(&buf[last_split..]);\n\n        buf.len()\n    }\n}\n\nimpl fmt::Write for EventDataWriter {\n    fn write_str(&mut self, s: &str) -> fmt::Result {\n        let _ = self.write_buf(s.as_bytes());\n        Ok(())\n    }\n}\n\nimpl Default for Event {\n    fn default() -> Self {\n        Self {\n            buffer: Buffer::Active(BytesMut::new()),\n            flags: EventFlags::from_bits(0),\n        }\n    }\n}\n\n#[derive(Debug, Copy, Clone, PartialEq)]\nstruct EventFlags(u8);\n\nimpl EventFlags {\n    const HAS_DATA: Self = Self::from_bits(0b0001);\n    const HAS_EVENT: Self = Self::from_bits(0b0010);\n    const HAS_RETRY: Self = Self::from_bits(0b0100);\n    const HAS_ID: Self = Self::from_bits(0b1000);\n\n    const fn bits(self) -> u8 {\n        self.0\n    }\n\n    const fn from_bits(bits: u8) -> Self {\n        Self(bits)\n    }\n\n    const fn contains(self, other: Self) -> bool {\n        self.bits() & other.bits() == other.bits()\n    }\n\n    fn insert(&mut self, other: Self) {\n        *self = Self::from_bits(self.bits() | other.bits());\n    }\n}\n\n/// Configure the interval between keep-alive messages, the content\n/// of each message, and the associated stream.\n#[derive(Debug, Clone)]\n#[must_use]\npub struct KeepAlive {\n    event: Event,\n    max_interval: Duration,\n}\n\nimpl KeepAlive {\n    /// Create a new `KeepAlive`.\n    pub fn new() -> Self {\n        Self {\n            event: Event::DEFAULT_KEEP_ALIVE,\n            max_interval: Duration::from_secs(15),\n        }\n    }\n\n    /// Customize the interval between keep-alive messages.\n    ///\n    /// Default is 15 seconds.\n    pub fn interval(mut self, time: Duration) -> Self {\n        self.max_interval = time;\n        self\n    }\n\n    /// Customize the text of the keep-alive message.\n    ///\n    /// Default is an empty comment.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `text` contains any newline or carriage returns, as they are not allowed in SSE\n    /// comments.\n    pub fn text<I>(self, text: I) -> Self\n    where\n        I: AsRef<str>,\n    {\n        self.event(Event::default().comment(text))\n    }\n\n    /// Customize the event of the keep-alive message.\n    ///\n    /// Default is an empty comment.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `event` contains any newline or carriage returns, as they are not allowed in SSE\n    /// comments.\n    pub fn event(mut self, event: Event) -> Self {\n        self.event = Event::finalized(event.finalize());\n        self\n    }\n}\n\nimpl Default for KeepAlive {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\n#[cfg(feature = \"tokio\")]\npin_project! {\n    /// A wrapper around a stream that produces keep-alive events\n    #[derive(Debug)]\n    pub struct KeepAliveStream<S> {\n        #[pin]\n        alive_timer: tokio::time::Sleep,\n        #[pin]\n        inner: S,\n        keep_alive: KeepAlive,\n    }\n}\n\n#[cfg(feature = \"tokio\")]\nimpl<S> KeepAliveStream<S> {\n    fn new(keep_alive: KeepAlive, inner: S) -> Self {\n        Self {\n            alive_timer: tokio::time::sleep(keep_alive.max_interval),\n            inner,\n            keep_alive,\n        }\n    }\n\n    fn reset(self: Pin<&mut Self>) {\n        let this = self.project();\n        this.alive_timer\n            .reset(tokio::time::Instant::now() + this.keep_alive.max_interval);\n    }\n}\n\n#[cfg(feature = \"tokio\")]\nimpl<S, E> Stream for KeepAliveStream<S>\nwhere\n    S: Stream<Item = Result<Event, E>>,\n{\n    type Item = Result<Event, E>;\n\n    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {\n        use std::future::Future;\n\n        let mut this = self.as_mut().project();\n\n        match this.inner.as_mut().poll_next(cx) {\n            Poll::Ready(Some(Ok(event))) => {\n                self.reset();\n\n                Poll::Ready(Some(Ok(event)))\n            }\n            Poll::Ready(Some(Err(error))) => Poll::Ready(Some(Err(error))),\n            Poll::Ready(None) => Poll::Ready(None),\n            Poll::Pending => {\n                ready!(this.alive_timer.poll(cx));\n\n                let event = this.keep_alive.event.clone();\n\n                self.reset();\n\n                Poll::Ready(Some(Ok(event)))\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{routing::get, test_helpers::*, Router};\n    use futures_util::stream;\n    use serde_json::value::RawValue;\n    use std::{collections::HashMap, convert::Infallible};\n    use tokio_stream::StreamExt as _;\n\n    #[test]\n    fn leading_space_is_not_stripped() {\n        let no_leading_space = Event::default().data(\"\\tfoobar\");\n        assert_eq!(&*no_leading_space.finalize(), b\"data: \\tfoobar\\n\\n\");\n\n        let leading_space = Event::default().data(\" foobar\");\n        assert_eq!(&*leading_space.finalize(), b\"data:  foobar\\n\\n\");\n    }\n\n    #[test]\n    fn write_data_writer_str() {\n        // also confirm that nop writers do nothing :)\n        let mut writer = Event::default()\n            .into_data_writer()\n            .into_event()\n            .into_data_writer();\n        writer.write_str(\"\").unwrap();\n        let mut writer = writer.into_event().into_data_writer();\n\n        writer.write_str(\"\").unwrap();\n        writer.write_str(\"moon \").unwrap();\n        writer.write_str(\"star\\nsun\").unwrap();\n        writer.write_str(\"\").unwrap();\n        writer.write_str(\"set\").unwrap();\n        writer.write_str(\"\").unwrap();\n        writer.write_str(\" bye\\r\").unwrap();\n\n        let event = writer.into_event();\n\n        assert_eq!(\n            &*event.finalize(),\n            b\"data: moon star\\ndata: sunset bye\\rdata: \\n\\n\"\n        );\n    }\n\n    #[test]\n    fn valid_json_raw_value_chars_handled() {\n        let json_string = \"{\\r\\\"foo\\\":  \\n\\r\\r   \\\"bar\\\\n\\\"\\n}\";\n        let json_raw_value_event = Event::default()\n            .json_data(serde_json::from_str::<&RawValue>(json_string).unwrap())\n            .unwrap();\n        assert_eq!(\n            &*json_raw_value_event.finalize(),\n            b\"data: {\\rdata: \\\"foo\\\":  \\ndata: \\rdata: \\rdata:    \\\"bar\\\\n\\\"\\ndata: }\\n\\n\"\n        );\n    }\n\n    #[crate::test]\n    async fn basic() {\n        let app = Router::new().route(\n            \"/\",\n            get(|| async {\n                let stream = stream::iter(vec![\n                    Event::default().data(\"one\").comment(\"this is a comment\"),\n                    Event::default()\n                        .json_data(serde_json::json!({ \"foo\": \"bar\" }))\n                        .unwrap(),\n                    Event::default()\n                        .event(\"three\")\n                        .retry(Duration::from_secs(30))\n                        .id(\"unique-id\"),\n                ])\n                .map(Ok::<_, Infallible>);\n                Sse::new(stream)\n            }),\n        );\n\n        let client = TestClient::new(app);\n        let mut stream = client.get(\"/\").await;\n\n        assert_eq!(stream.headers()[\"content-type\"], \"text/event-stream\");\n        assert_eq!(stream.headers()[\"cache-control\"], \"no-cache\");\n\n        let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n        assert_eq!(event_fields.get(\"data\").unwrap(), \"one\");\n        assert_eq!(event_fields.get(\"comment\").unwrap(), \"this is a comment\");\n\n        let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n        assert_eq!(event_fields.get(\"data\").unwrap(), \"{\\\"foo\\\":\\\"bar\\\"}\");\n        assert!(!event_fields.contains_key(\"comment\"));\n\n        let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n        assert_eq!(event_fields.get(\"event\").unwrap(), \"three\");\n        assert_eq!(event_fields.get(\"retry\").unwrap(), \"30000\");\n        assert_eq!(event_fields.get(\"id\").unwrap(), \"unique-id\");\n        assert!(!event_fields.contains_key(\"comment\"));\n\n        assert!(stream.chunk_text().await.is_none());\n    }\n\n    #[tokio::test(start_paused = true)]\n    async fn keep_alive() {\n        const DELAY: Duration = Duration::from_secs(5);\n\n        let app = Router::new().route(\n            \"/\",\n            get(|| async {\n                let stream = stream::repeat_with(|| Event::default().data(\"msg\"))\n                    .map(Ok::<_, Infallible>)\n                    .throttle(DELAY);\n\n                Sse::new(stream).keep_alive(\n                    KeepAlive::new()\n                        .interval(Duration::from_secs(1))\n                        .text(\"keep-alive-text\"),\n                )\n            }),\n        );\n\n        let client = TestClient::new(app);\n        let mut stream = client.get(\"/\").await;\n\n        for _ in 0..5 {\n            // first message should be an event\n            let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n            assert_eq!(event_fields.get(\"data\").unwrap(), \"msg\");\n\n            // then 4 seconds of keep-alive messages\n            for _ in 0..4 {\n                tokio::time::sleep(Duration::from_secs(1)).await;\n                let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n                assert_eq!(event_fields.get(\"comment\").unwrap(), \"keep-alive-text\");\n            }\n        }\n    }\n\n    #[tokio::test(start_paused = true)]\n    async fn keep_alive_ends_when_the_stream_ends() {\n        const DELAY: Duration = Duration::from_secs(5);\n\n        let app = Router::new().route(\n            \"/\",\n            get(|| async {\n                let stream = stream::repeat_with(|| Event::default().data(\"msg\"))\n                    .map(Ok::<_, Infallible>)\n                    .throttle(DELAY)\n                    .take(2);\n\n                Sse::new(stream).keep_alive(\n                    KeepAlive::new()\n                        .interval(Duration::from_secs(1))\n                        .text(\"keep-alive-text\"),\n                )\n            }),\n        );\n\n        let client = TestClient::new(app);\n        let mut stream = client.get(\"/\").await;\n\n        // first message should be an event\n        let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n        assert_eq!(event_fields.get(\"data\").unwrap(), \"msg\");\n\n        // then 4 seconds of keep-alive messages\n        for _ in 0..4 {\n            tokio::time::sleep(Duration::from_secs(1)).await;\n            let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n            assert_eq!(event_fields.get(\"comment\").unwrap(), \"keep-alive-text\");\n        }\n\n        // then the last event\n        let event_fields = parse_event(&stream.chunk_text().await.unwrap());\n        assert_eq!(event_fields.get(\"data\").unwrap(), \"msg\");\n\n        // then no more events or keep-alive messages\n        assert!(stream.chunk_text().await.is_none());\n    }\n\n    fn parse_event(payload: &str) -> HashMap<String, String> {\n        let mut fields = HashMap::new();\n\n        let mut lines = payload.lines().peekable();\n        while let Some(line) = lines.next() {\n            if line.is_empty() {\n                assert!(lines.next().is_none());\n                break;\n            }\n\n            let (mut key, value) = line.split_once(':').unwrap();\n            let value = value.trim();\n            if key.is_empty() {\n                key = \"comment\";\n            }\n            fields.insert(key.to_owned(), value.to_owned());\n        }\n\n        fields\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/future.rs",
    "content": "//! Future types.\n\npub use super::{\n    into_make_service::IntoMakeServiceFuture,\n    route::{InfallibleRouteFuture, RouteFuture},\n};\n"
  },
  {
    "path": "axum/src/routing/into_make_service.rs",
    "content": "use std::{\n    convert::Infallible,\n    future::ready,\n    task::{Context, Poll},\n};\nuse tower_service::Service;\n\n/// A [`MakeService`] that produces axum router services.\n///\n/// [`MakeService`]: tower::make::MakeService\n#[derive(Debug, Clone)]\npub struct IntoMakeService<S> {\n    svc: S,\n}\n\nimpl<S> IntoMakeService<S> {\n    pub(crate) fn new(svc: S) -> Self {\n        Self { svc }\n    }\n}\n\nimpl<S, T> Service<T> for IntoMakeService<S>\nwhere\n    S: Clone,\n{\n    type Response = S;\n    type Error = Infallible;\n    type Future = IntoMakeServiceFuture<S>;\n\n    #[inline]\n    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Poll::Ready(Ok(()))\n    }\n\n    fn call(&mut self, _target: T) -> Self::Future {\n        IntoMakeServiceFuture::new(ready(Ok(self.svc.clone())))\n    }\n}\n\nopaque_future! {\n    /// Response future for [`IntoMakeService`].\n    pub type IntoMakeServiceFuture<S> =\n        std::future::Ready<Result<S, Infallible>>;\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn traits() {\n        use crate::test_helpers::*;\n\n        assert_send::<IntoMakeService<()>>();\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/method_filter.rs",
    "content": "use http::Method;\nuse std::{\n    fmt,\n    fmt::{Debug, Formatter},\n};\n\n/// A filter that matches one or more HTTP methods.\n#[derive(Debug, Copy, Clone, PartialEq)]\npub struct MethodFilter(u16);\n\nimpl MethodFilter {\n    /// Match `CONNECT` requests.\n    ///\n    /// This is useful for implementing HTTP/2's [extended CONNECT method],\n    /// in which the `:protocol` pseudoheader is read\n    /// (using [`hyper::ext::Protocol`])\n    /// and the connection upgraded to a bidirectional byte stream\n    /// (using [`hyper::upgrade::on`]).\n    ///\n    /// As seen in the [HTTP Upgrade Token Registry],\n    /// common uses include WebSockets and proxying UDP or IP –\n    /// though note that when using [`WebSocketUpgrade`]\n    /// it's more useful to use [`any`](crate::routing::any)\n    /// as HTTP/1.1 WebSockets need to support `GET`.\n    ///\n    /// [extended CONNECT]: https://www.rfc-editor.org/rfc/rfc8441.html#section-4\n    /// [HTTP Upgrade Token Registry]: https://www.iana.org/assignments/http-upgrade-tokens/http-upgrade-tokens.xhtml\n    /// [`WebSocketUpgrade`]: crate::extract::WebSocketUpgrade\n    pub const CONNECT: Self = Self::from_bits(0b0_0000_0001);\n    /// Match `DELETE` requests.\n    pub const DELETE: Self = Self::from_bits(0b0_0000_0010);\n    /// Match `GET` requests.\n    pub const GET: Self = Self::from_bits(0b0_0000_0100);\n    /// Match `HEAD` requests.\n    pub const HEAD: Self = Self::from_bits(0b0_0000_1000);\n    /// Match `OPTIONS` requests.\n    pub const OPTIONS: Self = Self::from_bits(0b0_0001_0000);\n    /// Match `PATCH` requests.\n    pub const PATCH: Self = Self::from_bits(0b0_0010_0000);\n    /// Match `POST` requests.\n    pub const POST: Self = Self::from_bits(0b0_0100_0000);\n    /// Match `PUT` requests.\n    pub const PUT: Self = Self::from_bits(0b0_1000_0000);\n    /// Match `TRACE` requests.\n    pub const TRACE: Self = Self::from_bits(0b1_0000_0000);\n\n    const fn bits(self) -> u16 {\n        let bits = self;\n        bits.0\n    }\n\n    const fn from_bits(bits: u16) -> Self {\n        Self(bits)\n    }\n\n    pub(crate) const fn contains(self, other: Self) -> bool {\n        self.bits() & other.bits() == other.bits()\n    }\n\n    /// Performs the OR operation between the [`MethodFilter`] in `self` with `other`.\n    #[must_use]\n    pub const fn or(self, other: Self) -> Self {\n        Self(self.0 | other.0)\n    }\n}\n\n/// Error type used when converting a [`Method`] to a [`MethodFilter`] fails.\n#[derive(Debug)]\npub struct NoMatchingMethodFilter {\n    method: Method,\n}\n\nimpl NoMatchingMethodFilter {\n    /// Get the [`Method`] that couldn't be converted to a [`MethodFilter`].\n    pub fn method(&self) -> &Method {\n        &self.method\n    }\n}\n\nimpl fmt::Display for NoMatchingMethodFilter {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        write!(f, \"no `MethodFilter` for `{}`\", self.method.as_str())\n    }\n}\n\nimpl std::error::Error for NoMatchingMethodFilter {}\n\nimpl TryFrom<Method> for MethodFilter {\n    type Error = NoMatchingMethodFilter;\n\n    fn try_from(m: Method) -> Result<Self, NoMatchingMethodFilter> {\n        match m {\n            Method::CONNECT => Ok(Self::CONNECT),\n            Method::DELETE => Ok(Self::DELETE),\n            Method::GET => Ok(Self::GET),\n            Method::HEAD => Ok(Self::HEAD),\n            Method::OPTIONS => Ok(Self::OPTIONS),\n            Method::PATCH => Ok(Self::PATCH),\n            Method::POST => Ok(Self::POST),\n            Method::PUT => Ok(Self::PUT),\n            Method::TRACE => Ok(Self::TRACE),\n            other => Err(NoMatchingMethodFilter { method: other }),\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn from_http_method() {\n        assert_eq!(\n            MethodFilter::try_from(Method::CONNECT).unwrap(),\n            MethodFilter::CONNECT\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::DELETE).unwrap(),\n            MethodFilter::DELETE\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::GET).unwrap(),\n            MethodFilter::GET\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::HEAD).unwrap(),\n            MethodFilter::HEAD\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::OPTIONS).unwrap(),\n            MethodFilter::OPTIONS\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::PATCH).unwrap(),\n            MethodFilter::PATCH\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::POST).unwrap(),\n            MethodFilter::POST\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::PUT).unwrap(),\n            MethodFilter::PUT\n        );\n\n        assert_eq!(\n            MethodFilter::try_from(Method::TRACE).unwrap(),\n            MethodFilter::TRACE\n        );\n\n        assert!(\n            MethodFilter::try_from(http::Method::from_bytes(b\"CUSTOM\").unwrap())\n                .unwrap_err()\n                .to_string()\n                .contains(\"CUSTOM\")\n        );\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/method_routing.rs",
    "content": "//! Route to services and handlers based on HTTP methods.\n\nuse super::{future::InfallibleRouteFuture, IntoMakeService};\n#[cfg(feature = \"tokio\")]\nuse crate::extract::connect_info::IntoMakeServiceWithConnectInfo;\nuse crate::{\n    body::{Body, Bytes, HttpBody},\n    boxed::BoxedIntoRoute,\n    error_handling::{HandleError, HandleErrorLayer},\n    handler::Handler,\n    http::{Method, StatusCode},\n    response::Response,\n    routing::{future::RouteFuture, Fallback, MethodFilter, Route},\n};\nuse axum_core::{extract::Request, response::IntoResponse, BoxError};\nuse bytes::BytesMut;\nuse std::{\n    borrow::Cow,\n    convert::Infallible,\n    fmt,\n    task::{Context, Poll},\n};\nuse tower::service_fn;\nuse tower_layer::Layer;\nuse tower_service::Service;\n\nmacro_rules! top_level_service_fn {\n    (\n        $name:ident, GET\n    ) => {\n        top_level_service_fn!(\n            /// Route `GET` requests to the given service.\n            ///\n            /// # Example\n            ///\n            /// ```rust\n            /// use axum::{\n            ///     extract::Request,\n            ///     Router,\n            ///     routing::get_service,\n            ///     body::Body,\n            /// };\n            /// use http::Response;\n            /// use std::convert::Infallible;\n            ///\n            /// let service = tower::service_fn(|request: Request| async {\n            ///     Ok::<_, Infallible>(Response::new(Body::empty()))\n            /// });\n            ///\n            /// // Requests to `GET /` will go to `service`.\n            /// let app = Router::new().route(\"/\", get_service(service));\n            /// # let _: Router = app;\n            /// ```\n            ///\n            /// Note that `get` routes will also be called for `HEAD` requests but will have\n            /// the response body removed. Make sure to add explicit `HEAD` routes\n            /// afterwards.\n            $name,\n            GET\n        );\n    };\n\n    (\n        $name:ident, CONNECT\n    ) => {\n        top_level_service_fn!(\n            /// Route `CONNECT` requests to the given service.\n            ///\n            /// See [`MethodFilter::CONNECT`] for when you'd want to use this,\n            /// and [`get_service`] for an example.\n            $name,\n            CONNECT\n        );\n    };\n\n    (\n        $name:ident, $method:ident\n    ) => {\n        top_level_service_fn!(\n            #[doc = concat!(\"Route `\", stringify!($method) ,\"` requests to the given service.\")]\n            ///\n            /// See [`get_service`] for an example.\n            $name,\n            $method\n        );\n    };\n\n    (\n        $(#[$m:meta])+\n        $name:ident, $method:ident\n    ) => {\n        $(#[$m])+\n        pub fn $name<T, S>(svc: T) -> MethodRouter<S, T::Error>\n        where\n            T: Service<Request> + Clone + Send + Sync + 'static,\n            T::Response: IntoResponse + 'static,\n            T::Future: Send + 'static,\n            S: Clone,\n        {\n            on_service(MethodFilter::$method, svc)\n        }\n    };\n}\n\nmacro_rules! top_level_handler_fn {\n    (\n        $name:ident, GET\n    ) => {\n        top_level_handler_fn!(\n            /// Route `GET` requests to the given handler.\n            ///\n            /// # Example\n            ///\n            /// ```rust\n            /// use axum::{\n            ///     routing::get,\n            ///     Router,\n            /// };\n            ///\n            /// async fn handler() {}\n            ///\n            /// // Requests to `GET /` will go to `handler`.\n            /// let app = Router::new().route(\"/\", get(handler));\n            /// # let _: Router = app;\n            /// ```\n            ///\n            /// Note that `get` routes will also be called for `HEAD` requests but will have\n            /// the response body removed. Make sure to add explicit `HEAD` routes\n            /// afterwards.\n            $name,\n            GET\n        );\n    };\n\n    (\n        $name:ident, CONNECT\n    ) => {\n        top_level_handler_fn!(\n            /// Route `CONNECT` requests to the given handler.\n            ///\n            /// See [`MethodFilter::CONNECT`] for when you'd want to use this,\n            /// and [`get`] for an example.\n            $name,\n            CONNECT\n        );\n    };\n\n    (\n        $name:ident, $method:ident\n    ) => {\n        top_level_handler_fn!(\n            #[doc = concat!(\"Route `\", stringify!($method) ,\"` requests to the given handler.\")]\n            ///\n            /// See [`get`] for an example.\n            $name,\n            $method\n        );\n    };\n\n    (\n        $(#[$m:meta])+\n        $name:ident, $method:ident\n    ) => {\n        $(#[$m])+\n        pub fn $name<H, T, S>(handler: H) -> MethodRouter<S, Infallible>\n        where\n            H: Handler<T, S>,\n            T: 'static,\n            S: Clone + Send + Sync + 'static,\n        {\n            on(MethodFilter::$method, handler)\n        }\n    };\n}\n\nmacro_rules! chained_service_fn {\n    (\n        $name:ident, GET\n    ) => {\n        chained_service_fn!(\n            /// Chain an additional service that will only accept `GET` requests.\n            ///\n            /// # Example\n            ///\n            /// ```rust\n            /// use axum::{\n            ///     extract::Request,\n            ///     Router,\n            ///     routing::post_service,\n            ///     body::Body,\n            /// };\n            /// use http::Response;\n            /// use std::convert::Infallible;\n            ///\n            /// let service = tower::service_fn(|request: Request| async {\n            ///     Ok::<_, Infallible>(Response::new(Body::empty()))\n            /// });\n            ///\n            /// let other_service = tower::service_fn(|request: Request| async {\n            ///     Ok::<_, Infallible>(Response::new(Body::empty()))\n            /// });\n            ///\n            /// // Requests to `POST /` will go to `service` and `GET /` will go to\n            /// // `other_service`.\n            /// let app = Router::new().route(\"/\", post_service(service).get_service(other_service));\n            /// # let _: Router = app;\n            /// ```\n            ///\n            /// Note that `get` routes will also be called for `HEAD` requests but will have\n            /// the response body removed. Make sure to add explicit `HEAD` routes\n            /// afterwards.\n            $name,\n            GET\n        );\n    };\n\n    (\n        $name:ident, CONNECT\n    ) => {\n        chained_service_fn!(\n            /// Chain an additional service that will only accept `CONNECT` requests.\n            ///\n            /// See [`MethodFilter::CONNECT`] for when you'd want to use this,\n            /// and [`MethodRouter::get_service`] for an example.\n            $name,\n            CONNECT\n        );\n    };\n\n    (\n        $name:ident, $method:ident\n    ) => {\n        chained_service_fn!(\n            #[doc = concat!(\"Chain an additional service that will only accept `\", stringify!($method),\"` requests.\")]\n            ///\n            /// See [`MethodRouter::get_service`] for an example.\n            $name,\n            $method\n        );\n    };\n\n    (\n        $(#[$m:meta])+\n        $name:ident, $method:ident\n    ) => {\n        $(#[$m])+\n        #[track_caller]\n        pub fn $name<T>(self, svc: T) -> Self\n        where\n            T: Service<Request, Error = E>\n                + Clone\n                + Send\n                + Sync\n                + 'static,\n            T::Response: IntoResponse + 'static,\n            T::Future: Send + 'static,\n        {\n            self.on_service(MethodFilter::$method, svc)\n        }\n    };\n}\n\nmacro_rules! chained_handler_fn {\n    (\n        $name:ident, GET\n    ) => {\n        chained_handler_fn!(\n            /// Chain an additional handler that will only accept `GET` requests.\n            ///\n            /// # Example\n            ///\n            /// ```rust\n            /// use axum::{routing::post, Router};\n            ///\n            /// async fn handler() {}\n            ///\n            /// async fn other_handler() {}\n            ///\n            /// // Requests to `POST /` will go to `handler` and `GET /` will go to\n            /// // `other_handler`.\n            /// let app = Router::new().route(\"/\", post(handler).get(other_handler));\n            /// # let _: Router = app;\n            /// ```\n            ///\n            /// Note that `get` routes will also be called for `HEAD` requests but will have\n            /// the response body removed. Make sure to add explicit `HEAD` routes\n            /// afterwards.\n            $name,\n            GET\n        );\n    };\n\n    (\n        $name:ident, CONNECT\n    ) => {\n        chained_handler_fn!(\n            /// Chain an additional handler that will only accept `CONNECT` requests.\n            ///\n            /// See [`MethodFilter::CONNECT`] for when you'd want to use this,\n            /// and [`MethodRouter::get`] for an example.\n            $name,\n            CONNECT\n        );\n    };\n\n    (\n        $name:ident, $method:ident\n    ) => {\n        chained_handler_fn!(\n            #[doc = concat!(\"Chain an additional handler that will only accept `\", stringify!($method),\"` requests.\")]\n            ///\n            /// See [`MethodRouter::get`] for an example.\n            $name,\n            $method\n        );\n    };\n\n    (\n        $(#[$m:meta])+\n        $name:ident, $method:ident\n    ) => {\n        $(#[$m])+\n        #[track_caller]\n        pub fn $name<H, T>(self, handler: H) -> Self\n        where\n            H: Handler<T, S>,\n            T: 'static,\n            S: Send + Sync + 'static,\n        {\n            self.on(MethodFilter::$method, handler)\n        }\n    };\n}\n\ntop_level_service_fn!(connect_service, CONNECT);\ntop_level_service_fn!(delete_service, DELETE);\ntop_level_service_fn!(get_service, GET);\ntop_level_service_fn!(head_service, HEAD);\ntop_level_service_fn!(options_service, OPTIONS);\ntop_level_service_fn!(patch_service, PATCH);\ntop_level_service_fn!(post_service, POST);\ntop_level_service_fn!(put_service, PUT);\ntop_level_service_fn!(trace_service, TRACE);\n\n/// Route requests with the given method to the service.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     extract::Request,\n///     routing::on,\n///     Router,\n///     body::Body,\n///     routing::{MethodFilter, on_service},\n/// };\n/// use http::Response;\n/// use std::convert::Infallible;\n///\n/// let service = tower::service_fn(|request: Request| async {\n///     Ok::<_, Infallible>(Response::new(Body::empty()))\n/// });\n///\n/// // Requests to `POST /` will go to `service`.\n/// let app = Router::new().route(\"/\", on_service(MethodFilter::POST, service));\n/// # let _: Router = app;\n/// ```\npub fn on_service<T, S>(filter: MethodFilter, svc: T) -> MethodRouter<S, T::Error>\nwhere\n    T: Service<Request> + Clone + Send + Sync + 'static,\n    T::Response: IntoResponse + 'static,\n    T::Future: Send + 'static,\n    S: Clone,\n{\n    MethodRouter::new().on_service(filter, svc)\n}\n\n/// Route requests to the given service regardless of its method.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     extract::Request,\n///     Router,\n///     routing::any_service,\n///     body::Body,\n/// };\n/// use http::Response;\n/// use std::convert::Infallible;\n///\n/// let service = tower::service_fn(|request: Request| async {\n///     Ok::<_, Infallible>(Response::new(Body::empty()))\n/// });\n///\n/// // All requests to `/` will go to `service`.\n/// let app = Router::new().route(\"/\", any_service(service));\n/// # let _: Router = app;\n/// ```\n///\n/// Additional methods can still be chained:\n///\n/// ```rust\n/// use axum::{\n///     extract::Request,\n///     Router,\n///     routing::any_service,\n///     body::Body,\n/// };\n/// use http::Response;\n/// use std::convert::Infallible;\n///\n/// let service = tower::service_fn(|request: Request| async {\n///     # Ok::<_, Infallible>(Response::new(Body::empty()))\n///     // ...\n/// });\n///\n/// let other_service = tower::service_fn(|request: Request| async {\n///     # Ok::<_, Infallible>(Response::new(Body::empty()))\n///     // ...\n/// });\n///\n/// // `POST /` goes to `other_service`. All other requests go to `service`\n/// let app = Router::new().route(\"/\", any_service(service).post_service(other_service));\n/// # let _: Router = app;\n/// ```\npub fn any_service<T, S>(svc: T) -> MethodRouter<S, T::Error>\nwhere\n    T: Service<Request> + Clone + Send + Sync + 'static,\n    T::Response: IntoResponse + 'static,\n    T::Future: Send + 'static,\n    S: Clone,\n{\n    MethodRouter::new()\n        .fallback_service(svc)\n        .skip_allow_header()\n}\n\ntop_level_handler_fn!(connect, CONNECT);\ntop_level_handler_fn!(delete, DELETE);\ntop_level_handler_fn!(get, GET);\ntop_level_handler_fn!(head, HEAD);\ntop_level_handler_fn!(options, OPTIONS);\ntop_level_handler_fn!(patch, PATCH);\ntop_level_handler_fn!(post, POST);\ntop_level_handler_fn!(put, PUT);\ntop_level_handler_fn!(trace, TRACE);\n\n/// Route requests with the given method to the handler.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     routing::on,\n///     Router,\n///     routing::MethodFilter,\n/// };\n///\n/// async fn handler() {}\n///\n/// // Requests to `POST /` will go to `handler`.\n/// let app = Router::new().route(\"/\", on(MethodFilter::POST, handler));\n/// # let _: Router = app;\n/// ```\npub fn on<H, T, S>(filter: MethodFilter, handler: H) -> MethodRouter<S, Infallible>\nwhere\n    H: Handler<T, S>,\n    T: 'static,\n    S: Clone + Send + Sync + 'static,\n{\n    MethodRouter::new().on(filter, handler)\n}\n\n/// Route requests with the given handler regardless of the method.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     routing::any,\n///     Router,\n/// };\n///\n/// async fn handler() {}\n///\n/// // All requests to `/` will go to `handler`.\n/// let app = Router::new().route(\"/\", any(handler));\n/// # let _: Router = app;\n/// ```\n///\n/// Additional methods can still be chained:\n///\n/// ```rust\n/// use axum::{\n///     routing::any,\n///     Router,\n/// };\n///\n/// async fn handler() {}\n///\n/// async fn other_handler() {}\n///\n/// // `POST /` goes to `other_handler`. All other requests go to `handler`\n/// let app = Router::new().route(\"/\", any(handler).post(other_handler));\n/// # let _: Router = app;\n/// ```\npub fn any<H, T, S>(handler: H) -> MethodRouter<S, Infallible>\nwhere\n    H: Handler<T, S>,\n    T: 'static,\n    S: Clone + Send + Sync + 'static,\n{\n    MethodRouter::new().fallback(handler).skip_allow_header()\n}\n\n/// A [`Service`] that accepts requests based on a [`MethodFilter`] and\n/// allows chaining additional handlers and services.\n///\n/// # When does `MethodRouter` implement [`Service`]?\n///\n/// Whether or not `MethodRouter` implements [`Service`] depends on the state type it requires.\n///\n/// ```\n/// use tower::Service;\n/// use axum::{routing::get, extract::{State, Request}, body::Body};\n///\n/// // this `MethodRouter` doesn't require any state, i.e. the state is `()`,\n/// let method_router = get(|| async {});\n/// // and thus it implements `Service`\n/// assert_service(method_router);\n///\n/// // this requires a `String` and doesn't implement `Service`\n/// let method_router = get(|_: State<String>| async {});\n/// // until you provide the `String` with `.with_state(...)`\n/// let method_router_with_state = method_router.with_state(String::new());\n/// // and then it implements `Service`\n/// assert_service(method_router_with_state);\n///\n/// // helper to check that a value implements `Service`\n/// fn assert_service<S>(service: S)\n/// where\n///     S: Service<Request>,\n/// {}\n/// ```\n#[must_use]\npub struct MethodRouter<S = (), E = Infallible> {\n    get: MethodEndpoint<S, E>,\n    head: MethodEndpoint<S, E>,\n    delete: MethodEndpoint<S, E>,\n    options: MethodEndpoint<S, E>,\n    patch: MethodEndpoint<S, E>,\n    post: MethodEndpoint<S, E>,\n    put: MethodEndpoint<S, E>,\n    trace: MethodEndpoint<S, E>,\n    connect: MethodEndpoint<S, E>,\n    fallback: Fallback<S, E>,\n    allow_header: AllowHeader,\n}\n\n#[derive(Clone, Debug)]\nenum AllowHeader {\n    /// No `Allow` header value has been built-up yet. This is the default state\n    None,\n    /// Don't set an `Allow` header. This is used when `any` or `any_service` are called.\n    Skip,\n    /// The current value of the `Allow` header.\n    Bytes(BytesMut),\n}\n\nimpl AllowHeader {\n    fn merge(self, other: Self) -> Self {\n        match (self, other) {\n            (Self::Skip, _) | (_, Self::Skip) => Self::Skip,\n            (Self::None, Self::None) => Self::None,\n            (Self::None, Self::Bytes(pick)) | (Self::Bytes(pick), Self::None) => Self::Bytes(pick),\n            (Self::Bytes(mut a), Self::Bytes(b)) => {\n                a.extend_from_slice(b\",\");\n                a.extend_from_slice(&b);\n                Self::Bytes(a)\n            }\n        }\n    }\n}\n\nimpl<S, E> fmt::Debug for MethodRouter<S, E> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"MethodRouter\")\n            .field(\"get\", &self.get)\n            .field(\"head\", &self.head)\n            .field(\"delete\", &self.delete)\n            .field(\"options\", &self.options)\n            .field(\"patch\", &self.patch)\n            .field(\"post\", &self.post)\n            .field(\"put\", &self.put)\n            .field(\"trace\", &self.trace)\n            .field(\"connect\", &self.connect)\n            .field(\"fallback\", &self.fallback)\n            .field(\"allow_header\", &self.allow_header)\n            .finish()\n    }\n}\n\nimpl<S> MethodRouter<S, Infallible>\nwhere\n    S: Clone,\n{\n    /// Chain an additional handler that will accept requests matching the given\n    /// `MethodFilter`.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     routing::get,\n    ///     Router,\n    ///     routing::MethodFilter\n    /// };\n    ///\n    /// async fn handler() {}\n    ///\n    /// async fn other_handler() {}\n    ///\n    /// // Requests to `GET /` will go to `handler` and `DELETE /` will go to\n    /// // `other_handler`\n    /// let app = Router::new().route(\"/\", get(handler).on(MethodFilter::DELETE, other_handler));\n    /// # let _: Router = app;\n    /// ```\n    #[track_caller]\n    pub fn on<H, T>(self, filter: MethodFilter, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n        S: Send + Sync + 'static,\n    {\n        self.on_endpoint(\n            filter,\n            &MethodEndpoint::BoxedHandler(BoxedIntoRoute::from_handler(handler)),\n        )\n    }\n\n    chained_handler_fn!(connect, CONNECT);\n    chained_handler_fn!(delete, DELETE);\n    chained_handler_fn!(get, GET);\n    chained_handler_fn!(head, HEAD);\n    chained_handler_fn!(options, OPTIONS);\n    chained_handler_fn!(patch, PATCH);\n    chained_handler_fn!(post, POST);\n    chained_handler_fn!(put, PUT);\n    chained_handler_fn!(trace, TRACE);\n\n    /// Add a fallback [`Handler`] to the router.\n    pub fn fallback<H, T>(mut self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n        S: Send + Sync + 'static,\n    {\n        self.fallback = Fallback::BoxedHandler(BoxedIntoRoute::from_handler(handler));\n        self\n    }\n\n    /// Get a [`MethodFilter`] for the methods that this `MethodRouter` has\n    /// custom code for.\n    ///\n    /// Note that `MethodRouter`'s [`Service`] implementation never fails (it\n    /// always creates an HTTP response) based on which HTTP method was used.\n    /// However, the information which methods have the default behavior of\n    /// returning HTTP 405 is stored, and can be queried with this method.\n    ///\n    /// Returns `None` if the `MethodRouter` was constructed with [`any`] or\n    /// has had a [`fallback`][Self::fallback] set.\n    pub fn method_filter(&self) -> Option<MethodFilter> {\n        let Self {\n            get,\n            head,\n            delete,\n            options,\n            patch,\n            post,\n            put,\n            trace,\n            connect,\n            fallback,\n            allow_header: _,\n        } = self;\n\n        if !fallback.is_default() {\n            return None;\n        }\n\n        let filter = [\n            (get, MethodFilter::GET),\n            (head, MethodFilter::HEAD),\n            (delete, MethodFilter::DELETE),\n            (options, MethodFilter::OPTIONS),\n            (patch, MethodFilter::PATCH),\n            (post, MethodFilter::POST),\n            (put, MethodFilter::PUT),\n            (trace, MethodFilter::TRACE),\n            (connect, MethodFilter::CONNECT),\n        ]\n        .into_iter()\n        .filter_map(|(ep, f)| ep.is_some().then_some(f))\n        .reduce(MethodFilter::or)\n        .expect(\"can't create a MethodRouter with all-default handlers\");\n\n        Some(filter)\n    }\n\n    /// Add a fallback [`Handler`] if no custom one has been provided.\n    pub(crate) fn default_fallback<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n        S: Send + Sync + 'static,\n    {\n        match self.fallback {\n            Fallback::Default(_) => self.fallback(handler),\n            _ => self,\n        }\n    }\n}\n\nimpl MethodRouter<(), Infallible> {\n    /// Convert the router into a [`MakeService`].\n    ///\n    /// This allows you to serve a single `MethodRouter` if you don't need any\n    /// routing based on the path:\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     handler::Handler,\n    ///     http::{Uri, Method},\n    ///     response::IntoResponse,\n    ///     routing::get,\n    /// };\n    /// use std::net::SocketAddr;\n    ///\n    /// async fn handler(method: Method, uri: Uri, body: String) -> String {\n    ///     format!(\"received `{method} {uri}` with body `{body:?}`\")\n    /// }\n    ///\n    /// let router = get(handler).post(handler);\n    ///\n    /// # async {\n    /// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    /// axum::serve(listener, router.into_make_service()).await;\n    /// # };\n    /// ```\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    #[must_use]\n    pub fn into_make_service(self) -> IntoMakeService<Self> {\n        IntoMakeService::new(self.with_state(()))\n    }\n\n    /// Convert the router into a [`MakeService`] which stores information\n    /// about the incoming connection.\n    ///\n    /// See [`Router::into_make_service_with_connect_info`] for more details.\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     handler::Handler,\n    ///     response::IntoResponse,\n    ///     extract::ConnectInfo,\n    ///     routing::get,\n    /// };\n    /// use std::net::SocketAddr;\n    ///\n    /// async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {\n    ///     format!(\"Hello {addr}\")\n    /// }\n    ///\n    /// let router = get(handler).post(handler);\n    ///\n    /// # async {\n    /// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    /// axum::serve(listener, router.into_make_service()).await;\n    /// # };\n    /// ```\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    /// [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info\n    #[cfg(feature = \"tokio\")]\n    #[must_use]\n    pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {\n        IntoMakeServiceWithConnectInfo::new(self.with_state(()))\n    }\n}\n\nimpl<S, E> MethodRouter<S, E>\nwhere\n    S: Clone,\n{\n    /// Create a default `MethodRouter` that will respond with `405 Method Not Allowed` to all\n    /// requests.\n    pub fn new() -> Self {\n        let fallback = Route::new(service_fn(|_: Request| async {\n            Ok(StatusCode::METHOD_NOT_ALLOWED)\n        }));\n\n        Self {\n            get: MethodEndpoint::None,\n            head: MethodEndpoint::None,\n            delete: MethodEndpoint::None,\n            options: MethodEndpoint::None,\n            patch: MethodEndpoint::None,\n            post: MethodEndpoint::None,\n            put: MethodEndpoint::None,\n            trace: MethodEndpoint::None,\n            connect: MethodEndpoint::None,\n            allow_header: AllowHeader::None,\n            fallback: Fallback::Default(fallback),\n        }\n    }\n\n    /// Provide the state for the router.\n    pub fn with_state<S2>(self, state: S) -> MethodRouter<S2, E> {\n        MethodRouter {\n            get: self.get.with_state(&state),\n            head: self.head.with_state(&state),\n            delete: self.delete.with_state(&state),\n            options: self.options.with_state(&state),\n            patch: self.patch.with_state(&state),\n            post: self.post.with_state(&state),\n            put: self.put.with_state(&state),\n            trace: self.trace.with_state(&state),\n            connect: self.connect.with_state(&state),\n            allow_header: self.allow_header,\n            fallback: self.fallback.with_state(state),\n        }\n    }\n\n    /// Chain an additional service that will accept requests matching the given\n    /// `MethodFilter`.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     extract::Request,\n    ///     Router,\n    ///     routing::{MethodFilter, on_service},\n    ///     body::Body,\n    /// };\n    /// use http::Response;\n    /// use std::convert::Infallible;\n    ///\n    /// let service = tower::service_fn(|request: Request| async {\n    ///     Ok::<_, Infallible>(Response::new(Body::empty()))\n    /// });\n    ///\n    /// // Requests to `DELETE /` will go to `service`\n    /// let app = Router::new().route(\"/\", on_service(MethodFilter::DELETE, service));\n    /// # let _: Router = app;\n    /// ```\n    #[track_caller]\n    pub fn on_service<T>(self, filter: MethodFilter, svc: T) -> Self\n    where\n        T: Service<Request, Error = E> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse + 'static,\n        T::Future: Send + 'static,\n    {\n        self.on_endpoint(filter, &MethodEndpoint::Route(Route::new(svc)))\n    }\n\n    #[track_caller]\n    fn on_endpoint(mut self, filter: MethodFilter, endpoint: &MethodEndpoint<S, E>) -> Self {\n        // written as a separate function to generate less IR\n        #[track_caller]\n        fn set_endpoint<S, E>(\n            method_name: &str,\n            out: &mut MethodEndpoint<S, E>,\n            endpoint: &MethodEndpoint<S, E>,\n            endpoint_filter: MethodFilter,\n            filter: MethodFilter,\n            allow_header: &mut AllowHeader,\n            methods: &[&'static str],\n        ) where\n            MethodEndpoint<S, E>: Clone,\n            S: Clone,\n        {\n            if endpoint_filter.contains(filter) {\n                if out.is_some() {\n                    panic!(\n                        \"Overlapping method route. Cannot add two method routes that both handle \\\n                         `{method_name}`\",\n                    );\n                }\n                *out = endpoint.clone();\n                for method in methods {\n                    append_allow_header(allow_header, method);\n                }\n            }\n        }\n\n        set_endpoint(\n            \"GET\",\n            &mut self.get,\n            endpoint,\n            filter,\n            MethodFilter::GET,\n            &mut self.allow_header,\n            &[\"GET\", \"HEAD\"],\n        );\n\n        set_endpoint(\n            \"HEAD\",\n            &mut self.head,\n            endpoint,\n            filter,\n            MethodFilter::HEAD,\n            &mut self.allow_header,\n            &[\"HEAD\"],\n        );\n\n        set_endpoint(\n            \"TRACE\",\n            &mut self.trace,\n            endpoint,\n            filter,\n            MethodFilter::TRACE,\n            &mut self.allow_header,\n            &[\"TRACE\"],\n        );\n\n        set_endpoint(\n            \"PUT\",\n            &mut self.put,\n            endpoint,\n            filter,\n            MethodFilter::PUT,\n            &mut self.allow_header,\n            &[\"PUT\"],\n        );\n\n        set_endpoint(\n            \"POST\",\n            &mut self.post,\n            endpoint,\n            filter,\n            MethodFilter::POST,\n            &mut self.allow_header,\n            &[\"POST\"],\n        );\n\n        set_endpoint(\n            \"PATCH\",\n            &mut self.patch,\n            endpoint,\n            filter,\n            MethodFilter::PATCH,\n            &mut self.allow_header,\n            &[\"PATCH\"],\n        );\n\n        set_endpoint(\n            \"OPTIONS\",\n            &mut self.options,\n            endpoint,\n            filter,\n            MethodFilter::OPTIONS,\n            &mut self.allow_header,\n            &[\"OPTIONS\"],\n        );\n\n        set_endpoint(\n            \"DELETE\",\n            &mut self.delete,\n            endpoint,\n            filter,\n            MethodFilter::DELETE,\n            &mut self.allow_header,\n            &[\"DELETE\"],\n        );\n\n        set_endpoint(\n            \"CONNECT\",\n            &mut self.connect,\n            endpoint,\n            filter,\n            MethodFilter::CONNECT,\n            &mut self.allow_header,\n            &[\"CONNECT\"],\n        );\n\n        self\n    }\n\n    chained_service_fn!(connect_service, CONNECT);\n    chained_service_fn!(delete_service, DELETE);\n    chained_service_fn!(get_service, GET);\n    chained_service_fn!(head_service, HEAD);\n    chained_service_fn!(options_service, OPTIONS);\n    chained_service_fn!(patch_service, PATCH);\n    chained_service_fn!(post_service, POST);\n    chained_service_fn!(put_service, PUT);\n    chained_service_fn!(trace_service, TRACE);\n\n    #[doc = include_str!(\"../docs/method_routing/fallback.md\")]\n    pub fn fallback_service<T>(mut self, svc: T) -> Self\n    where\n        T: Service<Request, Error = E> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse + 'static,\n        T::Future: Send + 'static,\n    {\n        self.fallback = Fallback::Service(Route::new(svc));\n        self\n    }\n\n    #[doc = include_str!(\"../docs/method_routing/layer.md\")]\n    pub fn layer<L, NewError>(self, layer: L) -> MethodRouter<S, NewError>\n    where\n        L: Layer<Route<E>> + Clone + Send + Sync + 'static,\n        L::Service: Service<Request> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Error: Into<NewError> + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n        E: 'static,\n        S: 'static,\n        NewError: 'static,\n    {\n        let layer_fn = move |route: Route<E>| route.layer(layer.clone());\n\n        MethodRouter {\n            get: self.get.map(layer_fn.clone()),\n            head: self.head.map(layer_fn.clone()),\n            delete: self.delete.map(layer_fn.clone()),\n            options: self.options.map(layer_fn.clone()),\n            patch: self.patch.map(layer_fn.clone()),\n            post: self.post.map(layer_fn.clone()),\n            put: self.put.map(layer_fn.clone()),\n            trace: self.trace.map(layer_fn.clone()),\n            connect: self.connect.map(layer_fn.clone()),\n            fallback: self.fallback.map(layer_fn),\n            allow_header: self.allow_header,\n        }\n    }\n\n    #[doc = include_str!(\"../docs/method_routing/route_layer.md\")]\n    #[track_caller]\n    pub fn route_layer<L>(mut self, layer: L) -> Self\n    where\n        L: Layer<Route<E>> + Clone + Send + Sync + 'static,\n        L::Service: Service<Request, Error = E> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n        E: 'static,\n        S: 'static,\n    {\n        if self.get.is_none()\n            && self.head.is_none()\n            && self.delete.is_none()\n            && self.options.is_none()\n            && self.patch.is_none()\n            && self.post.is_none()\n            && self.put.is_none()\n            && self.trace.is_none()\n            && self.connect.is_none()\n        {\n            panic!(\n                \"Adding a route_layer before any routes is a no-op. \\\n                 Add the routes you want the layer to apply to first.\"\n            );\n        }\n\n        let layer_fn = move |svc| Route::new(layer.layer(svc));\n\n        self.get = self.get.map(layer_fn.clone());\n        self.head = self.head.map(layer_fn.clone());\n        self.delete = self.delete.map(layer_fn.clone());\n        self.options = self.options.map(layer_fn.clone());\n        self.patch = self.patch.map(layer_fn.clone());\n        self.post = self.post.map(layer_fn.clone());\n        self.put = self.put.map(layer_fn.clone());\n        self.trace = self.trace.map(layer_fn.clone());\n        self.connect = self.connect.map(layer_fn);\n\n        self\n    }\n\n    pub(crate) fn merge_for_path(\n        mut self,\n        path: Option<&str>,\n        other: Self,\n    ) -> Result<Self, Cow<'static, str>> {\n        // written using inner functions to generate less IR\n        fn merge_inner<S, E>(\n            path: Option<&str>,\n            name: &str,\n            first: MethodEndpoint<S, E>,\n            second: MethodEndpoint<S, E>,\n        ) -> Result<MethodEndpoint<S, E>, Cow<'static, str>> {\n            match (first, second) {\n                (MethodEndpoint::None, MethodEndpoint::None) => Ok(MethodEndpoint::None),\n                (pick, MethodEndpoint::None) | (MethodEndpoint::None, pick) => Ok(pick),\n                _ => {\n                    if let Some(path) = path {\n                        Err(format!(\n                            \"Overlapping method route. Handler for `{name} {path}` already exists\"\n                        )\n                        .into())\n                    } else {\n                        Err(format!(\n                            \"Overlapping method route. Cannot merge two method routes that both \\\n                             define `{name}`\"\n                        )\n                        .into())\n                    }\n                }\n            }\n        }\n\n        self.get = merge_inner(path, \"GET\", self.get, other.get)?;\n        self.head = merge_inner(path, \"HEAD\", self.head, other.head)?;\n        self.delete = merge_inner(path, \"DELETE\", self.delete, other.delete)?;\n        self.options = merge_inner(path, \"OPTIONS\", self.options, other.options)?;\n        self.patch = merge_inner(path, \"PATCH\", self.patch, other.patch)?;\n        self.post = merge_inner(path, \"POST\", self.post, other.post)?;\n        self.put = merge_inner(path, \"PUT\", self.put, other.put)?;\n        self.trace = merge_inner(path, \"TRACE\", self.trace, other.trace)?;\n        self.connect = merge_inner(path, \"CONNECT\", self.connect, other.connect)?;\n\n        self.fallback = self\n            .fallback\n            .merge(other.fallback)\n            .ok_or(\"Cannot merge two `MethodRouter`s that both have a fallback\")?;\n\n        self.allow_header = self.allow_header.merge(other.allow_header);\n\n        Ok(self)\n    }\n\n    #[doc = include_str!(\"../docs/method_routing/merge.md\")]\n    #[track_caller]\n    pub fn merge(self, other: Self) -> Self {\n        match self.merge_for_path(None, other) {\n            Ok(t) => t,\n            // not using unwrap or unwrap_or_else to get a clean panic message + the right location\n            Err(e) => panic!(\"{e}\"),\n        }\n    }\n\n    /// Apply a [`HandleErrorLayer`].\n    ///\n    /// This is a convenience method for doing `self.layer(HandleErrorLayer::new(f))`.\n    pub fn handle_error<F, T>(self, f: F) -> MethodRouter<S, Infallible>\n    where\n        F: Clone + Send + Sync + 'static,\n        HandleError<Route<E>, F, T>: Service<Request, Error = Infallible>,\n        <HandleError<Route<E>, F, T> as Service<Request>>::Future: Send,\n        <HandleError<Route<E>, F, T> as Service<Request>>::Response: IntoResponse + Send,\n        T: 'static,\n        E: 'static,\n        S: 'static,\n    {\n        self.layer(HandleErrorLayer::new(f))\n    }\n\n    fn skip_allow_header(mut self) -> Self {\n        self.allow_header = AllowHeader::Skip;\n        self\n    }\n\n    pub(crate) fn call_with_state(&self, req: Request, state: S) -> RouteFuture<E> {\n        macro_rules! call {\n            (\n                $req:expr,\n                $method_variant:ident,\n                $svc:expr\n            ) => {\n                if *req.method() == Method::$method_variant {\n                    match $svc {\n                        MethodEndpoint::None => {}\n                        MethodEndpoint::Route(route) => {\n                            return route.clone().oneshot_inner_owned($req);\n                        }\n                        MethodEndpoint::BoxedHandler(handler) => {\n                            let route = handler.clone().into_route(state);\n                            return route.oneshot_inner_owned($req);\n                        }\n                    }\n                }\n            };\n        }\n\n        // written with a pattern match like this to ensure we call all routes\n        let Self {\n            get,\n            head,\n            delete,\n            options,\n            patch,\n            post,\n            put,\n            trace,\n            connect,\n            fallback,\n            allow_header,\n        } = self;\n\n        call!(req, HEAD, head);\n        call!(req, HEAD, get);\n        call!(req, GET, get);\n        call!(req, POST, post);\n        call!(req, OPTIONS, options);\n        call!(req, PATCH, patch);\n        call!(req, PUT, put);\n        call!(req, DELETE, delete);\n        call!(req, TRACE, trace);\n        call!(req, CONNECT, connect);\n\n        let future = fallback.clone().call_with_state(req, state);\n\n        match allow_header {\n            AllowHeader::None => future.allow_header(Bytes::new()),\n            AllowHeader::Skip => future,\n            AllowHeader::Bytes(allow_header) => future.allow_header(allow_header.clone().freeze()),\n        }\n    }\n}\n\nfn append_allow_header(allow_header: &mut AllowHeader, method: &'static str) {\n    match allow_header {\n        AllowHeader::None => {\n            *allow_header = AllowHeader::Bytes(BytesMut::from(method));\n        }\n        AllowHeader::Skip => {}\n        AllowHeader::Bytes(allow_header) => {\n            if let Ok(s) = std::str::from_utf8(allow_header) {\n                if !s.contains(method) {\n                    allow_header.extend_from_slice(b\",\");\n                    allow_header.extend_from_slice(method.as_bytes());\n                }\n            } else {\n                #[cfg(debug_assertions)]\n                panic!(\"`allow_header` contained invalid utf-8. This should never happen\")\n            }\n        }\n    }\n}\n\nimpl<S, E> Clone for MethodRouter<S, E> {\n    fn clone(&self) -> Self {\n        Self {\n            get: self.get.clone(),\n            head: self.head.clone(),\n            delete: self.delete.clone(),\n            options: self.options.clone(),\n            patch: self.patch.clone(),\n            post: self.post.clone(),\n            put: self.put.clone(),\n            trace: self.trace.clone(),\n            connect: self.connect.clone(),\n            fallback: self.fallback.clone(),\n            allow_header: self.allow_header.clone(),\n        }\n    }\n}\n\nimpl<S, E> Default for MethodRouter<S, E>\nwhere\n    S: Clone,\n{\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nenum MethodEndpoint<S, E> {\n    None,\n    Route(Route<E>),\n    BoxedHandler(BoxedIntoRoute<S, E>),\n}\n\nimpl<S, E> MethodEndpoint<S, E>\nwhere\n    S: Clone,\n{\n    fn is_some(&self) -> bool {\n        matches!(self, Self::Route(_) | Self::BoxedHandler(_))\n    }\n\n    fn is_none(&self) -> bool {\n        matches!(self, Self::None)\n    }\n\n    fn map<F, E2>(self, f: F) -> MethodEndpoint<S, E2>\n    where\n        S: 'static,\n        E: 'static,\n        F: FnOnce(Route<E>) -> Route<E2> + Clone + Send + Sync + 'static,\n        E2: 'static,\n    {\n        match self {\n            Self::None => MethodEndpoint::None,\n            Self::Route(route) => MethodEndpoint::Route(f(route)),\n            Self::BoxedHandler(handler) => MethodEndpoint::BoxedHandler(handler.map(f)),\n        }\n    }\n\n    fn with_state<S2>(self, state: &S) -> MethodEndpoint<S2, E> {\n        match self {\n            Self::None => MethodEndpoint::None,\n            Self::Route(route) => MethodEndpoint::Route(route),\n            Self::BoxedHandler(handler) => MethodEndpoint::Route(handler.into_route(state.clone())),\n        }\n    }\n}\n\nimpl<S, E> Clone for MethodEndpoint<S, E> {\n    fn clone(&self) -> Self {\n        match self {\n            Self::None => Self::None,\n            Self::Route(inner) => Self::Route(inner.clone()),\n            Self::BoxedHandler(inner) => Self::BoxedHandler(inner.clone()),\n        }\n    }\n}\n\nimpl<S, E> fmt::Debug for MethodEndpoint<S, E> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::None => f.debug_tuple(\"None\").finish(),\n            Self::Route(inner) => inner.fmt(f),\n            Self::BoxedHandler(_) => f.debug_tuple(\"BoxedHandler\").finish(),\n        }\n    }\n}\n\nimpl<B, E> Service<Request<B>> for MethodRouter<(), E>\nwhere\n    B: HttpBody<Data = Bytes> + Send + 'static,\n    B::Error: Into<BoxError>,\n{\n    type Response = Response;\n    type Error = E;\n    type Future = RouteFuture<E>;\n\n    #[inline]\n    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Poll::Ready(Ok(()))\n    }\n\n    #[inline]\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        let req = req.map(Body::new);\n        self.call_with_state(req, ())\n    }\n}\n\n#[diagnostic::do_not_recommend]\nimpl<S> Handler<(), S> for MethodRouter<S>\nwhere\n    S: Clone + 'static,\n{\n    type Future = InfallibleRouteFuture;\n\n    fn call(self, req: Request, state: S) -> Self::Future {\n        InfallibleRouteFuture::new(self.call_with_state(req, state))\n    }\n}\n\n// for `axum::serve(listener, router)`\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nconst _: () = {\n    use crate::serve;\n\n    impl<L> Service<serve::IncomingStream<'_, L>> for MethodRouter<()>\n    where\n        L: serve::Listener,\n    {\n        type Response = Self;\n        type Error = Infallible;\n        type Future = std::future::Ready<Result<Self::Response, Self::Error>>;\n\n        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n            Poll::Ready(Ok(()))\n        }\n\n        fn call(&mut self, _req: serve::IncomingStream<'_, L>) -> Self::Future {\n            std::future::ready(Ok(self.clone().with_state(())))\n        }\n    }\n};\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{extract::State, handler::HandlerWithoutStateExt};\n    use http::{header::ALLOW, HeaderMap};\n    use http_body_util::BodyExt;\n    use std::time::Duration;\n    use tower::ServiceExt;\n    use tower_http::{\n        services::fs::ServeDir, timeout::TimeoutLayer, validate_request::ValidateRequestHeaderLayer,\n    };\n\n    #[crate::test]\n    async fn method_not_allowed_by_default() {\n        let mut svc = MethodRouter::new();\n        let (status, _, body) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert!(body.is_empty());\n    }\n\n    #[crate::test]\n    async fn get_service_fn() {\n        async fn handle(_req: Request) -> Result<Response<Body>, Infallible> {\n            Ok(Response::new(Body::from(\"ok\")))\n        }\n\n        let mut svc = get_service(service_fn(handle));\n\n        let (status, _, body) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n        assert_eq!(body, \"ok\");\n    }\n\n    #[crate::test]\n    async fn get_handler() {\n        let mut svc = MethodRouter::new().get(ok);\n        let (status, _, body) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n        assert_eq!(body, \"ok\");\n    }\n\n    #[crate::test]\n    async fn get_accepts_head() {\n        let mut svc = MethodRouter::new().get(ok);\n        let (status, _, body) = call(Method::HEAD, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n        assert!(body.is_empty());\n    }\n\n    #[crate::test]\n    async fn head_takes_precedence_over_get() {\n        let mut svc = MethodRouter::new().head(created).get(ok);\n        let (status, _, body) = call(Method::HEAD, &mut svc).await;\n        assert_eq!(status, StatusCode::CREATED);\n        assert!(body.is_empty());\n    }\n\n    #[crate::test]\n    async fn merge() {\n        let mut svc = get(ok).merge(post(ok)).merge(connect(ok));\n\n        let (status, _, _) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n\n        let (status, _, _) = call(Method::POST, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n\n        let (status, _, _) = call(Method::CONNECT, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n    }\n\n    #[allow(deprecated)]\n    #[crate::test]\n    async fn layer() {\n        let mut svc = MethodRouter::new()\n            .get(|| async { std::future::pending::<()>().await })\n            .layer(ValidateRequestHeaderLayer::bearer(\"password\"));\n\n        // method with route\n        let (status, _, _) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::UNAUTHORIZED);\n\n        // method without route\n        let (status, _, _) = call(Method::DELETE, &mut svc).await;\n        assert_eq!(status, StatusCode::UNAUTHORIZED);\n    }\n\n    #[allow(deprecated)]\n    #[crate::test]\n    async fn route_layer() {\n        let mut svc = MethodRouter::new()\n            .get(|| async { std::future::pending::<()>().await })\n            .route_layer(ValidateRequestHeaderLayer::bearer(\"password\"));\n\n        // method with route\n        let (status, _, _) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::UNAUTHORIZED);\n\n        // method without route\n        let (status, _, _) = call(Method::DELETE, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n    }\n\n    #[allow(dead_code, deprecated)]\n    async fn building_complex_router() {\n        let app = crate::Router::new().route(\n            \"/\",\n            // use the all the things 💣️\n            get(ok)\n                .post(ok)\n                .route_layer(ValidateRequestHeaderLayer::bearer(\"password\"))\n                .merge(delete_service(ServeDir::new(\".\")))\n                .fallback(|| async { StatusCode::NOT_FOUND })\n                .put(ok)\n                .layer(TimeoutLayer::with_status_code(\n                    StatusCode::REQUEST_TIMEOUT,\n                    Duration::from_secs(10),\n                )),\n        );\n\n        let listener = tokio::net::TcpListener::bind(\"0.0.0.0:0\").await.unwrap();\n        crate::serve(listener, app).await;\n    }\n\n    #[crate::test]\n    async fn sets_allow_header() {\n        let mut svc = MethodRouter::new().put(ok).patch(ok);\n        let (status, headers, _) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert_eq!(headers[ALLOW], \"PUT,PATCH\");\n    }\n\n    #[crate::test]\n    async fn sets_allow_header_get_head() {\n        let mut svc = MethodRouter::new().get(ok).head(ok);\n        let (status, headers, _) = call(Method::PUT, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert_eq!(headers[ALLOW], \"GET,HEAD\");\n    }\n\n    #[crate::test]\n    async fn empty_allow_header_by_default() {\n        let mut svc = MethodRouter::new();\n        let (status, headers, _) = call(Method::PATCH, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert_eq!(headers[ALLOW], \"\");\n    }\n\n    #[crate::test]\n    async fn allow_header_when_merging() {\n        let a = put(ok).patch(ok);\n        let b = get(ok).head(ok);\n        let mut svc = a.merge(b);\n\n        let (status, headers, _) = call(Method::DELETE, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert_eq!(headers[ALLOW], \"PUT,PATCH,GET,HEAD\");\n    }\n\n    #[crate::test]\n    async fn allow_header_any() {\n        let mut svc = any(ok);\n\n        let (status, headers, _) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n        assert!(!headers.contains_key(ALLOW));\n    }\n\n    #[crate::test]\n    async fn allow_header_with_fallback() {\n        let mut svc = MethodRouter::new()\n            .get(ok)\n            .fallback(|| async { (StatusCode::METHOD_NOT_ALLOWED, \"Method not allowed\") });\n\n        let (status, headers, _) = call(Method::DELETE, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert_eq!(headers[ALLOW], \"GET,HEAD\");\n    }\n\n    #[crate::test]\n    async fn allow_header_with_fallback_that_sets_allow() {\n        async fn fallback(method: Method) -> Response {\n            if method == Method::POST {\n                \"OK\".into_response()\n            } else {\n                (\n                    StatusCode::METHOD_NOT_ALLOWED,\n                    [(ALLOW, \"GET,POST\")],\n                    \"Method not allowed\",\n                )\n                    .into_response()\n            }\n        }\n\n        let mut svc = MethodRouter::new().get(ok).fallback(fallback);\n\n        let (status, _, _) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n\n        let (status, _, _) = call(Method::POST, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n\n        let (status, headers, _) = call(Method::DELETE, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert_eq!(headers[ALLOW], \"GET,POST\");\n    }\n\n    #[crate::test]\n    async fn allow_header_noop_middleware() {\n        let mut svc = MethodRouter::new()\n            .get(ok)\n            .layer(tower::layer::util::Identity::new());\n\n        let (status, headers, _) = call(Method::DELETE, &mut svc).await;\n        assert_eq!(status, StatusCode::METHOD_NOT_ALLOWED);\n        assert_eq!(headers[ALLOW], \"GET,HEAD\");\n    }\n\n    #[crate::test]\n    #[should_panic(\n        expected = \"Overlapping method route. Cannot add two method routes that both handle `GET`\"\n    )]\n    async fn handler_overlaps() {\n        let _: MethodRouter<()> = get(ok).get(ok);\n    }\n\n    #[crate::test]\n    #[should_panic(\n        expected = \"Overlapping method route. Cannot add two method routes that both handle `POST`\"\n    )]\n    async fn service_overlaps() {\n        let _: MethodRouter<()> = post_service(ok.into_service()).post_service(ok.into_service());\n    }\n\n    #[crate::test]\n    async fn get_head_does_not_overlap() {\n        let _: MethodRouter<()> = get(ok).head(ok);\n    }\n\n    #[crate::test]\n    async fn head_get_does_not_overlap() {\n        let _: MethodRouter<()> = head(ok).get(ok);\n    }\n\n    #[crate::test]\n    async fn accessing_state() {\n        let mut svc = MethodRouter::new()\n            .get(|State(state): State<&'static str>| async move { state })\n            .with_state(\"state\");\n\n        let (status, _, text) = call(Method::GET, &mut svc).await;\n\n        assert_eq!(status, StatusCode::OK);\n        assert_eq!(text, \"state\");\n    }\n\n    #[crate::test]\n    async fn fallback_accessing_state() {\n        let mut svc = MethodRouter::new()\n            .fallback(|State(state): State<&'static str>| async move { state })\n            .with_state(\"state\");\n\n        let (status, _, text) = call(Method::GET, &mut svc).await;\n\n        assert_eq!(status, StatusCode::OK);\n        assert_eq!(text, \"state\");\n    }\n\n    #[crate::test]\n    async fn merge_accessing_state() {\n        let one = get(|State(state): State<&'static str>| async move { state });\n        let two = post(|State(state): State<&'static str>| async move { state });\n\n        let mut svc = one.merge(two).with_state(\"state\");\n\n        let (status, _, text) = call(Method::GET, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n        assert_eq!(text, \"state\");\n\n        let (status, _, _) = call(Method::POST, &mut svc).await;\n        assert_eq!(status, StatusCode::OK);\n        assert_eq!(text, \"state\");\n    }\n\n    #[test]\n    fn method_filter() {\n        let router: MethodRouter = get(|| async {});\n        assert_eq!(router.method_filter(), Some(MethodFilter::GET));\n\n        let router: MethodRouter = get(|| async {}).head(|| async {}).post(|| async {});\n        assert_eq!(\n            router.method_filter(),\n            Some(\n                MethodFilter::GET\n                    .or(MethodFilter::HEAD)\n                    .or(MethodFilter::POST)\n            )\n        );\n\n        let router: MethodRouter = any(|| async {});\n        assert_eq!(router.method_filter(), None);\n    }\n\n    async fn call<S>(method: Method, svc: &mut S) -> (StatusCode, HeaderMap, String)\n    where\n        S: Service<Request, Error = Infallible>,\n        S::Response: IntoResponse,\n    {\n        let request = Request::builder()\n            .uri(\"/\")\n            .method(method)\n            .body(Body::empty())\n            .unwrap();\n        let response = svc\n            .ready()\n            .await\n            .unwrap()\n            .call(request)\n            .await\n            .unwrap()\n            .into_response();\n        let (parts, body) = response.into_parts();\n        let body =\n            String::from_utf8(BodyExt::collect(body).await.unwrap().to_bytes().to_vec()).unwrap();\n        (parts.status, parts.headers, body)\n    }\n\n    async fn ok() -> (StatusCode, &'static str) {\n        (StatusCode::OK, \"ok\")\n    }\n\n    async fn created() -> (StatusCode, &'static str) {\n        (StatusCode::CREATED, \"created\")\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/mod.rs",
    "content": "//! Routing between [`Service`]s and handlers.\n\nuse self::{future::RouteFuture, not_found::NotFound, path_router::PathRouter};\n#[cfg(feature = \"tokio\")]\nuse crate::extract::connect_info::IntoMakeServiceWithConnectInfo;\n#[cfg(feature = \"matched-path\")]\nuse crate::extract::MatchedPath;\nuse crate::{\n    body::{Body, HttpBody},\n    boxed::BoxedIntoRoute,\n    handler::Handler,\n    util::try_downcast,\n};\nuse axum_core::{\n    extract::Request,\n    response::{IntoResponse, Response},\n};\nuse std::{\n    convert::Infallible,\n    fmt,\n    marker::PhantomData,\n    sync::Arc,\n    task::{Context, Poll},\n};\nuse tower::service_fn;\nuse tower_layer::{layer_fn, Layer};\nuse tower_service::Service;\n\npub mod future;\npub mod method_routing;\n\nmod into_make_service;\nmod method_filter;\nmod not_found;\npub(crate) mod path_router;\nmod route;\nmod strip_prefix;\npub(crate) mod url_params;\n\n#[cfg(test)]\nmod tests;\n\npub use self::{into_make_service::IntoMakeService, method_filter::MethodFilter, route::Route};\n\npub use self::method_routing::{\n    any, any_service, connect, connect_service, delete, delete_service, get, get_service, head,\n    head_service, on, on_service, options, options_service, patch, patch_service, post,\n    post_service, put, put_service, trace, trace_service, MethodRouter,\n};\n\nmacro_rules! panic_on_err {\n    ($expr:expr) => {\n        match $expr {\n            Ok(x) => x,\n            Err(err) => panic!(\"{err}\"),\n        }\n    };\n}\n\nconst TAKE_ONCE_ROUTE_PANIC_MSG: &str =\n    \"TakeOnceRoute called more than once; if this was not triggered by an intentional test, this should never happen. Please file an issue.\";\n\nfn take_route_or_internal_error(service: &mut Option<Route>) -> Route {\n    service.take().unwrap_or_else(|| {\n        if cfg!(debug_assertions) {\n            panic!(\"{TAKE_ONCE_ROUTE_PANIC_MSG}\");\n        }\n\n        Route::new(service_fn(|_req: Request| async move {\n            Ok::<_, Infallible>(http::StatusCode::INTERNAL_SERVER_ERROR.into_response())\n        }))\n    })\n}\n\n#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub(crate) struct RouteId(usize);\n\n/// The router type for composing handlers and services.\n///\n/// `Router<S>` means a router that is _missing_ a state of type `S` to be able\n/// to handle requests. Thus, only `Router<()>` (i.e. without missing state) can\n/// be passed to [`serve`]. See [`Router::with_state`] for more details.\n///\n/// [`serve`]: crate::serve()\n#[must_use]\npub struct Router<S = ()> {\n    inner: Arc<RouterInner<S>>,\n}\n\nimpl<S> Clone for Router<S> {\n    fn clone(&self) -> Self {\n        Self {\n            inner: Arc::clone(&self.inner),\n        }\n    }\n}\n\nstruct RouterInner<S> {\n    path_router: PathRouter<S>,\n    default_fallback: bool,\n    catch_all_fallback: Fallback<S>,\n}\n\nimpl<S> Default for Router<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<S> fmt::Debug for Router<S> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Router\")\n            .field(\"path_router\", &self.inner.path_router)\n            .field(\"default_fallback\", &self.inner.default_fallback)\n            .field(\"catch_all_fallback\", &self.inner.catch_all_fallback)\n            .finish()\n    }\n}\n\npub(crate) const NEST_TAIL_PARAM: &str = \"__private__axum_nest_tail_param\";\n#[cfg(feature = \"matched-path\")]\npub(crate) const NEST_TAIL_PARAM_CAPTURE: &str = \"/{*__private__axum_nest_tail_param}\";\npub(crate) const FALLBACK_PARAM: &str = \"__private__axum_fallback\";\npub(crate) const FALLBACK_PARAM_PATH: &str = \"/{*__private__axum_fallback}\";\n\nmacro_rules! map_inner {\n    ( $self_:ident, $inner:pat_param => $expr:expr) => {\n        #[allow(redundant_semicolons)]\n        {\n            let $inner = $self_.into_inner();\n            Router {\n                inner: Arc::new($expr),\n            }\n        }\n    };\n}\n\nmacro_rules! tap_inner {\n    ( $self_:ident, mut $inner:ident => { $($stmt:stmt)* } ) => {\n        #[allow(redundant_semicolons)]\n        {\n            let mut $inner = $self_.into_inner();\n            $($stmt)*;\n            Router {\n                inner: Arc::new($inner),\n            }\n        }\n    };\n}\n\nimpl<S> Router<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    /// Create a new `Router`.\n    ///\n    /// Unless you add additional routes this will respond with `404 Not Found` to\n    /// all requests.\n    pub fn new() -> Self {\n        Self {\n            inner: Arc::new(RouterInner {\n                path_router: Default::default(),\n                default_fallback: true,\n                catch_all_fallback: Fallback::Default(Route::new(NotFound)),\n            }),\n        }\n    }\n\n    fn into_inner(self) -> RouterInner<S> {\n        match Arc::try_unwrap(self.inner) {\n            Ok(inner) => inner,\n            Err(arc) => RouterInner {\n                path_router: arc.path_router.clone(),\n                default_fallback: arc.default_fallback,\n                catch_all_fallback: arc.catch_all_fallback.clone(),\n            },\n        }\n    }\n\n    #[doc = include_str!(\"../docs/routing/without_v07_checks.md\")]\n    pub fn without_v07_checks(self) -> Self {\n        tap_inner!(self, mut this => {\n            this.path_router.without_v07_checks();\n        })\n    }\n\n    #[doc = include_str!(\"../docs/routing/route.md\")]\n    #[track_caller]\n    pub fn route(self, path: &str, method_router: MethodRouter<S>) -> Self {\n        tap_inner!(self, mut this => {\n            panic_on_err!(this.path_router.route(path, method_router));\n        })\n    }\n\n    #[doc = include_str!(\"../docs/routing/route_service.md\")]\n    pub fn route_service<T>(self, path: &str, service: T) -> Self\n    where\n        T: Service<Request, Error = Infallible> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse,\n        T::Future: Send + 'static,\n    {\n        let Err(service) = try_downcast::<Self, _>(service) else {\n            panic!(\n                \"Invalid route: `Router::route_service` cannot be used with `Router`s. \\\n                Use `Router::nest` instead\"\n            );\n        };\n\n        tap_inner!(self, mut this => {\n            panic_on_err!(this.path_router.route_service(path, service));\n        })\n    }\n\n    #[doc = include_str!(\"../docs/routing/nest.md\")]\n    #[doc(alias = \"scope\")] // Some other libs like actix-web use this term\n    #[track_caller]\n    pub fn nest(self, path: &str, router: Self) -> Self {\n        if path.is_empty() || path == \"/\" {\n            panic!(\"Nesting at the root is no longer supported. Use merge instead.\");\n        }\n\n        let RouterInner {\n            path_router,\n            default_fallback: _,\n            // we don't need to inherit the catch-all fallback. It is only used for CONNECT\n            // requests with an empty path. If we were to inherit the catch-all fallback\n            // it would end up matching `/{path}/*` which doesn't match empty paths.\n            catch_all_fallback: _,\n        } = router.into_inner();\n\n        tap_inner!(self, mut this => {\n            panic_on_err!(this.path_router.nest(path, path_router));\n        })\n    }\n\n    /// Like [`nest`](Self::nest), but accepts an arbitrary `Service`.\n    #[track_caller]\n    pub fn nest_service<T>(self, path: &str, service: T) -> Self\n    where\n        T: Service<Request, Error = Infallible> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse,\n        T::Future: Send + 'static,\n    {\n        if path.is_empty() || path == \"/\" {\n            panic!(\"Nesting at the root is no longer supported. Use fallback_service instead.\");\n        }\n\n        tap_inner!(self, mut this => {\n            panic_on_err!(this.path_router.nest_service(path, service));\n        })\n    }\n\n    #[doc = include_str!(\"../docs/routing/merge.md\")]\n    #[track_caller]\n    pub fn merge<R>(self, other: R) -> Self\n    where\n        R: Into<Self>,\n    {\n        let other: Self = other.into();\n        let RouterInner {\n            path_router,\n            default_fallback,\n            catch_all_fallback,\n        } = other.into_inner();\n\n        map_inner!(self, mut this => {\n            match (this.default_fallback, default_fallback) {\n                // other has a default fallback\n                // use the one from other\n                (_, true) => {}\n                // this has default fallback, other has a custom fallback\n                (true, false) => {\n                    this.default_fallback = false;\n                }\n                // both have a custom fallback, not allowed\n                (false, false) => {\n                    panic!(\"Cannot merge two `Router`s that both have a fallback\")\n                }\n            };\n\n            panic_on_err!(this.path_router.merge(path_router));\n\n            this.catch_all_fallback = this\n                .catch_all_fallback\n                .merge(catch_all_fallback)\n                .unwrap_or_else(|| panic!(\"Cannot merge two `Router`s that both have a fallback\"));\n\n            this\n        })\n    }\n\n    #[doc = include_str!(\"../docs/routing/layer.md\")]\n    pub fn layer<L>(self, layer: L) -> Self\n    where\n        L: Layer<Route> + Clone + Send + Sync + 'static,\n        L::Service: Service<Request> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n    {\n        map_inner!(self, this => RouterInner {\n            path_router: this.path_router.layer(layer.clone()),\n            default_fallback: this.default_fallback,\n            catch_all_fallback: this.catch_all_fallback.map(|route| route.layer(layer)),\n        })\n    }\n\n    #[doc = include_str!(\"../docs/routing/route_layer.md\")]\n    #[track_caller]\n    pub fn route_layer<L>(self, layer: L) -> Self\n    where\n        L: Layer<Route> + Clone + Send + Sync + 'static,\n        L::Service: Service<Request> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n    {\n        map_inner!(self, this => RouterInner {\n            path_router: this.path_router.route_layer(layer),\n            default_fallback: this.default_fallback,\n            catch_all_fallback: this.catch_all_fallback,\n        })\n    }\n\n    /// True if the router currently has at least one route added.\n    #[must_use]\n    pub fn has_routes(&self) -> bool {\n        self.inner.path_router.has_routes()\n    }\n\n    #[track_caller]\n    #[doc = include_str!(\"../docs/routing/fallback.md\")]\n    pub fn fallback<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        tap_inner!(self, mut this => {\n            this.catch_all_fallback =\n                Fallback::BoxedHandler(BoxedIntoRoute::from_handler(handler.clone()));\n        })\n        .fallback_endpoint(Endpoint::MethodRouter(any(handler)))\n    }\n\n    /// Add a fallback [`Service`] to the router.\n    ///\n    /// See [`Router::fallback`] for more details.\n    pub fn fallback_service<T>(self, service: T) -> Self\n    where\n        T: Service<Request, Error = Infallible> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse,\n        T::Future: Send + 'static,\n    {\n        let route = Route::new(service);\n        tap_inner!(self, mut this => {\n            this.catch_all_fallback = Fallback::Service(route.clone());\n        })\n        .fallback_endpoint(Endpoint::Route(route))\n    }\n\n    #[doc = include_str!(\"../docs/routing/method_not_allowed_fallback.md\")]\n    #[allow(clippy::needless_pass_by_value)]\n    pub fn method_not_allowed_fallback<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        tap_inner!(self, mut this => {\n            this.path_router\n                .method_not_allowed_fallback(&handler);\n        })\n    }\n\n    /// Reset the fallback to its default.\n    ///\n    /// Useful to merge two routers with fallbacks, as [`merge`] doesn't allow\n    /// both routers to have an explicit fallback. Use this method to remove the\n    /// one you want to discard before merging.\n    ///\n    /// [`merge`]: Self::merge\n    pub fn reset_fallback(self) -> Self {\n        tap_inner!(self, mut this => {\n            this.default_fallback = true;\n            this.catch_all_fallback = Fallback::Default(Route::new(NotFound));\n        })\n    }\n\n    fn fallback_endpoint(self, endpoint: Endpoint<S>) -> Self {\n        // TODO make this better.\n        // We need the returned `Service` to be `Clone` and the function inside `service_fn` to be\n        // `FnMut` so instead of just using the owned service, we do this trick with `Option`. We\n        // know this will be called just once so it's fine. We're doing that so that we avoid one\n        // clone inside `oneshot_inner` so that the `Router` and subsequently the `State` is not\n        // cloned too much.\n        tap_inner!(self, mut this => {\n            _ = this.path_router.route_endpoint(\n                \"/\",\n                endpoint.clone().layer(\n                    layer_fn(\n                        |service: Route| {\n                            let mut service = Some(service);\n                            service_fn(\n                                #[cfg_attr(not(feature = \"matched-path\"), allow(unused_mut))]\n                                move |mut request: Request| {\n                                    #[cfg(feature = \"matched-path\")]\n                                    request.extensions_mut().remove::<MatchedPath>();\n                                    let route = take_route_or_internal_error(&mut service);\n                                    route.oneshot_inner_owned(request)\n                                }\n                            )\n                        }\n                    )\n                )\n            );\n\n            _ = this.path_router.route_endpoint(\n                FALLBACK_PARAM_PATH,\n                endpoint.layer(\n                    layer_fn(\n                        |service: Route| {\n                            let mut service = Some(service);\n                            service_fn(\n                                #[cfg_attr(not(feature = \"matched-path\"), allow(unused_mut))]\n                                move |mut request: Request| {\n                                    #[cfg(feature = \"matched-path\")]\n                                    request.extensions_mut().remove::<MatchedPath>();\n                                    let route = take_route_or_internal_error(&mut service);\n                                    route.oneshot_inner_owned(request)\n                                }\n                            )\n                        }\n                    )\n                )\n            );\n\n            this.default_fallback = false;\n        })\n    }\n\n    #[doc = include_str!(\"../docs/routing/with_state.md\")]\n    pub fn with_state<S2>(self, state: S) -> Router<S2> {\n        map_inner!(self, this => RouterInner {\n            path_router: this.path_router.with_state(state.clone()),\n            default_fallback: this.default_fallback,\n            catch_all_fallback: this.catch_all_fallback.with_state(state),\n        })\n    }\n\n    pub(crate) fn call_with_state(&self, req: Request, state: S) -> RouteFuture<Infallible> {\n        let (req, state) = match self.inner.path_router.call_with_state(req, state) {\n            Ok(future) => return future,\n            Err((req, state)) => (req, state),\n        };\n\n        self.inner\n            .catch_all_fallback\n            .clone()\n            .call_with_state(req, state)\n    }\n\n    /// Convert the router into a borrowed [`Service`] with a fixed request body type, to aid type\n    /// inference.\n    ///\n    /// In some cases when calling methods from [`tower::ServiceExt`] on a [`Router`] you might get\n    /// type inference errors along the lines of\n    ///\n    /// ```not_rust\n    /// let response = router.ready().await?.call(request).await?;\n    ///                       ^^^^^ cannot infer type for type parameter `B`\n    /// ```\n    ///\n    /// This happens because `Router` implements [`Service`] with `impl<B> Service<Request<B>> for Router<()>`.\n    ///\n    /// For example:\n    ///\n    /// ```compile_fail\n    /// use axum::{\n    ///     Router,\n    ///     routing::get,\n    ///     http::Request,\n    ///     body::Body,\n    /// };\n    /// use tower::{Service, ServiceExt};\n    ///\n    /// # async fn async_main() -> Result<(), Box<dyn std::error::Error>> {\n    /// let mut router = Router::new().route(\"/\", get(|| async {}));\n    /// let request = Request::new(Body::empty());\n    /// let response = router.ready().await?.call(request).await?;\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// Calling `Router::as_service` fixes that:\n    ///\n    /// ```\n    /// use axum::{\n    ///     Router,\n    ///     routing::get,\n    ///     http::Request,\n    ///     body::Body,\n    /// };\n    /// use tower::{Service, ServiceExt};\n    ///\n    /// # async fn async_main() -> Result<(), Box<dyn std::error::Error>> {\n    /// let mut router = Router::new().route(\"/\", get(|| async {}));\n    /// let request = Request::new(Body::empty());\n    /// let response = router.as_service().ready().await?.call(request).await?;\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// This is mainly used when calling `Router` in tests. It shouldn't be necessary when running\n    /// the `Router` normally via [`Router::into_make_service`].\n    pub fn as_service<B>(&mut self) -> RouterAsService<'_, B, S> {\n        RouterAsService {\n            router: self,\n            _marker: PhantomData,\n        }\n    }\n\n    /// Convert the router into an owned [`Service`] with a fixed request body type, to aid type\n    /// inference.\n    ///\n    /// This is the same as [`Router::as_service`] instead it returns an owned [`Service`]. See\n    /// that method for more details.\n    #[must_use]\n    pub fn into_service<B>(self) -> RouterIntoService<B, S> {\n        RouterIntoService {\n            router: self,\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl Router {\n    /// Convert this router into a [`MakeService`], that is a [`Service`] whose\n    /// response is another service.\n    ///\n    /// ```\n    /// use axum::{\n    ///     routing::get,\n    ///     Router,\n    /// };\n    ///\n    /// let app = Router::new().route(\"/\", get(|| async { \"Hi!\" }));\n    ///\n    /// # async {\n    /// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    /// axum::serve(listener, app).await;\n    /// # };\n    /// ```\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    #[must_use]\n    pub fn into_make_service(self) -> IntoMakeService<Self> {\n        // call `Router::with_state` such that everything is turned into `Route` eagerly\n        // rather than doing that per request\n        IntoMakeService::new(self.with_state(()))\n    }\n\n    #[doc = include_str!(\"../docs/routing/into_make_service_with_connect_info.md\")]\n    #[cfg(feature = \"tokio\")]\n    #[must_use]\n    pub fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {\n        // call `Router::with_state` such that everything is turned into `Route` eagerly\n        // rather than doing that per request\n        IntoMakeServiceWithConnectInfo::new(self.with_state(()))\n    }\n}\n\n// for `axum::serve(listener, router)`\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nconst _: () = {\n    use crate::serve;\n\n    impl<L> Service<serve::IncomingStream<'_, L>> for Router<()>\n    where\n        L: serve::Listener,\n    {\n        type Response = Self;\n        type Error = Infallible;\n        type Future = std::future::Ready<Result<Self::Response, Self::Error>>;\n\n        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n            Poll::Ready(Ok(()))\n        }\n\n        fn call(&mut self, _req: serve::IncomingStream<'_, L>) -> Self::Future {\n            // call `Router::with_state` such that everything is turned into `Route` eagerly\n            // rather than doing that per request\n            std::future::ready(Ok(self.clone().with_state(())))\n        }\n    }\n};\n\nimpl<B> Service<Request<B>> for Router<()>\nwhere\n    B: HttpBody<Data = bytes::Bytes> + Send + 'static,\n    B::Error: Into<axum_core::BoxError>,\n{\n    type Response = Response;\n    type Error = Infallible;\n    type Future = RouteFuture<Infallible>;\n\n    #[inline]\n    fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Poll::Ready(Ok(()))\n    }\n\n    #[inline]\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        let req = req.map(Body::new);\n        self.call_with_state(req, ())\n    }\n}\n\n/// A [`Router`] converted into a borrowed [`Service`] with a fixed body type.\n///\n/// See [`Router::as_service`] for more details.\npub struct RouterAsService<'a, B, S = ()> {\n    router: &'a mut Router<S>,\n    _marker: PhantomData<fn(B)>,\n}\n\nimpl<B> Service<Request<B>> for RouterAsService<'_, B, ()>\nwhere\n    B: HttpBody<Data = bytes::Bytes> + Send + 'static,\n    B::Error: Into<axum_core::BoxError>,\n{\n    type Response = Response;\n    type Error = Infallible;\n    type Future = RouteFuture<Infallible>;\n\n    #[inline]\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        <Router as Service<Request<B>>>::poll_ready(self.router, cx)\n    }\n\n    #[inline]\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        self.router.call(req)\n    }\n}\n\nimpl<B, S> fmt::Debug for RouterAsService<'_, B, S>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"RouterAsService\")\n            .field(\"router\", &self.router)\n            .finish()\n    }\n}\n\n/// A [`Router`] converted into an owned [`Service`] with a fixed body type.\n///\n/// See [`Router::into_service`] for more details.\npub struct RouterIntoService<B, S = ()> {\n    router: Router<S>,\n    _marker: PhantomData<fn(B)>,\n}\n\nimpl<B, S> Clone for RouterIntoService<B, S>\nwhere\n    Router<S>: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            router: self.router.clone(),\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl<B> Service<Request<B>> for RouterIntoService<B, ()>\nwhere\n    B: HttpBody<Data = bytes::Bytes> + Send + 'static,\n    B::Error: Into<axum_core::BoxError>,\n{\n    type Response = Response;\n    type Error = Infallible;\n    type Future = RouteFuture<Infallible>;\n\n    #[inline]\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        <Router as Service<Request<B>>>::poll_ready(&mut self.router, cx)\n    }\n\n    #[inline]\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        self.router.call(req)\n    }\n}\n\nimpl<B, S> fmt::Debug for RouterIntoService<B, S>\nwhere\n    S: fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"RouterIntoService\")\n            .field(\"router\", &self.router)\n            .finish()\n    }\n}\n\nenum Fallback<S, E = Infallible> {\n    Default(Route<E>),\n    Service(Route<E>),\n    BoxedHandler(BoxedIntoRoute<S, E>),\n}\n\nimpl<S, E> Fallback<S, E>\nwhere\n    S: Clone,\n{\n    fn merge(self, other: Self) -> Option<Self> {\n        match (self, other) {\n            // If either are `Default`, return the opposite one.\n            (Self::Default(_), pick) | (pick, Self::Default(_)) => Some(pick),\n            // Otherwise, return None\n            _ => None,\n        }\n    }\n\n    fn map<F, E2>(self, f: F) -> Fallback<S, E2>\n    where\n        S: 'static,\n        E: 'static,\n        F: FnOnce(Route<E>) -> Route<E2> + Clone + Send + Sync + 'static,\n        E2: 'static,\n    {\n        match self {\n            Self::Default(route) => Fallback::Default(f(route)),\n            Self::Service(route) => Fallback::Service(f(route)),\n            Self::BoxedHandler(handler) => Fallback::BoxedHandler(handler.map(f)),\n        }\n    }\n\n    fn with_state<S2>(self, state: S) -> Fallback<S2, E> {\n        match self {\n            Self::Default(route) => Fallback::Default(route),\n            Self::Service(route) => Fallback::Service(route),\n            Self::BoxedHandler(handler) => Fallback::Service(handler.into_route(state)),\n        }\n    }\n\n    fn call_with_state(self, req: Request, state: S) -> RouteFuture<E> {\n        match self {\n            Self::Default(route) | Self::Service(route) => route.oneshot_inner_owned(req),\n            Self::BoxedHandler(handler) => {\n                let route = handler.into_route(state);\n                route.oneshot_inner_owned(req)\n            }\n        }\n    }\n\n    fn is_default(&self) -> bool {\n        matches!(self, Self::Default(..))\n    }\n}\n\nimpl<S, E> Clone for Fallback<S, E> {\n    fn clone(&self) -> Self {\n        match self {\n            Self::Default(inner) => Self::Default(inner.clone()),\n            Self::Service(inner) => Self::Service(inner.clone()),\n            Self::BoxedHandler(inner) => Self::BoxedHandler(inner.clone()),\n        }\n    }\n}\n\nimpl<S, E> fmt::Debug for Fallback<S, E> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::Default(inner) => f.debug_tuple(\"Default\").field(inner).finish(),\n            Self::Service(inner) => f.debug_tuple(\"Service\").field(inner).finish(),\n            Self::BoxedHandler(_) => f.debug_tuple(\"BoxedHandler\").finish(),\n        }\n    }\n}\n\n#[allow(clippy::large_enum_variant)]\nenum Endpoint<S> {\n    MethodRouter(MethodRouter<S>),\n    Route(Route),\n}\n\nimpl<S> Endpoint<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    fn layer<L>(self, layer: L) -> Self\n    where\n        L: Layer<Route> + Clone + Send + Sync + 'static,\n        L::Service: Service<Request> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n    {\n        match self {\n            Self::MethodRouter(method_router) => Self::MethodRouter(method_router.layer(layer)),\n            Self::Route(route) => Self::Route(route.layer(layer)),\n        }\n    }\n}\n\nimpl<S> Clone for Endpoint<S> {\n    fn clone(&self) -> Self {\n        match self {\n            Self::MethodRouter(inner) => Self::MethodRouter(inner.clone()),\n            Self::Route(inner) => Self::Route(inner.clone()),\n        }\n    }\n}\n\nimpl<S> fmt::Debug for Endpoint<S> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::MethodRouter(method_router) => {\n                f.debug_tuple(\"MethodRouter\").field(method_router).finish()\n            }\n            Self::Route(route) => f.debug_tuple(\"Route\").field(route).finish(),\n        }\n    }\n}\n\n#[test]\nfn traits() {\n    use crate::test_helpers::*;\n    assert_send::<Router<()>>();\n    assert_sync::<Router<()>>();\n    assert_send::<RouterAsService<'static, Body, ()>>();\n    assert_sync::<RouterAsService<'static, Body, ()>>();\n    assert_send::<RouterIntoService<Body, ()>>();\n    assert_sync::<RouterIntoService<Body, ()>>();\n}\n"
  },
  {
    "path": "axum/src/routing/not_found.rs",
    "content": "use crate::response::Response;\nuse axum_core::response::IntoResponse;\nuse http::{Request, StatusCode};\nuse std::{\n    convert::Infallible,\n    future::ready,\n    task::{Context, Poll},\n};\nuse tower_service::Service;\n\n/// A [`Service`] that responds with `404 Not Found` to all requests.\n///\n/// This is used as the bottom service in a method router. You shouldn't have to\n/// use it manually.\n#[derive(Clone, Copy, Debug)]\npub(super) struct NotFound;\n\nimpl<B> Service<Request<B>> for NotFound\nwhere\n    B: Send + 'static,\n{\n    type Response = Response;\n    type Error = Infallible;\n    type Future = std::future::Ready<Result<Response, Self::Error>>;\n\n    #[inline]\n    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Poll::Ready(Ok(()))\n    }\n\n    fn call(&mut self, _req: Request<B>) -> Self::Future {\n        ready(Ok(StatusCode::NOT_FOUND.into_response()))\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/path_router.rs",
    "content": "use crate::{\n    extract::{nested_path::SetNestedPath, Request},\n    handler::Handler,\n};\nuse axum_core::response::IntoResponse;\nuse matchit::MatchError;\nuse std::{borrow::Cow, collections::HashMap, convert::Infallible, fmt, sync::Arc};\nuse tower_layer::Layer;\nuse tower_service::Service;\n\nuse super::{\n    future::RouteFuture, strip_prefix::StripPrefix, url_params, Endpoint, MethodRouter, Route,\n    RouteId, NEST_TAIL_PARAM,\n};\n\npub(super) struct PathRouter<S> {\n    routes: Vec<Endpoint<S>>,\n    node: Arc<Node>,\n    v7_checks: bool,\n}\n\nfn validate_path(v7_checks: bool, path: &str) -> Result<(), &'static str> {\n    if path.is_empty() {\n        return Err(\"Paths must start with a `/`. Use \\\"/\\\" for root routes\");\n    } else if !path.starts_with('/') {\n        return Err(\"Paths must start with a `/`\");\n    }\n\n    if v7_checks {\n        validate_v07_paths(path)?;\n    }\n\n    Ok(())\n}\n\nfn validate_v07_paths(path: &str) -> Result<(), &'static str> {\n    path.split('/')\n        .find_map(|segment| {\n            if segment.starts_with(':') {\n                Some(Err(\n                    \"Path segments must not start with `:`. For capture groups, use \\\n                `{capture}`. If you meant to literally match a segment starting with \\\n                a colon, call `without_v07_checks` on the router.\",\n                ))\n            } else if segment.starts_with('*') {\n                Some(Err(\n                    \"Path segments must not start with `*`. For wildcard capture, use \\\n                `{*wildcard}`. If you meant to literally match a segment starting with \\\n                an asterisk, call `without_v07_checks` on the router.\",\n                ))\n            } else {\n                None\n            }\n        })\n        .unwrap_or(Ok(()))\n}\n\nimpl<S> PathRouter<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    pub(super) fn without_v07_checks(&mut self) {\n        self.v7_checks = false;\n    }\n\n    pub(super) fn route(\n        &mut self,\n        path: &str,\n        method_router: MethodRouter<S>,\n    ) -> Result<(), Cow<'static, str>> {\n        validate_path(self.v7_checks, path)?;\n\n        if let Some((route_id, Endpoint::MethodRouter(prev_method_router))) = self\n            .node\n            .path_to_route_id\n            .get(path)\n            .and_then(|route_id| self.routes.get(route_id.0).map(|svc| (*route_id, svc)))\n        {\n            // if we're adding a new `MethodRouter` to a route that already has one just\n            // merge them. This makes `.route(\"/\", get(_)).route(\"/\", post(_))` work\n            let service = Endpoint::MethodRouter(\n                prev_method_router\n                    .clone()\n                    .merge_for_path(Some(path), method_router)?,\n            );\n            self.routes[route_id.0] = service;\n        } else {\n            let endpoint = Endpoint::MethodRouter(method_router);\n            self.new_route(path, endpoint)?;\n        }\n\n        Ok(())\n    }\n\n    pub(super) fn method_not_allowed_fallback<H, T>(&mut self, handler: &H)\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        for endpoint in self.routes.iter_mut() {\n            if let Endpoint::MethodRouter(rt) = endpoint {\n                *rt = rt.clone().default_fallback(handler.clone());\n            }\n        }\n    }\n\n    pub(super) fn route_service<T>(\n        &mut self,\n        path: &str,\n        service: T,\n    ) -> Result<(), Cow<'static, str>>\n    where\n        T: Service<Request, Error = Infallible> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse,\n        T::Future: Send + 'static,\n    {\n        self.route_endpoint(path, Endpoint::Route(Route::new(service)))\n    }\n\n    pub(super) fn route_endpoint(\n        &mut self,\n        path: &str,\n        endpoint: Endpoint<S>,\n    ) -> Result<(), Cow<'static, str>> {\n        validate_path(self.v7_checks, path)?;\n\n        self.new_route(path, endpoint)?;\n\n        Ok(())\n    }\n\n    fn set_node(&mut self, path: &str, id: RouteId) -> Result<(), String> {\n        let node = Arc::make_mut(&mut self.node);\n\n        node.insert(path, id)\n            .map_err(|err| format!(\"Invalid route {path:?}: {err}\"))\n    }\n\n    fn new_route(&mut self, path: &str, endpoint: Endpoint<S>) -> Result<(), String> {\n        let id = RouteId(self.routes.len());\n        self.set_node(path, id)?;\n        self.routes.push(endpoint);\n        Ok(())\n    }\n\n    pub(super) fn merge(&mut self, other: Self) -> Result<(), Cow<'static, str>> {\n        let Self {\n            routes,\n            node,\n            v7_checks,\n        } = other;\n\n        // If either of the two did not allow paths starting with `:` or `*`, do not allow them for the merged router either.\n        self.v7_checks |= v7_checks;\n\n        for (id, route) in routes.into_iter().enumerate() {\n            let route_id = RouteId(id);\n            let path = node\n                .route_id_to_path\n                .get(&route_id)\n                .expect(\"no path for route id. This is a bug in axum. Please file an issue\");\n\n            match route {\n                Endpoint::MethodRouter(method_router) => self.route(path, method_router)?,\n                Endpoint::Route(route) => self.route_service(path, route)?,\n            }\n        }\n\n        Ok(())\n    }\n\n    pub(super) fn nest(\n        &mut self,\n        path_to_nest_at: &str,\n        router: Self,\n    ) -> Result<(), Cow<'static, str>> {\n        let prefix = validate_nest_path(self.v7_checks, path_to_nest_at)?;\n\n        let Self {\n            routes,\n            node,\n            // Ignore the configuration of the nested router\n            v7_checks: _,\n        } = router;\n\n        for (id, endpoint) in routes.into_iter().enumerate() {\n            let route_id = RouteId(id);\n            let inner_path = node\n                .route_id_to_path\n                .get(&route_id)\n                .expect(\"no path for route id. This is a bug in axum. Please file an issue\");\n\n            let path = path_for_nested_route(prefix, inner_path);\n\n            let layer = (\n                StripPrefix::layer(prefix),\n                SetNestedPath::layer(path_to_nest_at),\n            );\n            match endpoint.layer(layer) {\n                Endpoint::MethodRouter(method_router) => {\n                    self.route(&path, method_router)?;\n                }\n                Endpoint::Route(route) => {\n                    self.route_endpoint(&path, Endpoint::Route(route))?;\n                }\n            }\n        }\n\n        Ok(())\n    }\n\n    pub(super) fn nest_service<T>(\n        &mut self,\n        path_to_nest_at: &str,\n        svc: T,\n    ) -> Result<(), Cow<'static, str>>\n    where\n        T: Service<Request, Error = Infallible> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse,\n        T::Future: Send + 'static,\n    {\n        let path = validate_nest_path(self.v7_checks, path_to_nest_at)?;\n        let prefix = path;\n\n        let path = if path.ends_with('/') {\n            format!(\"{path}{{*{NEST_TAIL_PARAM}}}\")\n        } else {\n            format!(\"{path}/{{*{NEST_TAIL_PARAM}}}\")\n        };\n\n        let layer = (\n            StripPrefix::layer(prefix),\n            SetNestedPath::layer(path_to_nest_at),\n        );\n        let endpoint = Endpoint::Route(Route::new(layer.layer(svc)));\n\n        self.route_endpoint(&path, endpoint.clone())?;\n\n        // `/{*rest}` is not matched by `/` so we need to also register a router at the\n        // prefix itself. Otherwise if you were to nest at `/foo` then `/foo` itself\n        // wouldn't match, which it should\n        self.route_endpoint(prefix, endpoint.clone())?;\n        if !prefix.ends_with('/') {\n            // same goes for `/foo/`, that should also match\n            self.route_endpoint(&format!(\"{prefix}/\"), endpoint)?;\n        }\n\n        Ok(())\n    }\n\n    pub(super) fn layer<L>(self, layer: L) -> Self\n    where\n        L: Layer<Route> + Clone + Send + Sync + 'static,\n        L::Service: Service<Request> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n    {\n        let routes = self\n            .routes\n            .into_iter()\n            .map(|endpoint| endpoint.layer(layer.clone()))\n            .collect();\n\n        Self {\n            routes,\n            node: self.node,\n            v7_checks: self.v7_checks,\n        }\n    }\n\n    #[track_caller]\n    pub(super) fn route_layer<L>(self, layer: L) -> Self\n    where\n        L: Layer<Route> + Clone + Send + Sync + 'static,\n        L::Service: Service<Request> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n    {\n        if self.routes.is_empty() {\n            panic!(\n                \"Adding a route_layer before any routes is a no-op. \\\n                 Add the routes you want the layer to apply to first.\"\n            );\n        }\n\n        let routes = self\n            .routes\n            .into_iter()\n            .map(|endpoint| endpoint.layer(layer.clone()))\n            .collect();\n\n        Self {\n            routes,\n            node: self.node,\n            v7_checks: self.v7_checks,\n        }\n    }\n\n    pub(super) fn has_routes(&self) -> bool {\n        !self.routes.is_empty()\n    }\n\n    pub(super) fn with_state<S2>(self, state: S) -> PathRouter<S2> {\n        let routes = self\n            .routes\n            .into_iter()\n            .map(|endpoint| match endpoint {\n                Endpoint::MethodRouter(method_router) => {\n                    Endpoint::MethodRouter(method_router.with_state(state.clone()))\n                }\n                Endpoint::Route(route) => Endpoint::Route(route),\n            })\n            .collect();\n\n        PathRouter {\n            routes,\n            node: self.node,\n            v7_checks: self.v7_checks,\n        }\n    }\n\n    #[allow(clippy::result_large_err)]\n    pub(super) fn call_with_state(\n        &self,\n        #[cfg_attr(not(feature = \"original-uri\"), allow(unused_mut))] mut req: Request,\n        state: S,\n    ) -> Result<RouteFuture<Infallible>, (Request, S)> {\n        #[cfg(feature = \"original-uri\")]\n        {\n            use crate::extract::OriginalUri;\n\n            if req.extensions().get::<OriginalUri>().is_none() {\n                let original_uri = OriginalUri(req.uri().clone());\n                req.extensions_mut().insert(original_uri);\n            }\n        }\n\n        let (mut parts, body) = req.into_parts();\n\n        match self.node.at(parts.uri.path()) {\n            Ok(match_) => {\n                let id = *match_.value;\n\n                #[cfg(feature = \"matched-path\")]\n                crate::extract::matched_path::set_matched_path_for_request(\n                    id,\n                    &self.node.route_id_to_path,\n                    &mut parts.extensions,\n                );\n\n                url_params::insert_url_params(&mut parts.extensions, &match_.params);\n\n                let endpoint = self\n                    .routes\n                    .get(id.0)\n                    .expect(\"no route for id. This is a bug in axum. Please file an issue\");\n\n                let req = Request::from_parts(parts, body);\n                match endpoint {\n                    Endpoint::MethodRouter(method_router) => {\n                        Ok(method_router.call_with_state(req, state))\n                    }\n                    Endpoint::Route(route) => Ok(route.clone().call_owned(req)),\n                }\n            }\n            // explicitly handle all variants in case matchit adds\n            // new ones we need to handle differently\n            Err(MatchError::NotFound) => Err((Request::from_parts(parts, body), state)),\n        }\n    }\n}\n\nimpl<S> Default for PathRouter<S> {\n    fn default() -> Self {\n        Self {\n            routes: Default::default(),\n            node: Default::default(),\n            v7_checks: true,\n        }\n    }\n}\n\nimpl<S> fmt::Debug for PathRouter<S> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"PathRouter\")\n            .field(\"routes\", &self.routes)\n            .field(\"node\", &self.node)\n            .finish()\n    }\n}\n\nimpl<S> Clone for PathRouter<S> {\n    fn clone(&self) -> Self {\n        Self {\n            routes: self.routes.clone(),\n            node: self.node.clone(),\n            v7_checks: self.v7_checks,\n        }\n    }\n}\n\n/// Wrapper around `matchit::Router` that supports merging two `Router`s.\n#[derive(Clone, Default)]\nstruct Node {\n    inner: matchit::Router<RouteId>,\n    route_id_to_path: HashMap<RouteId, Arc<str>>,\n    path_to_route_id: HashMap<Arc<str>, RouteId>,\n}\n\nimpl Node {\n    fn insert(\n        &mut self,\n        path: impl Into<String>,\n        val: RouteId,\n    ) -> Result<(), matchit::InsertError> {\n        let path = path.into();\n\n        self.inner.insert(&path, val)?;\n\n        let shared_path: Arc<str> = path.into();\n        self.route_id_to_path.insert(val, shared_path.clone());\n        self.path_to_route_id.insert(shared_path, val);\n\n        Ok(())\n    }\n\n    fn at<'n, 'p>(\n        &'n self,\n        path: &'p str,\n    ) -> Result<matchit::Match<'n, 'p, &'n RouteId>, MatchError> {\n        self.inner.at(path)\n    }\n}\n\nimpl fmt::Debug for Node {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Node\")\n            .field(\"paths\", &self.route_id_to_path)\n            .finish()\n    }\n}\n\nfn validate_nest_path(v7_checks: bool, path: &str) -> Result<&str, &'static str> {\n    if !path.starts_with('/') {\n        return Err(\"Nesting paths must start with a `/`.\");\n    }\n    if path.len() < 2 {\n        return Err(\"Nesting at `/` is not supported.\");\n    }\n\n    if path.split('/').any(|segment| {\n        segment.starts_with(\"{*\") && segment.ends_with('}') && !segment.ends_with(\"}}\")\n    }) {\n        return Err(\"Invalid route: nested routes cannot contain wildcards (*)\");\n    }\n\n    if v7_checks {\n        validate_v07_paths(path)?;\n    }\n\n    Ok(path)\n}\n\npub(crate) fn path_for_nested_route<'a>(prefix: &'a str, path: &'a str) -> Cow<'a, str> {\n    debug_assert!(prefix.starts_with('/'));\n    debug_assert!(path.starts_with('/'));\n\n    if prefix.ends_with('/') {\n        format!(\"{prefix}{}\", path.trim_start_matches('/')).into()\n    } else if path == \"/\" {\n        prefix.into()\n    } else {\n        format!(\"{prefix}{path}\").into()\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/route.rs",
    "content": "use crate::{\n    body::{Body, HttpBody},\n    response::Response,\n    util::MapIntoResponse,\n};\nuse axum_core::{extract::Request, response::IntoResponse};\nuse bytes::Bytes;\nuse http::{\n    header::{self, CONTENT_LENGTH},\n    HeaderMap, HeaderValue, Method,\n};\nuse pin_project_lite::pin_project;\nuse std::{\n    convert::Infallible,\n    fmt,\n    future::Future,\n    pin::Pin,\n    task::{ready, Context, Poll},\n};\nuse tower::{\n    util::{BoxCloneSyncService, MapErrLayer, Oneshot},\n    ServiceExt,\n};\nuse tower_layer::Layer;\nuse tower_service::Service;\n\n/// How routes are stored inside a [`Router`](super::Router).\n///\n/// You normally shouldn't need to care about this type. It's used in\n/// [`Router::layer`](super::Router::layer).\npub struct Route<E = Infallible>(BoxCloneSyncService<Request, Response, E>);\n\nimpl<E> Route<E> {\n    pub(crate) fn new<T>(svc: T) -> Self\n    where\n        T: Service<Request, Error = E> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse + 'static,\n        T::Future: Send + 'static,\n    {\n        Self(BoxCloneSyncService::new(MapIntoResponse::new(svc)))\n    }\n\n    /// Variant of [`Route::call`] that takes ownership of the route to avoid cloning.\n    pub(crate) fn call_owned(self, req: Request<Body>) -> RouteFuture<E> {\n        let req = req.map(Body::new);\n        self.oneshot_inner_owned(req).not_top_level()\n    }\n\n    pub(crate) fn oneshot_inner(&self, req: Request) -> RouteFuture<E> {\n        let method = req.method().clone();\n        RouteFuture::new(method, self.0.clone().oneshot(req))\n    }\n\n    /// Variant of [`Route::oneshot_inner`] that takes ownership of the route to avoid cloning.\n    pub(crate) fn oneshot_inner_owned(self, req: Request) -> RouteFuture<E> {\n        let method = req.method().clone();\n        RouteFuture::new(method, self.0.oneshot(req))\n    }\n\n    pub(crate) fn layer<L, NewError>(self, layer: L) -> Route<NewError>\n    where\n        L: Layer<Self> + Clone + Send + 'static,\n        L::Service: Service<Request> + Clone + Send + Sync + 'static,\n        <L::Service as Service<Request>>::Response: IntoResponse + 'static,\n        <L::Service as Service<Request>>::Error: Into<NewError> + 'static,\n        <L::Service as Service<Request>>::Future: Send + 'static,\n        NewError: 'static,\n    {\n        let layer = (MapErrLayer::new(Into::into), layer);\n\n        Route::new(layer.layer(self))\n    }\n}\n\nimpl<E> Clone for Route<E> {\n    #[track_caller]\n    fn clone(&self) -> Self {\n        Self(self.0.clone())\n    }\n}\n\nimpl<E> fmt::Debug for Route<E> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Route\").finish()\n    }\n}\n\nimpl<B, E> Service<Request<B>> for Route<E>\nwhere\n    B: HttpBody<Data = bytes::Bytes> + Send + 'static,\n    B::Error: Into<axum_core::BoxError>,\n{\n    type Response = Response;\n    type Error = E;\n    type Future = RouteFuture<E>;\n\n    #[inline]\n    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        Poll::Ready(Ok(()))\n    }\n\n    #[inline]\n    fn call(&mut self, req: Request<B>) -> Self::Future {\n        self.oneshot_inner(req.map(Body::new)).not_top_level()\n    }\n}\n\npin_project! {\n    /// Response future for [`Route`].\n    pub struct RouteFuture<E> {\n        #[pin]\n        inner: Oneshot<BoxCloneSyncService<Request, Response, E>, Request>,\n        method: Method,\n        allow_header: Option<Bytes>,\n        top_level: bool,\n    }\n}\n\nimpl<E> RouteFuture<E> {\n    fn new(\n        method: Method,\n        inner: Oneshot<BoxCloneSyncService<Request, Response, E>, Request>,\n    ) -> Self {\n        Self {\n            inner,\n            method,\n            allow_header: None,\n            top_level: true,\n        }\n    }\n\n    pub(crate) fn allow_header(mut self, allow_header: Bytes) -> Self {\n        self.allow_header = Some(allow_header);\n        self\n    }\n\n    pub(crate) fn not_top_level(mut self) -> Self {\n        self.top_level = false;\n        self\n    }\n}\n\nimpl<E> Future for RouteFuture<E> {\n    type Output = Result<Response, E>;\n\n    #[inline]\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        let this = self.project();\n        let mut res = ready!(this.inner.poll(cx))?;\n\n        if *this.method == Method::CONNECT && res.status().is_success() {\n            // From https://httpwg.org/specs/rfc9110.html#CONNECT:\n            // > A server MUST NOT send any Transfer-Encoding or\n            // > Content-Length header fields in a 2xx (Successful)\n            // > response to CONNECT.\n            if res.headers().contains_key(&CONTENT_LENGTH)\n                || res.headers().contains_key(&header::TRANSFER_ENCODING)\n                || res.size_hint().lower() != 0\n            {\n                error!(\"response to CONNECT with nonempty body\");\n                res = res.map(|_| Body::empty());\n            }\n        } else if *this.top_level {\n            if res.status() == http::StatusCode::METHOD_NOT_ALLOWED {\n                // From https://httpwg.org/specs/rfc9110.html#field.allow:\n                // An origin server MUST generate an `Allow` header field in a 405 (Method Not Allowed) response and MAY do so in any other response.\n                set_allow_header(res.headers_mut(), this.allow_header);\n            }\n\n            // make sure to set content-length before removing the body\n            set_content_length(&res.size_hint(), res.headers_mut());\n\n            if *this.method == Method::HEAD {\n                *res.body_mut() = Body::empty();\n            }\n        }\n\n        Poll::Ready(Ok(res))\n    }\n}\n\nfn set_allow_header(headers: &mut HeaderMap, allow_header: &mut Option<Bytes>) {\n    match allow_header.take() {\n        Some(allow_header) if !headers.contains_key(header::ALLOW) => {\n            headers.insert(\n                header::ALLOW,\n                HeaderValue::from_maybe_shared(allow_header).expect(\"invalid `Allow` header\"),\n            );\n        }\n        _ => {}\n    }\n}\n\nfn set_content_length(size_hint: &http_body::SizeHint, headers: &mut HeaderMap) {\n    if headers.contains_key(CONTENT_LENGTH) {\n        return;\n    }\n\n    if let Some(size) = size_hint.exact() {\n        let header_value = if size == 0 {\n            #[allow(clippy::declare_interior_mutable_const)]\n            const ZERO: HeaderValue = HeaderValue::from_static(\"0\");\n\n            ZERO\n        } else {\n            let mut buffer = itoa::Buffer::new();\n            HeaderValue::from_str(buffer.format(size)).unwrap()\n        };\n\n        headers.insert(CONTENT_LENGTH, header_value);\n    }\n}\n\npin_project! {\n    /// A [`RouteFuture`] that always yields a [`Response`].\n    pub struct InfallibleRouteFuture {\n        #[pin]\n        future: RouteFuture<Infallible>,\n    }\n}\n\nimpl InfallibleRouteFuture {\n    pub(crate) fn new(future: RouteFuture<Infallible>) -> Self {\n        Self { future }\n    }\n}\n\nimpl Future for InfallibleRouteFuture {\n    type Output = Response;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        match ready!(self.project().future.poll(cx)) {\n            Ok(response) => Poll::Ready(response),\n            Err(err) => match err {},\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn traits() {\n        use crate::test_helpers::*;\n        assert_send::<Route<()>>();\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/strip_prefix.rs",
    "content": "use http::{Request, Uri};\nuse std::{\n    sync::Arc,\n    task::{Context, Poll},\n};\nuse tower::Layer;\nuse tower_layer::layer_fn;\nuse tower_service::Service;\n\n#[derive(Clone)]\npub(super) struct StripPrefix<S> {\n    inner: S,\n    prefix: Arc<str>,\n}\n\nimpl<S> StripPrefix<S> {\n    pub(super) fn layer(prefix: &str) -> impl Layer<S, Service = Self> + Clone {\n        let prefix = Arc::from(prefix);\n        layer_fn(move |inner| Self {\n            inner,\n            prefix: Arc::clone(&prefix),\n        })\n    }\n}\n\nimpl<S, B> Service<Request<B>> for StripPrefix<S>\nwhere\n    S: Service<Request<B>>,\n{\n    type Response = S::Response;\n    type Error = S::Error;\n    type Future = S::Future;\n\n    #[inline]\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, mut req: Request<B>) -> Self::Future {\n        if let Some(new_uri) = strip_prefix(req.uri(), &self.prefix) {\n            *req.uri_mut() = new_uri;\n        }\n        self.inner.call(req)\n    }\n}\n\nfn strip_prefix(uri: &Uri, prefix: &str) -> Option<Uri> {\n    let path_and_query = uri.path_and_query()?;\n\n    // Check whether the prefix matches the path and if so how long the matching prefix is.\n    //\n    // For example:\n    //\n    // prefix = /api\n    // path   = /api/users\n    //          ^^^^ this much is matched and the length is 4. Thus if we chop off the first 4\n    //          characters we get the remainder\n    //\n    // prefix = /api/{version}\n    // path   = /api/v0/users\n    //          ^^^^^^^ this much is matched and the length is 7.\n    let mut matching_prefix_length = Some(0);\n    for item in zip_longest(segments(path_and_query.path()), segments(prefix)) {\n        // count the `/`\n        *matching_prefix_length.as_mut().unwrap() += 1;\n\n        match item {\n            Item::Both(path_segment, prefix_segment) => {\n                if is_capture(prefix_segment) || path_segment == prefix_segment {\n                    // the prefix segment is either a param, which matches anything, or\n                    // it actually matches the path segment\n                    *matching_prefix_length.as_mut().unwrap() += path_segment.len();\n                } else if prefix_segment.is_empty() {\n                    // the prefix ended in a `/` so we got a match.\n                    //\n                    // For example:\n                    //\n                    // prefix = /foo/\n                    // path   = /foo/bar\n                    //\n                    // The prefix matches and the new path should be `/bar`\n                    break;\n                } else {\n                    // the prefix segment didn't match so there is no match\n                    matching_prefix_length = None;\n                    break;\n                }\n            }\n            // the path had more segments than the prefix but we got a match.\n            //\n            // For example:\n            //\n            // prefix = /foo\n            // path   = /foo/bar\n            Item::First(_) => {\n                break;\n            }\n            // the prefix had more segments than the path so there is no match\n            Item::Second(_) => {\n                matching_prefix_length = None;\n                break;\n            }\n        }\n    }\n\n    // if the prefix matches it will always do so up until a `/`, it cannot match only\n    // part of a segment. Therefore this will always be at a char boundary and `split_at` won't\n    // panic\n    let after_prefix = uri.path().split_at(matching_prefix_length?).1;\n\n    let new_path_and_query = match (after_prefix.starts_with('/'), path_and_query.query()) {\n        (true, None) => after_prefix.parse().unwrap(),\n        (true, Some(query)) => format!(\"{after_prefix}?{query}\").parse().unwrap(),\n        (false, None) => format!(\"/{after_prefix}\").parse().unwrap(),\n        (false, Some(query)) => format!(\"/{after_prefix}?{query}\").parse().unwrap(),\n    };\n\n    let mut parts = uri.clone().into_parts();\n    parts.path_and_query = Some(new_path_and_query);\n\n    Some(Uri::from_parts(parts).unwrap())\n}\n\nfn segments(s: &str) -> impl Iterator<Item = &str> {\n    assert!(\n        s.starts_with('/'),\n        \"path didn't start with '/'. axum should have caught this higher up.\"\n    );\n\n    s.split('/')\n        // skip one because paths always start with `/` so `/a/b` would become [\"\", \"a\", \"b\"]\n        // otherwise\n        .skip(1)\n}\n\nfn zip_longest<I, I2>(a: I, b: I2) -> impl Iterator<Item = Item<I::Item>>\nwhere\n    I: Iterator,\n    I2: Iterator<Item = I::Item>,\n{\n    let a = a.map(Some).chain(std::iter::repeat_with(|| None));\n    let b = b.map(Some).chain(std::iter::repeat_with(|| None));\n    a.zip(b).map_while(|(a, b)| match (a, b) {\n        (Some(a), Some(b)) => Some(Item::Both(a, b)),\n        (Some(a), None) => Some(Item::First(a)),\n        (None, Some(b)) => Some(Item::Second(b)),\n        (None, None) => None,\n    })\n}\n\nfn is_capture(segment: &str) -> bool {\n    segment.starts_with('{')\n        && segment.ends_with('}')\n        && !segment.starts_with(\"{{\")\n        && !segment.ends_with(\"}}\")\n        && !segment.starts_with(\"{*\")\n}\n\n#[derive(Debug)]\nenum Item<T> {\n    Both(T, T),\n    First(T),\n    Second(T),\n}\n\n#[cfg(test)]\nmod tests {\n    #[allow(unused_imports)]\n    use super::*;\n    use quickcheck::Arbitrary;\n    use quickcheck_macros::quickcheck;\n\n    macro_rules! test {\n        (\n            $name:ident,\n            uri = $uri:literal,\n            prefix = $prefix:literal,\n            expected = $expected:expr,\n        ) => {\n            #[test]\n            fn $name() {\n                let uri = $uri.parse().unwrap();\n                let new_uri = strip_prefix(&uri, $prefix).map(|uri| uri.to_string());\n                assert_eq!(new_uri.as_deref(), $expected);\n            }\n        };\n    }\n\n    test!(empty, uri = \"/\", prefix = \"/\", expected = Some(\"/\"),);\n\n    test!(\n        single_segment,\n        uri = \"/a\",\n        prefix = \"/a\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        single_segment_root_uri,\n        uri = \"/\",\n        prefix = \"/a\",\n        expected = None,\n    );\n\n    // the prefix is empty, so removing it should have no effect\n    test!(\n        single_segment_root_prefix,\n        uri = \"/a\",\n        prefix = \"/\",\n        expected = Some(\"/a\"),\n    );\n\n    test!(\n        single_segment_no_match,\n        uri = \"/a\",\n        prefix = \"/b\",\n        expected = None,\n    );\n\n    test!(\n        single_segment_trailing_slash,\n        uri = \"/a/\",\n        prefix = \"/a/\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        single_segment_trailing_slash_2,\n        uri = \"/a\",\n        prefix = \"/a/\",\n        expected = None,\n    );\n\n    test!(\n        single_segment_trailing_slash_3,\n        uri = \"/a/\",\n        prefix = \"/a\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        multi_segment,\n        uri = \"/a/b\",\n        prefix = \"/a\",\n        expected = Some(\"/b\"),\n    );\n\n    test!(\n        multi_segment_2,\n        uri = \"/b/a\",\n        prefix = \"/a\",\n        expected = None,\n    );\n\n    test!(\n        multi_segment_3,\n        uri = \"/a\",\n        prefix = \"/a/b\",\n        expected = None,\n    );\n\n    test!(\n        multi_segment_4,\n        uri = \"/a/b\",\n        prefix = \"/b\",\n        expected = None,\n    );\n\n    test!(\n        multi_segment_trailing_slash,\n        uri = \"/a/b/\",\n        prefix = \"/a/b/\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        multi_segment_trailing_slash_2,\n        uri = \"/a/b\",\n        prefix = \"/a/b/\",\n        expected = None,\n    );\n\n    test!(\n        multi_segment_trailing_slash_3,\n        uri = \"/a/b/\",\n        prefix = \"/a/b\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        param_0,\n        uri = \"/\",\n        prefix = \"/{param}\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        param_1,\n        uri = \"/a\",\n        prefix = \"/{param}\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        param_2,\n        uri = \"/a/b\",\n        prefix = \"/{param}\",\n        expected = Some(\"/b\"),\n    );\n\n    test!(\n        param_3,\n        uri = \"/b/a\",\n        prefix = \"/{param}\",\n        expected = Some(\"/a\"),\n    );\n\n    test!(\n        param_4,\n        uri = \"/a/b\",\n        prefix = \"/a/{param}\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        param_5,\n        uri = \"/b/a\",\n        prefix = \"/a/{param}\",\n        expected = None,\n    );\n\n    test!(\n        param_6,\n        uri = \"/a/b\",\n        prefix = \"/{param}/a\",\n        expected = None,\n    );\n\n    test!(\n        param_7,\n        uri = \"/b/a\",\n        prefix = \"/{param}/a\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        param_8,\n        uri = \"/a/b/c\",\n        prefix = \"/a/{param}/c\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        param_9,\n        uri = \"/c/b/a\",\n        prefix = \"/a/{param}/c\",\n        expected = None,\n    );\n\n    test!(\n        param_10,\n        uri = \"/a/\",\n        prefix = \"/{param}\",\n        expected = Some(\"/\"),\n    );\n\n    test!(param_11, uri = \"/a\", prefix = \"/{param}/\", expected = None,);\n\n    test!(\n        param_12,\n        uri = \"/a/\",\n        prefix = \"/{param}/\",\n        expected = Some(\"/\"),\n    );\n\n    test!(\n        param_13,\n        uri = \"/a/a\",\n        prefix = \"/a/\",\n        expected = Some(\"/a\"),\n    );\n\n    #[quickcheck]\n    fn does_not_panic(uri_and_prefix: UriAndPrefix) -> bool {\n        let UriAndPrefix { uri, prefix } = uri_and_prefix;\n        strip_prefix(&uri, &prefix);\n        true\n    }\n\n    #[derive(Clone, Debug)]\n    struct UriAndPrefix {\n        uri: Uri,\n        prefix: String,\n    }\n\n    impl Arbitrary for UriAndPrefix {\n        fn arbitrary(g: &mut quickcheck::Gen) -> Self {\n            let mut uri = String::new();\n            let mut prefix = String::new();\n\n            let size = u8_between(1, 20, g);\n\n            for _ in 0..size {\n                let segment = ascii_alphanumeric(g);\n\n                uri.push('/');\n                uri.push_str(&segment);\n\n                prefix.push('/');\n\n                let make_matching_segment = bool::arbitrary(g);\n                let make_capture = bool::arbitrary(g);\n\n                match (make_matching_segment, make_capture) {\n                    (_, true) => {\n                        prefix.push_str(\":a\");\n                    }\n                    (true, false) => {\n                        prefix.push_str(&segment);\n                    }\n                    (false, false) => {\n                        prefix.push_str(&ascii_alphanumeric(g));\n                    }\n                }\n            }\n\n            if bool::arbitrary(g) {\n                uri.push('/');\n            }\n\n            if bool::arbitrary(g) {\n                prefix.push('/');\n            }\n\n            Self {\n                uri: uri.parse().unwrap(),\n                prefix,\n            }\n        }\n    }\n\n    fn ascii_alphanumeric(g: &mut quickcheck::Gen) -> String {\n        #[derive(Clone)]\n        struct AsciiAlphanumeric(String);\n\n        impl Arbitrary for AsciiAlphanumeric {\n            fn arbitrary(g: &mut quickcheck::Gen) -> Self {\n                let mut out = String::new();\n\n                let size = u8_between(1, 20, g) as usize;\n\n                while out.len() < size {\n                    let c = char::arbitrary(g);\n                    if c.is_ascii_alphanumeric() {\n                        out.push(c);\n                    }\n                }\n                Self(out)\n            }\n        }\n\n        let out = AsciiAlphanumeric::arbitrary(g).0;\n        assert!(!out.is_empty());\n        out\n    }\n\n    fn u8_between(lower: u8, upper: u8, g: &mut quickcheck::Gen) -> u8 {\n        loop {\n            let size = u8::arbitrary(g);\n            if size > lower && size <= upper {\n                break size;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/tests/fallback.rs",
    "content": "use super::*;\nuse crate::middleware::{map_request, map_response};\n\n#[crate::test]\nasync fn basic() {\n    let app = Router::new()\n        .route(\"/foo\", get(|| async {}))\n        .fallback(|| async { \"fallback\" });\n\n    let client = TestClient::new(app);\n\n    assert_eq!(client.get(\"/foo\").await.status(), StatusCode::OK);\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"fallback\");\n}\n\n#[crate::test]\nasync fn nest() {\n    let app = Router::new()\n        .nest(\"/foo\", Router::new().route(\"/bar\", get(|| async {})))\n        .fallback(|| async { \"fallback\" });\n\n    let client = TestClient::new(app);\n\n    assert_eq!(client.get(\"/foo/bar\").await.status(), StatusCode::OK);\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"fallback\");\n}\n\n#[crate::test]\nasync fn two() {\n    let app = Router::new()\n        .route(\"/first\", get(|| async {}))\n        .route(\"/second\", get(|| async {}))\n        .fallback(get(|| async { \"fallback\" }));\n    let client = TestClient::new(app);\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"fallback\");\n}\n\n#[crate::test]\nasync fn or() {\n    let one = Router::new().route(\"/one\", get(|| async {}));\n    let two = Router::new().route(\"/two\", get(|| async {}));\n\n    let app = one.merge(two).fallback(|| async { \"fallback\" });\n\n    let client = TestClient::new(app);\n\n    assert_eq!(client.get(\"/one\").await.status(), StatusCode::OK);\n    assert_eq!(client.get(\"/two\").await.status(), StatusCode::OK);\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"fallback\");\n}\n\n#[crate::test]\nasync fn fallback_accessing_state() {\n    let app = Router::new()\n        .fallback(|State(state): State<&'static str>| async move { state })\n        .with_state(\"state\");\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"state\");\n}\n\nasync fn inner_fallback() -> impl IntoResponse {\n    (StatusCode::NOT_FOUND, \"inner\")\n}\n\nasync fn outer_fallback() -> impl IntoResponse {\n    (StatusCode::NOT_FOUND, \"outer\")\n}\n\n#[crate::test]\nasync fn nested_router_inherits_fallback() {\n    let inner = Router::new();\n    let app = Router::new().nest(\"/foo\", inner).fallback(outer_fallback);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn doesnt_inherit_fallback_if_overridden() {\n    let inner = Router::new().fallback(inner_fallback);\n    let app = Router::new().nest(\"/foo\", inner).fallback(outer_fallback);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"inner\");\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn deeply_nested_inherit_from_top() {\n    let app = Router::new()\n        .nest(\"/foo\", Router::new().nest(\"/bar\", Router::new()))\n        .fallback(outer_fallback);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn deeply_nested_inherit_from_middle() {\n    let app = Router::new().nest(\n        \"/foo\",\n        Router::new()\n            .nest(\"/bar\", Router::new())\n            .fallback(outer_fallback),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn with_middleware_on_inner_fallback() {\n    async fn never_called<B>(_: Request<B>) -> Request<B> {\n        panic!(\"should never be called\")\n    }\n\n    let inner = Router::new().layer(map_request(never_called));\n    let app = Router::new().nest(\"/foo\", inner).fallback(outer_fallback);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn also_inherits_default_layered_fallback() {\n    async fn set_header<B>(mut res: Response<B>) -> Response<B> {\n        res.headers_mut()\n            .insert(\"x-from-fallback\", \"1\".parse().unwrap());\n        res\n    }\n\n    let inner = Router::new();\n    let app = Router::new()\n        .nest(\"/foo\", inner)\n        .fallback(outer_fallback)\n        .layer(map_response(set_header));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.headers()[\"x-from-fallback\"], \"1\");\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn nest_fallback_on_inner() {\n    let app = Router::new()\n        .nest(\n            \"/foo\",\n            Router::new()\n                .route(\"/\", get(|| async {}))\n                .fallback(|| async { (StatusCode::NOT_FOUND, \"inner fallback\") }),\n        )\n        .fallback(|| async { (StatusCode::NOT_FOUND, \"outer fallback\") });\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/not-found\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"inner fallback\");\n}\n\n// https://github.com/tokio-rs/axum/issues/1931\n#[crate::test]\nasync fn doesnt_panic_if_used_with_nested_router() {\n    async fn handler() {}\n\n    let routes_static =\n        Router::new().nest_service(\"/foo\", crate::routing::get_service(handler.into_service()));\n\n    let routes_all = Router::new().fallback_service(routes_static);\n\n    let client = TestClient::new(routes_all);\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn issue_2072() {\n    let nested_routes = Router::new().fallback(inner_fallback);\n\n    let app = Router::new()\n        .nest(\"/nested\", nested_routes)\n        .merge(Router::new());\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/nested/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"inner\");\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"\");\n}\n\n#[crate::test]\nasync fn issue_2072_outer_fallback_before_merge() {\n    let nested_routes = Router::new().fallback(inner_fallback);\n\n    let app = Router::new()\n        .nest(\"/nested\", nested_routes)\n        .fallback(outer_fallback)\n        .merge(Router::new());\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/nested/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"inner\");\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn issue_2072_outer_fallback_after_merge() {\n    let nested_routes = Router::new().fallback(inner_fallback);\n\n    let app = Router::new()\n        .nest(\"/nested\", nested_routes)\n        .merge(Router::new())\n        .fallback(outer_fallback);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/nested/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"inner\");\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn merge_router_with_fallback_into_nested_router_with_fallback() {\n    let nested_routes = Router::new().fallback(inner_fallback);\n\n    let app = Router::new()\n        .nest(\"/nested\", nested_routes)\n        .merge(Router::new().fallback(outer_fallback));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/nested/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"inner\");\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn merging_nested_router_with_fallback_into_router_with_fallback() {\n    let nested_routes = Router::new().fallback(inner_fallback);\n\n    let app = Router::new()\n        .fallback(outer_fallback)\n        .merge(Router::new().nest(\"/nested\", nested_routes));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/nested/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"inner\");\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn merge_empty_into_router_with_fallback() {\n    let app = Router::new().fallback(outer_fallback).merge(Router::new());\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn merge_router_with_fallback_into_empty() {\n    let app = Router::new().merge(Router::new().fallback(outer_fallback));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/does-not-exist\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    assert_eq!(res.text().await, \"outer\");\n}\n\n#[crate::test]\nasync fn mna_fallback_not_405() {\n    let app = Router::new()\n        .route(\"/path\", get(|| async { \"path\" }))\n        .method_not_allowed_fallback(|| async { (http::StatusCode::NOT_FOUND, \"Not Found\") });\n\n    let client = TestClient::new(app);\n    let method_not_allowed_fallback = client.post(\"/path\").await;\n\n    assert_eq!(\n        method_not_allowed_fallback.status(),\n        http::StatusCode::NOT_FOUND\n    );\n    assert_eq!(method_not_allowed_fallback.headers().get(ALLOW), None);\n    assert_eq!(method_not_allowed_fallback.text().await, \"Not Found\");\n}\n\n#[crate::test]\nasync fn mna_fallback_with_existing_fallback() {\n    let app = Router::new()\n        .route(\n            \"/\",\n            get(|| async { \"test\" }).fallback(|| async { \"index fallback\" }),\n        )\n        .route(\"/path\", get(|| async { \"path\" }))\n        .method_not_allowed_fallback(|| async { \"method not allowed fallback\" });\n\n    let client = TestClient::new(app);\n    let index_fallback = client.post(\"/\").await;\n    let method_not_allowed_fallback = client.post(\"/path\").await;\n\n    assert_eq!(index_fallback.text().await, \"index fallback\");\n    assert_eq!(\n        method_not_allowed_fallback.text().await,\n        \"method not allowed fallback\"\n    );\n}\n\n#[crate::test]\nasync fn mna_fallback_with_state() {\n    let app = Router::new()\n        .route(\"/\", get(|| async { \"index\" }))\n        .method_not_allowed_fallback(|State(state): State<&'static str>| async move { state })\n        .with_state(\"state\");\n\n    let client = TestClient::new(app);\n    let res = client.post(\"/\").await;\n    assert_eq!(res.text().await, \"state\");\n}\n\n#[crate::test]\nasync fn mna_fallback_with_unused_state() {\n    let app = Router::new()\n        .route(\"/\", get(|| async { \"index\" }))\n        .with_state(())\n        .method_not_allowed_fallback(|| async move { \"bla\" });\n\n    let client = TestClient::new(app);\n    let res = client.post(\"/\").await;\n    assert_eq!(res.text().await, \"bla\");\n}\n\n#[crate::test]\nasync fn state_isnt_cloned_too_much_with_fallback() {\n    let state = CountingCloneableState::new();\n\n    let app = Router::new()\n        .fallback(|_: State<CountingCloneableState>| async {})\n        .with_state(state.clone());\n\n    let client = TestClient::new(app);\n\n    // ignore clones made during setup\n    state.setup_done();\n\n    client.get(\"/does-not-exist\").await;\n\n    assert_eq!(state.count(), 3);\n}\n"
  },
  {
    "path": "axum/src/routing/tests/get_to_head.rs",
    "content": "use super::*;\nuse http::Method;\nuse tower::ServiceExt;\n\nmod for_handlers {\n    use super::*;\n\n    #[crate::test]\n    async fn get_handles_head() {\n        let app = Router::new().route(\n            \"/\",\n            get(|| async {\n                let mut headers = HeaderMap::new();\n                headers.insert(\"x-some-header\", \"foobar\".parse().unwrap());\n                (headers, \"you shouldn't see this\")\n            }),\n        );\n\n        // don't use reqwest because it always strips bodies from HEAD responses\n        let res = app\n            .oneshot(\n                Request::builder()\n                    .uri(\"/\")\n                    .method(Method::HEAD)\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.headers()[\"x-some-header\"], \"foobar\");\n\n        let body = BodyExt::collect(res.into_body()).await.unwrap().to_bytes();\n        assert_eq!(body.len(), 0);\n    }\n}\n\nmod for_services {\n    use super::*;\n\n    #[crate::test]\n    async fn get_handles_head() {\n        let app = Router::new().route(\n            \"/\",\n            get_service(service_fn(|_req: Request| async move {\n                Ok::<_, Infallible>(\n                    ([(\"x-some-header\", \"foobar\")], \"you shouldn't see this\").into_response(),\n                )\n            })),\n        );\n\n        // don't use reqwest because it always strips bodies from HEAD responses\n        let res = app\n            .oneshot(\n                Request::builder()\n                    .uri(\"/\")\n                    .method(Method::HEAD)\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.headers()[\"x-some-header\"], \"foobar\");\n\n        let body = BodyExt::collect(res.into_body()).await.unwrap().to_bytes();\n        assert_eq!(body.len(), 0);\n    }\n}\n"
  },
  {
    "path": "axum/src/routing/tests/handle_error.rs",
    "content": "use super::*;\nuse std::future::pending;\nuse tower::timeout::TimeoutLayer;\n\nasync fn unit() {}\n\nasync fn forever() {\n    pending().await\n}\n\nfn timeout() -> TimeoutLayer {\n    TimeoutLayer::new(Duration::from_millis(10))\n}\n\n#[crate::test]\nasync fn handler() {\n    let app = Router::new().route(\n        \"/\",\n        get(forever.layer((\n            HandleErrorLayer::new(|_: BoxError| async { StatusCode::REQUEST_TIMEOUT }),\n            timeout(),\n        ))),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);\n}\n\n#[crate::test]\nasync fn handler_multiple_methods_first() {\n    let app = Router::new().route(\n        \"/\",\n        get(forever.layer((\n            HandleErrorLayer::new(|_: BoxError| async { StatusCode::REQUEST_TIMEOUT }),\n            timeout(),\n        )))\n        .post(unit),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);\n}\n\n#[crate::test]\nasync fn handler_multiple_methods_middle() {\n    let app = Router::new().route(\n        \"/\",\n        delete(unit)\n            .get(forever.layer((\n                HandleErrorLayer::new(|_: BoxError| async { StatusCode::REQUEST_TIMEOUT }),\n                timeout(),\n            )))\n            .post(unit),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);\n}\n\n#[crate::test]\nasync fn handler_multiple_methods_last() {\n    let app = Router::new().route(\n        \"/\",\n        delete(unit).get(forever.layer((\n            HandleErrorLayer::new(|_: BoxError| async { StatusCode::REQUEST_TIMEOUT }),\n            timeout(),\n        ))),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);\n}\n\n#[crate::test]\nasync fn handler_service_ext() {\n    let fallible_service = tower::service_fn(|_| async { Err::<(), ()>(()) });\n    let handle_error_service =\n        fallible_service.handle_error(|_| async { StatusCode::INTERNAL_SERVER_ERROR });\n\n    let app = Router::new().route(\"/\", get_service(handle_error_service));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);\n}\n"
  },
  {
    "path": "axum/src/routing/tests/merge.rs",
    "content": "use super::*;\nuse crate::extract::OriginalUri;\nuse serde_json::{json, Value};\nuse tower::limit::ConcurrencyLimitLayer;\n\n#[crate::test]\nasync fn basic() {\n    let one = Router::new()\n        .route(\"/foo\", get(|| async {}))\n        .route(\"/bar\", get(|| async {}));\n    let two = Router::new().route(\"/baz\", get(|| async {}));\n    let app = one.merge(two);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/baz\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/qux\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n}\n\n#[crate::test]\nasync fn multiple_ors_balanced_differently() {\n    let one = Router::new().route(\"/one\", get(|| async { \"one\" }));\n    let two = Router::new().route(\"/two\", get(|| async { \"two\" }));\n    let three = Router::new().route(\"/three\", get(|| async { \"three\" }));\n    let four = Router::new().route(\"/four\", get(|| async { \"four\" }));\n\n    test(\n        \"one\",\n        one.clone()\n            .merge(two.clone())\n            .merge(three.clone())\n            .merge(four.clone()),\n    )\n    .await;\n\n    test(\n        \"two\",\n        one.clone()\n            .merge(two.clone())\n            .merge(three.clone().merge(four.clone())),\n    )\n    .await;\n\n    test(\n        \"three\",\n        one.clone()\n            .merge(two.clone().merge(three.clone()).merge(four.clone())),\n    )\n    .await;\n\n    test(\"four\", one.merge(two.merge(three.merge(four)))).await;\n\n    async fn test(name: &str, app: Router) {\n        let client = TestClient::new(app);\n\n        for n in [\"one\", \"two\", \"three\", \"four\"].iter() {\n            println!(\"running: {name} / {n}\");\n            let res = client.get(&format!(\"/{n}\")).await;\n            assert_eq!(res.status(), StatusCode::OK);\n            assert_eq!(res.text().await, *n);\n        }\n    }\n}\n\n#[crate::test]\nasync fn nested_or() {\n    let bar = Router::new().route(\"/bar\", get(|| async { \"bar\" }));\n    let baz = Router::new().route(\"/baz\", get(|| async { \"baz\" }));\n\n    let bar_or_baz = bar.merge(baz);\n\n    let client = TestClient::new(bar_or_baz.clone());\n    assert_eq!(client.get(\"/bar\").await.text().await, \"bar\");\n    assert_eq!(client.get(\"/baz\").await.text().await, \"baz\");\n\n    let client = TestClient::new(Router::new().nest(\"/foo\", bar_or_baz));\n    assert_eq!(client.get(\"/foo/bar\").await.text().await, \"bar\");\n    assert_eq!(client.get(\"/foo/baz\").await.text().await, \"baz\");\n}\n\n#[crate::test]\nasync fn or_with_route_following() {\n    let one = Router::new().route(\"/one\", get(|| async { \"one\" }));\n    let two = Router::new().route(\"/two\", get(|| async { \"two\" }));\n    let app = one.merge(two).route(\"/three\", get(|| async { \"three\" }));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/one\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/two\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/three\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn layer() {\n    let one = Router::new().route(\"/foo\", get(|| async {}));\n    let two = Router::new()\n        .route(\"/bar\", get(|| async {}))\n        .layer(ConcurrencyLimitLayer::new(10));\n    let app = one.merge(two);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn layer_and_handle_error() {\n    let one = Router::new().route(\"/foo\", get(|| async {}));\n    let two = Router::new()\n        .route(\"/timeout\", get(std::future::pending::<()>))\n        .layer(TimeoutLayer::with_status_code(\n            StatusCode::REQUEST_TIMEOUT,\n            Duration::from_millis(10),\n        ));\n    let app = one.merge(two);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/timeout\").await;\n    assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn nesting() {\n    let one = Router::new().route(\"/foo\", get(|| async {}));\n    let two = Router::new().nest(\"/bar\", Router::new().route(\"/baz\", get(|| async {})));\n    let app = one.merge(two);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn boxed() {\n    let one = Router::new().route(\"/foo\", get(|| async {}));\n    let two = Router::new().route(\"/bar\", get(|| async {}));\n    let app = one.merge(two);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn many_ors() {\n    let app = Router::new()\n        .route(\"/r1\", get(|| async {}))\n        .merge(Router::new().route(\"/r2\", get(|| async {})))\n        .merge(Router::new().route(\"/r3\", get(|| async {})))\n        .merge(Router::new().route(\"/r4\", get(|| async {})))\n        .merge(Router::new().route(\"/r5\", get(|| async {})))\n        .merge(Router::new().route(\"/r6\", get(|| async {})))\n        .merge(Router::new().route(\"/r7\", get(|| async {})));\n\n    let client = TestClient::new(app);\n\n    for n in 1..=7 {\n        let res = client.get(&format!(\"/r{n}\")).await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    let res = client.get(\"/r8\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n}\n\n#[crate::test]\nasync fn services() {\n    use crate::routing::get_service;\n\n    let app = Router::new()\n        .route(\n            \"/foo\",\n            get_service(service_fn(|_: Request| async {\n                Ok::<_, Infallible>(Response::new(Body::empty()))\n            })),\n        )\n        .merge(Router::new().route(\n            \"/bar\",\n            get_service(service_fn(|_: Request| async {\n                Ok::<_, Infallible>(Response::new(Body::empty()))\n            })),\n        ));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\nasync fn all_the_uris(\n    uri: Uri,\n    OriginalUri(original_uri): OriginalUri,\n    req: Request,\n) -> impl IntoResponse {\n    Json(json!({\n        \"uri\": uri.to_string(),\n        \"request_uri\": req.uri().to_string(),\n        \"original_uri\": original_uri.to_string(),\n    }))\n}\n\n#[crate::test]\nasync fn nesting_and_seeing_the_right_uri() {\n    let one = Router::new().nest(\"/foo/\", Router::new().route(\"/bar\", get(all_the_uris)));\n    let two = Router::new().route(\"/foo\", get(all_the_uris));\n\n    let client = TestClient::new(one.merge(two));\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/bar\",\n            \"request_uri\": \"/bar\",\n            \"original_uri\": \"/foo/bar\",\n        })\n    );\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/foo\",\n            \"request_uri\": \"/foo\",\n            \"original_uri\": \"/foo\",\n        })\n    );\n}\n\n#[crate::test]\nasync fn nesting_and_seeing_the_right_uri_at_more_levels_of_nesting() {\n    let one = Router::new().nest(\n        \"/foo/\",\n        Router::new().nest(\"/bar\", Router::new().route(\"/baz\", get(all_the_uris))),\n    );\n    let two = Router::new().route(\"/foo\", get(all_the_uris));\n\n    let client = TestClient::new(one.merge(two));\n\n    let res = client.get(\"/foo/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/baz\",\n            \"request_uri\": \"/baz\",\n            \"original_uri\": \"/foo/bar/baz\",\n        })\n    );\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/foo\",\n            \"request_uri\": \"/foo\",\n            \"original_uri\": \"/foo\",\n        })\n    );\n}\n\n#[crate::test]\nasync fn nesting_and_seeing_the_right_uri_ors_with_nesting() {\n    let one = Router::new().nest(\n        \"/one\",\n        Router::new().nest(\"/bar\", Router::new().route(\"/baz\", get(all_the_uris))),\n    );\n    let two = Router::new().nest(\"/two\", Router::new().route(\"/qux\", get(all_the_uris)));\n    let three = Router::new().route(\"/three\", get(all_the_uris));\n\n    let client = TestClient::new(one.merge(two).merge(three));\n\n    let res = client.get(\"/one/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/baz\",\n            \"request_uri\": \"/baz\",\n            \"original_uri\": \"/one/bar/baz\",\n        })\n    );\n\n    let res = client.get(\"/two/qux\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/qux\",\n            \"request_uri\": \"/qux\",\n            \"original_uri\": \"/two/qux\",\n        })\n    );\n\n    let res = client.get(\"/three\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/three\",\n            \"request_uri\": \"/three\",\n            \"original_uri\": \"/three\",\n        })\n    );\n}\n\n#[crate::test]\nasync fn nesting_and_seeing_the_right_uri_ors_with_multi_segment_uris() {\n    let one = Router::new().nest(\n        \"/one\",\n        Router::new().nest(\"/foo\", Router::new().route(\"/bar\", get(all_the_uris))),\n    );\n    let two = Router::new().route(\"/two/foo\", get(all_the_uris));\n\n    let client = TestClient::new(one.merge(two));\n\n    let res = client.get(\"/one/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/bar\",\n            \"request_uri\": \"/bar\",\n            \"original_uri\": \"/one/foo/bar\",\n        })\n    );\n\n    let res = client.get(\"/two/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(\n        res.json::<Value>().await,\n        json!({\n            \"uri\": \"/two/foo\",\n            \"request_uri\": \"/two/foo\",\n            \"original_uri\": \"/two/foo\",\n        })\n    );\n}\n\n#[allow(deprecated)]\n#[crate::test]\nasync fn middleware_that_return_early() {\n    let private = Router::new()\n        .route(\"/\", get(|| async {}))\n        .layer(ValidateRequestHeaderLayer::bearer(\"password\"));\n\n    let public = Router::new().route(\"/public\", get(|| async {}));\n\n    let client = TestClient::new(private.merge(public));\n\n    assert_eq!(client.get(\"/\").await.status(), StatusCode::UNAUTHORIZED);\n    assert_eq!(\n        client\n            .get(\"/\")\n            .header(\"authorization\", \"Bearer password\")\n            .await\n            .status(),\n        StatusCode::OK\n    );\n    assert_eq!(\n        client.get(\"/doesnt-exist\").await.status(),\n        StatusCode::NOT_FOUND\n    );\n    assert_eq!(client.get(\"/public\").await.status(), StatusCode::OK);\n}\n"
  },
  {
    "path": "axum/src/routing/tests/mod.rs",
    "content": "use crate::{\n    body::{Body, Bytes},\n    error_handling::HandleErrorLayer,\n    extract::{self, DefaultBodyLimit, FromRef, Path, State},\n    handler::{Handler, HandlerWithoutStateExt},\n    middleware::{self, Next},\n    response::{IntoResponse, Response},\n    routing::{\n        delete, get, get_service, on, on_service, patch, patch_service,\n        path_router::path_for_nested_route, post, MethodFilter,\n    },\n    test_helpers::{\n        tracing_helpers::{capture_tracing, TracingEvent},\n        *,\n    },\n    BoxError, Extension, Json, Router, ServiceExt,\n};\nuse axum_core::extract::Request;\nuse counting_cloneable_state::CountingCloneableState;\nuse futures_util::stream::StreamExt;\nuse http::{\n    header::{ALLOW, CONTENT_LENGTH, HOST},\n    HeaderMap, Method, StatusCode, Uri,\n};\nuse http_body_util::BodyExt;\nuse serde::Deserialize;\nuse serde_json::json;\nuse std::{\n    convert::Infallible,\n    future::{ready, IntoFuture, Ready},\n    sync::atomic::{AtomicUsize, Ordering},\n    task::{Context, Poll},\n    time::Duration,\n};\nuse tower::{service_fn, util::MapResponseLayer, ServiceExt as TowerServiceExt};\nuse tower_http::{\n    limit::RequestBodyLimitLayer, timeout::TimeoutLayer,\n    validate_request::ValidateRequestHeaderLayer,\n};\nuse tower_service::Service;\n\nmod fallback;\nmod get_to_head;\nmod handle_error;\nmod merge;\nmod nest;\n\n#[cfg(all(feature = \"tokio\", debug_assertions))]\n#[test]\nfn take_route_or_internal_error_panics_on_second_call() {\n    let route = super::Route::new(service_fn(|_req: Request| async move {\n        Ok::<_, Infallible>(\"ok\")\n    }));\n\n    let mut service = Some(route);\n    let _ = super::take_route_or_internal_error(&mut service);\n\n    let panic = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n        let _ = super::take_route_or_internal_error(&mut service);\n    }))\n    .expect_err(\"take_route_or_internal_error should panic on the second call in debug mode\");\n\n    let panic_message = panic\n        .downcast_ref::<&str>()\n        .copied()\n        .or_else(|| panic.downcast_ref::<String>().map(String::as_str))\n        .unwrap_or(\"<non-string panic>\");\n\n    assert_eq!(panic_message, super::TAKE_ONCE_ROUTE_PANIC_MSG);\n}\n\n#[crate::test]\nasync fn hello_world() {\n    async fn root(_: Request) -> &'static str {\n        \"Hello, World!\"\n    }\n\n    async fn foo(_: Request) -> &'static str {\n        \"foo\"\n    }\n\n    async fn users_create(_: Request) -> &'static str {\n        \"users#create\"\n    }\n\n    let app = Router::new()\n        .route(\"/\", get(root).post(foo))\n        .route(\"/users\", post(users_create));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"Hello, World!\");\n\n    let res = client.post(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"foo\");\n\n    let res = client.post(\"/users\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"users#create\");\n}\n\n#[crate::test]\nasync fn routing() {\n    let app = Router::new()\n        .route(\n            \"/users\",\n            get(|_: Request| async { \"users#index\" }).post(|_: Request| async { \"users#create\" }),\n        )\n        .route(\"/users/{id}\", get(|_: Request| async { \"users#show\" }))\n        .route(\n            \"/users/{id}/action\",\n            get(|_: Request| async { \"users#action\" }),\n        );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n    let res = client.get(\"/users\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"users#index\");\n\n    let res = client.post(\"/users\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"users#create\");\n\n    let res = client.get(\"/users/1\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"users#show\");\n\n    let res = client.get(\"/users/1/action\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"users#action\");\n}\n\n#[crate::test]\nasync fn router_type_doesnt_change() {\n    let app: Router = Router::new()\n        .route(\n            \"/\",\n            on(MethodFilter::GET, |_: Request| async { \"hi from GET\" })\n                .on(MethodFilter::POST, |_: Request| async { \"hi from POST\" }),\n        )\n        .layer(tower_http::trace::TraceLayer::new_for_http());\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"hi from GET\");\n\n    let res = client.post(\"/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"hi from POST\");\n}\n\n#[crate::test]\nasync fn routing_between_services() {\n    use std::convert::Infallible;\n    use tower::service_fn;\n\n    async fn handle(_: Request) -> &'static str {\n        \"handler\"\n    }\n\n    let app = Router::new()\n        .route(\n            \"/one\",\n            get_service(service_fn(|_: Request| async {\n                Ok::<_, Infallible>(Response::new(Body::from(\"one get\")))\n            }))\n            .post_service(service_fn(|_: Request| async {\n                Ok::<_, Infallible>(Response::new(Body::from(\"one post\")))\n            }))\n            .on_service(\n                MethodFilter::PUT,\n                service_fn(|_: Request| async {\n                    Ok::<_, Infallible>(Response::new(Body::from(\"one put\")))\n                }),\n            ),\n        )\n        .route(\"/two\", on_service(MethodFilter::GET, handle.into_service()));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/one\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"one get\");\n\n    let res = client.post(\"/one\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"one post\");\n\n    let res = client.put(\"/one\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"one put\");\n\n    let res = client.get(\"/two\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"handler\");\n}\n\n#[crate::test]\nasync fn middleware_on_single_route() {\n    use tower_http::trace::TraceLayer;\n\n    async fn handle(_: Request) -> &'static str {\n        \"Hello, World!\"\n    }\n\n    let app = Router::new().route(\"/\", get(handle.layer(TraceLayer::new_for_http())));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n\n    assert_eq!(body, \"Hello, World!\");\n}\n\n#[crate::test]\nasync fn service_in_bottom() {\n    async fn handler(_req: Request) -> Result<Response<Body>, Infallible> {\n        Ok(Response::new(Body::empty()))\n    }\n\n    let app = Router::new().route(\"/\", get_service(service_fn(handler)));\n\n    TestClient::new(app);\n}\n\n#[crate::test]\nasync fn wrong_method_handler() {\n    let app = Router::new()\n        .route(\"/\", get(|| async {}).post(|| async {}))\n        .route(\"/foo\", patch(|| async {}));\n\n    let client = TestClient::new(app);\n\n    let res = client.patch(\"/\").await;\n    assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);\n    assert_eq!(res.headers()[ALLOW], \"GET,HEAD,POST\");\n\n    let res = client.patch(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.post(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);\n    assert_eq!(res.headers()[ALLOW], \"PATCH\");\n\n    let res = client.get(\"/bar\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n}\n\n#[crate::test]\nasync fn wrong_method_service() {\n    #[derive(Clone)]\n    struct Svc;\n\n    impl<R> Service<R> for Svc {\n        type Response = Response;\n        type Error = Infallible;\n        type Future = Ready<Result<Self::Response, Self::Error>>;\n\n        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n            Poll::Ready(Ok(()))\n        }\n\n        fn call(&mut self, _req: R) -> Self::Future {\n            ready(Ok(().into_response()))\n        }\n    }\n\n    let app = Router::new()\n        .route(\"/\", get_service(Svc).post_service(Svc))\n        .route(\"/foo\", patch_service(Svc));\n\n    let client = TestClient::new(app);\n\n    let res = client.patch(\"/\").await;\n    assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);\n    assert_eq!(res.headers()[ALLOW], \"GET,HEAD,POST\");\n\n    let res = client.patch(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.post(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);\n    assert_eq!(res.headers()[ALLOW], \"PATCH\");\n\n    let res = client.get(\"/bar\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n}\n\n#[crate::test]\nasync fn multiple_methods_for_one_handler() {\n    async fn root(_: Request) -> &'static str {\n        \"Hello, World!\"\n    }\n\n    let app = Router::new().route(\"/\", on(MethodFilter::GET.or(MethodFilter::POST), root));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.post(\"/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn wildcard_sees_whole_url() {\n    let app = Router::new().route(\n        \"/api/{*rest}\",\n        get(|uri: Uri| async move { uri.to_string() }),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/api/foo/bar\").await;\n    assert_eq!(res.text().await, \"/api/foo/bar\");\n}\n\n#[crate::test]\nasync fn middleware_applies_to_routes_above() {\n    let app = Router::new()\n        .route(\"/one\", get(std::future::pending::<()>))\n        .layer(TimeoutLayer::with_status_code(\n            StatusCode::REQUEST_TIMEOUT,\n            Duration::ZERO,\n        ))\n        .route(\"/two\", get(|| async {}));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/one\").await;\n    assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);\n\n    let res = client.get(\"/two\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn not_found_for_extra_trailing_slash() {\n    let app = Router::new().route(\"/foo\", get(|| async {}));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn not_found_for_missing_trailing_slash() {\n    let app = Router::new().route(\"/foo/\", get(|| async {}));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n}\n\n#[crate::test]\nasync fn with_and_without_trailing_slash() {\n    let app = Router::new()\n        .route(\"/foo\", get(|| async { \"without tsr\" }))\n        .route(\"/foo/\", get(|| async { \"with tsr\" }));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"with tsr\");\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"without tsr\");\n}\n\n// for https://github.com/tokio-rs/axum/issues/420\n#[crate::test]\nasync fn wildcard_doesnt_match_just_trailing_slash() {\n    let app = Router::new().route(\n        \"/x/{*path}\",\n        get(|Path(path): Path<String>| async move { path }),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/x\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n    let res = client.get(\"/x/\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n    let res = client.get(\"/x/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"foo/bar\");\n}\n\n#[crate::test]\nasync fn what_matches_wildcard() {\n    let app = Router::new()\n        .route(\"/{*key}\", get(|| async { \"root\" }))\n        .route(\"/x/{*key}\", get(|| async { \"x\" }))\n        .fallback(|| async { \"fallback\" });\n\n    let client = TestClient::new(app);\n\n    let get = |path| {\n        let f = client.get(path);\n        async move { f.await.text().await }\n    };\n\n    assert_eq!(get(\"/\").await, \"fallback\");\n    assert_eq!(get(\"/a\").await, \"root\");\n    assert_eq!(get(\"/a/\").await, \"root\");\n    assert_eq!(get(\"/a/b\").await, \"root\");\n    assert_eq!(get(\"/a/b/\").await, \"root\");\n\n    assert_eq!(get(\"/x\").await, \"root\");\n    assert_eq!(get(\"/x/\").await, \"root\");\n    assert_eq!(get(\"/x/a\").await, \"x\");\n    assert_eq!(get(\"/x/a/\").await, \"x\");\n    assert_eq!(get(\"/x/a/b\").await, \"x\");\n    assert_eq!(get(\"/x/a/b/\").await, \"x\");\n}\n\n#[should_panic(\n    expected = \"Invalid route \\\"/{*wild}\\\": Insertion failed due to conflict with previously registered route: /{*__private__axum_fallback}\"\n)]\n#[test]\nfn colliding_fallback_with_wildcard() {\n    _ = Router::<()>::new()\n        .fallback(|| async { \"fallback\" })\n        .route(\"/{*wild}\", get(|| async { \"wildcard\" }));\n}\n\n// We might want to reject this too\n#[crate::test]\nasync fn colliding_wildcard_with_fallback() {\n    let router = Router::new()\n        .route(\"/{*wild}\", get(|| async { \"wildcard\" }))\n        .fallback(|| async { \"fallback\" });\n\n    let client = TestClient::new(router);\n\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"fallback\");\n\n    let res = client.get(\"/x\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"wildcard\");\n}\n\n// We might want to reject this too\n#[crate::test]\nasync fn colliding_fallback_with_fallback() {\n    let router = Router::new()\n        .fallback(|| async { \"fallback1\" })\n        .fallback(|| async { \"fallback2\" });\n\n    let client = TestClient::new(router);\n\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"fallback1\");\n\n    let res = client.get(\"/x\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"fallback1\");\n}\n\n#[crate::test]\nasync fn colliding_root_with_fallback() {\n    let router = Router::new()\n        .route(\"/\", get(|| async { \"root\" }))\n        .fallback(|| async { \"fallback\" });\n\n    let client = TestClient::new(router);\n\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"root\");\n\n    let res = client.get(\"/x\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"fallback\");\n}\n\n#[crate::test]\nasync fn colliding_fallback_with_root() {\n    let router = Router::new()\n        .fallback(|| async { \"fallback\" })\n        .route(\"/\", get(|| async { \"root\" }));\n\n    let client = TestClient::new(router);\n\n    // This works because fallback registers `any` so the `get` gets merged into it.\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"root\");\n\n    let res = client.get(\"/x\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"fallback\");\n}\n\n#[crate::test]\nasync fn static_and_dynamic_paths() {\n    let app = Router::new()\n        .route(\n            \"/{key}\",\n            get(|Path(key): Path<String>| async move { format!(\"dynamic: {key}\") }),\n        )\n        .route(\"/foo\", get(|| async { \"static\" }));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/bar\").await;\n    assert_eq!(res.text().await, \"dynamic: bar\");\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.text().await, \"static\");\n}\n\n#[crate::test]\n#[should_panic(expected = \"Paths must start with a `/`. Use \\\"/\\\" for root routes\")]\nasync fn empty_route() {\n    let app = Router::new().route(\"\", get(|| async {}));\n    TestClient::new(app);\n}\n\n#[crate::test]\nasync fn middleware_still_run_for_unmatched_requests() {\n    #[derive(Clone)]\n    struct CountMiddleware<S>(S);\n\n    static COUNT: AtomicUsize = AtomicUsize::new(0);\n\n    impl<R, S> Service<R> for CountMiddleware<S>\n    where\n        S: Service<R>,\n    {\n        type Response = S::Response;\n        type Error = S::Error;\n        type Future = S::Future;\n\n        fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n            self.0.poll_ready(cx)\n        }\n\n        fn call(&mut self, req: R) -> Self::Future {\n            COUNT.fetch_add(1, Ordering::SeqCst);\n            self.0.call(req)\n        }\n    }\n\n    let app = Router::new()\n        .route(\"/\", get(|| async {}))\n        .layer(tower::layer::layer_fn(CountMiddleware));\n\n    let client = TestClient::new(app);\n\n    assert_eq!(COUNT.load(Ordering::SeqCst), 0);\n\n    client.get(\"/\").await;\n    assert_eq!(COUNT.load(Ordering::SeqCst), 1);\n\n    client.get(\"/not-found\").await;\n    assert_eq!(COUNT.load(Ordering::SeqCst), 2);\n}\n\n#[crate::test]\n#[should_panic(expected = \"\\\n    Invalid route: `Router::route_service` cannot be used with `Router`s. \\\n    Use `Router::nest` instead\\\n\")]\nasync fn routing_to_router_panics() {\n    TestClient::new(Router::new().route_service(\"/\", Router::new()));\n}\n\n#[allow(deprecated)]\n#[crate::test]\nasync fn route_layer() {\n    let app = Router::new()\n        .route(\"/foo\", get(|| async {}))\n        .route_layer(ValidateRequestHeaderLayer::bearer(\"password\"));\n\n    let client = TestClient::new(app);\n\n    let res = client\n        .get(\"/foo\")\n        .header(\"authorization\", \"Bearer password\")\n        .await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::UNAUTHORIZED);\n\n    let res = client.get(\"/not-found\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n    // it would be nice if this would return `405 Method Not Allowed`\n    // but that requires knowing more about which method route we're calling, which we\n    // don't know currently since it's just a generic `Service`\n    let res = client.post(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::UNAUTHORIZED);\n}\n\n#[crate::test]\nasync fn different_methods_added_in_different_routes() {\n    let app = Router::new()\n        .route(\"/\", get(|| async { \"GET\" }))\n        .route(\"/\", post(|| async { \"POST\" }));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"GET\");\n\n    let res = client.post(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"POST\");\n}\n\n#[crate::test]\n#[should_panic(expected = \"Cannot merge two `Router`s that both have a fallback\")]\nasync fn merging_routers_with_fallbacks_panics() {\n    async fn fallback() {}\n    let one = Router::new().fallback(fallback);\n    let two = Router::new().fallback(fallback);\n    TestClient::new(one.merge(two));\n}\n\n#[test]\n#[should_panic(expected = \"Overlapping method route. Handler for `GET /foo/bar` already exists\")]\nfn routes_with_overlapping_method_routes() {\n    async fn handler() {}\n    let _: Router = Router::new()\n        .route(\"/foo/bar\", get(handler))\n        .route(\"/foo/bar\", get(handler));\n}\n\n#[test]\n#[should_panic(expected = \"Overlapping method route. Handler for `GET /foo/bar` already exists\")]\nfn merging_with_overlapping_method_routes() {\n    async fn handler() {}\n    let app: Router = Router::new().route(\"/foo/bar\", get(handler));\n    _ = app.clone().merge(app);\n}\n\n#[crate::test]\nasync fn merging_routers_with_same_paths_but_different_methods() {\n    let one = Router::new().route(\"/\", get(|| async { \"GET\" }));\n    let two = Router::new().route(\"/\", post(|| async { \"POST\" }));\n\n    let client = TestClient::new(one.merge(two));\n\n    let res = client.get(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"GET\");\n\n    let res = client.post(\"/\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"POST\");\n}\n\n#[crate::test]\nasync fn head_content_length_through_hyper_server() {\n    let app = Router::new()\n        .route(\"/\", get(|| async { \"foo\" }))\n        .route(\"/json\", get(|| async { Json(json!({ \"foo\": 1 })) }));\n\n    let client = TestClient::new(app);\n\n    let res = client.head(\"/\").await;\n    assert_eq!(res.headers()[\"content-length\"], \"3\");\n    assert!(res.text().await.is_empty());\n\n    let res = client.head(\"/json\").await;\n    assert_eq!(res.headers()[\"content-length\"], \"9\");\n    assert!(res.text().await.is_empty());\n}\n\n#[crate::test]\nasync fn head_content_length_through_hyper_server_that_hits_fallback() {\n    let app = Router::new().fallback(|| async { \"foo\" });\n\n    let client = TestClient::new(app);\n\n    let res = client.head(\"/\").await;\n    assert_eq!(res.headers()[\"content-length\"], \"3\");\n}\n\n#[crate::test]\nasync fn head_with_middleware_applied() {\n    use tower_http::compression::{predicate::SizeAbove, CompressionLayer};\n\n    let app = Router::new()\n        .nest(\n            \"/foo\",\n            Router::new().route(\"/\", get(|| async { \"Hello, World!\" })),\n        )\n        .layer(CompressionLayer::new().compress_when(SizeAbove::new(0)));\n\n    let client = TestClient::new(app);\n\n    // send GET request\n    let res = client.get(\"/foo\").header(\"accept-encoding\", \"gzip\").await;\n    assert_eq!(res.headers()[\"transfer-encoding\"], \"chunked\");\n    // cannot have `transfer-encoding: chunked` and `content-length`\n    assert!(!res.headers().contains_key(\"content-length\"));\n\n    // send HEAD request\n    let res = client.head(\"/foo\").header(\"accept-encoding\", \"gzip\").await;\n    // no response body so no `transfer-encoding`\n    assert!(!res.headers().contains_key(\"transfer-encoding\"));\n    // no content-length since we cannot know it since the response\n    // is compressed\n    assert!(!res.headers().contains_key(\"content-length\"));\n}\n\n#[crate::test]\n#[should_panic(expected = \"Paths must start with a `/`\")]\nasync fn routes_must_start_with_slash() {\n    let app = Router::new().route(\":foo\", get(|| async {}));\n    TestClient::new(app);\n}\n\n#[crate::test]\nasync fn body_limited_by_default() {\n    let app = Router::new()\n        .route(\"/bytes\", post(|_: Bytes| async {}))\n        .route(\"/string\", post(|_: String| async {}))\n        .route(\"/json\", post(|_: Json<serde_json::Value>| async {}));\n\n    let client = TestClient::new(app);\n\n    for uri in [\"/bytes\", \"/string\", \"/json\"] {\n        println!(\"calling {uri}\");\n\n        let stream = futures_util::stream::repeat(\"a\".repeat(1000)).map(Ok::<_, hyper::Error>);\n        let body = reqwest::Body::wrap_stream(stream);\n\n        let res_future = client\n            .post(uri)\n            .header(\"content-type\", \"application/json\")\n            .body(body)\n            .into_future();\n        let res = tokio::time::timeout(Duration::from_secs(3), res_future)\n            .await\n            .expect(\"never got response\");\n\n        assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n    }\n}\n\n#[crate::test]\nasync fn disabling_the_default_limit() {\n    let app = Router::new()\n        .route(\"/\", post(|_: Bytes| async {}))\n        .layer(DefaultBodyLimit::disable());\n\n    let client = TestClient::new(app);\n\n    // `DEFAULT_LIMIT` is 2mb so make a body larger than that\n    let body = reqwest::Body::from(\"a\".repeat(3_000_000));\n\n    let res = client.post(\"/\").body(body).await;\n\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn limited_body_with_content_length() {\n    const LIMIT: usize = 3;\n\n    let app = Router::new()\n        .route(\n            \"/\",\n            post(|headers: HeaderMap, _body: Bytes| async move {\n                assert!(headers.get(CONTENT_LENGTH).is_some());\n            }),\n        )\n        .layer(RequestBodyLimitLayer::new(LIMIT));\n\n    let client = TestClient::new(app);\n\n    let res = client.post(\"/\").body(\"a\".repeat(LIMIT)).await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.post(\"/\").body(\"a\".repeat(LIMIT * 2)).await;\n    assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n}\n\n#[crate::test]\nasync fn changing_the_default_limit() {\n    let new_limit = 2;\n\n    let app = Router::new()\n        .route(\"/\", post(|_: Bytes| async {}))\n        .layer(DefaultBodyLimit::max(new_limit));\n\n    let client = TestClient::new(app);\n\n    let res = client\n        .post(\"/\")\n        .body(reqwest::Body::from(\"a\".repeat(new_limit)))\n        .await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client\n        .post(\"/\")\n        .body(reqwest::Body::from(\"a\".repeat(new_limit + 1)))\n        .await;\n    assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n}\n\n#[crate::test]\nasync fn changing_the_default_limit_differently_on_different_routes() {\n    let limit1 = 2;\n    let limit2 = 10;\n\n    let app = Router::new()\n        .route(\n            \"/limit1\",\n            post(|_: Bytes| async {}).layer(DefaultBodyLimit::max(limit1)),\n        )\n        .route(\n            \"/limit2\",\n            post(|_: Bytes| async {}).layer(DefaultBodyLimit::max(limit2)),\n        )\n        .route(\"/default\", post(|_: Bytes| async {}));\n\n    let client = TestClient::new(app);\n\n    let res = client\n        .post(\"/limit1\")\n        .body(reqwest::Body::from(\"a\".repeat(limit1)))\n        .await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client\n        .post(\"/limit1\")\n        .body(reqwest::Body::from(\"a\".repeat(limit2)))\n        .await;\n    assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n\n    let res = client\n        .post(\"/limit2\")\n        .body(reqwest::Body::from(\"a\".repeat(limit1)))\n        .await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client\n        .post(\"/limit2\")\n        .body(reqwest::Body::from(\"a\".repeat(limit2)))\n        .await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client\n        .post(\"/limit2\")\n        .body(reqwest::Body::from(\"a\".repeat(limit1 + limit2)))\n        .await;\n    assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n\n    let res = client\n        .post(\"/default\")\n        .body(reqwest::Body::from(\"a\".repeat(limit1 + limit2)))\n        .await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client\n        .post(\"/default\")\n        // `DEFAULT_LIMIT` is 2mb so make a body larger than that\n        .body(reqwest::Body::from(\"a\".repeat(3_000_000)))\n        .await;\n    assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n}\n\n#[crate::test]\nasync fn limited_body_with_streaming_body() {\n    const LIMIT: usize = 3;\n\n    let app = Router::new()\n        .route(\n            \"/\",\n            post(|headers: HeaderMap, _body: Bytes| async move {\n                assert!(headers.get(CONTENT_LENGTH).is_none());\n            }),\n        )\n        .layer(RequestBodyLimitLayer::new(LIMIT));\n\n    let client = TestClient::new(app);\n\n    let stream = futures_util::stream::iter(vec![Ok::<_, hyper::Error>(\"a\".repeat(LIMIT))]);\n    let res = client\n        .post(\"/\")\n        .body(reqwest::Body::wrap_stream(stream))\n        .await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let stream = futures_util::stream::iter(vec![Ok::<_, hyper::Error>(\"a\".repeat(LIMIT * 2))]);\n    let res = client\n        .post(\"/\")\n        .body(reqwest::Body::wrap_stream(stream))\n        .await;\n    assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n}\n\n#[crate::test]\nasync fn extract_state() {\n    #[derive(Clone)]\n    struct AppState {\n        value: i32,\n        inner: InnerState,\n    }\n\n    #[derive(Clone)]\n    struct InnerState {\n        value: i32,\n    }\n\n    impl FromRef<AppState> for InnerState {\n        fn from_ref(state: &AppState) -> Self {\n            state.inner.clone()\n        }\n    }\n\n    async fn handler(State(outer): State<AppState>, State(inner): State<InnerState>) {\n        assert_eq!(outer.value, 1);\n        assert_eq!(inner.value, 2);\n    }\n\n    let state = AppState {\n        value: 1,\n        inner: InnerState { value: 2 },\n    };\n\n    let app = Router::new().route(\"/\", get(handler)).with_state(state);\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn explicitly_set_state() {\n    let app = Router::new()\n        .route_service(\n            \"/\",\n            get(|State(state): State<&'static str>| async move { state }).with_state(\"foo\"),\n        )\n        .with_state(\"...\");\n\n    let client = TestClient::new(app);\n    let res = client.get(\"/\").await;\n    assert_eq!(res.text().await, \"foo\");\n}\n\n#[crate::test]\nasync fn layer_response_into_response() {\n    fn map_response<B>(_res: Response<B>) -> Result<Response<B>, impl IntoResponse> {\n        let headers = [(\"x-foo\", \"bar\")];\n        let status = StatusCode::IM_A_TEAPOT;\n        Err((headers, status))\n    }\n\n    let app = Router::new()\n        .route(\"/\", get(|| async {}))\n        .layer(MapResponseLayer::new(map_response));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.headers()[\"x-foo\"], \"bar\");\n    assert_eq!(res.status(), StatusCode::IM_A_TEAPOT);\n}\n\n#[allow(dead_code)]\nfn method_router_fallback_with_state() {\n    async fn fallback(_: State<&'static str>) {}\n\n    async fn not_found(_: State<&'static str>) {}\n\n    let state = \"foo\";\n\n    let _: Router = Router::new()\n        .fallback(get(fallback).fallback(not_found))\n        .with_state(state);\n}\n\n#[test]\nfn test_path_for_nested_route() {\n    assert_eq!(path_for_nested_route(\"/\", \"/\"), \"/\");\n\n    assert_eq!(path_for_nested_route(\"/a\", \"/\"), \"/a\");\n    assert_eq!(path_for_nested_route(\"/\", \"/b\"), \"/b\");\n    assert_eq!(path_for_nested_route(\"/a/\", \"/\"), \"/a/\");\n    assert_eq!(path_for_nested_route(\"/\", \"/b/\"), \"/b/\");\n\n    assert_eq!(path_for_nested_route(\"/a\", \"/b\"), \"/a/b\");\n    assert_eq!(path_for_nested_route(\"/a/\", \"/b\"), \"/a/b\");\n    assert_eq!(path_for_nested_route(\"/a\", \"/b/\"), \"/a/b/\");\n    assert_eq!(path_for_nested_route(\"/a/\", \"/b/\"), \"/a/b/\");\n}\n\n#[crate::test]\nasync fn state_isnt_cloned_too_much() {\n    let state = CountingCloneableState::new();\n\n    let app = Router::new()\n        .route(\"/\", get(|_: State<CountingCloneableState>| async {}))\n        .with_state(state.clone());\n\n    let client = TestClient::new(app);\n\n    // ignore clones made during setup\n    state.setup_done();\n\n    client.get(\"/\").await;\n\n    assert_eq!(state.count(), 3);\n}\n\n#[crate::test]\nasync fn state_isnt_cloned_too_much_in_layer() {\n    async fn layer(State(_): State<CountingCloneableState>, req: Request, next: Next) -> Response {\n        next.run(req).await\n    }\n\n    let state = CountingCloneableState::new();\n\n    let app = Router::new().layer(middleware::from_fn_with_state(state.clone(), layer));\n\n    let client = TestClient::new(app);\n\n    // ignore clones made during setup\n    state.setup_done();\n\n    client.get(\"/\").await;\n\n    assert_eq!(state.count(), 3);\n}\n\n#[crate::test]\nasync fn logging_rejections() {\n    #[derive(Deserialize, Eq, PartialEq, Debug)]\n    #[serde(deny_unknown_fields)]\n    struct RejectionEvent {\n        message: String,\n        status: u16,\n        body: String,\n        rejection_type: String,\n    }\n\n    let events = capture_tracing::<RejectionEvent, _>(|| async {\n        let app = Router::new()\n            .route(\"/extension\", get(|_: Extension<Infallible>| async {}))\n            .route(\"/string\", post(|_: String| async {}));\n\n        let client = TestClient::new(app);\n\n        assert_eq!(\n            client.get(\"/extension\").await.status(),\n            StatusCode::INTERNAL_SERVER_ERROR\n        );\n\n        assert_eq!(\n            client\n                .post(\"/string\")\n                .body(Vec::from([0, 159, 146, 150]))\n                .await\n                .status(),\n            StatusCode::BAD_REQUEST,\n        );\n    })\n    .with_filter(\"axum::rejection=trace\")\n    .await;\n\n    assert_eq!(\n        events,\n        Vec::from([\n            TracingEvent {\n                fields: RejectionEvent {\n                    message: \"rejecting request\".to_owned(),\n                    status: 500,\n                    body: \"Missing request extension: Extension of \\\n                        type `core::convert::Infallible` was not found. \\\n                        Perhaps you forgot to add it? See `axum::Extension`.\"\n                        .to_owned(),\n                    rejection_type: \"axum::extract::rejection::MissingExtension\".to_owned(),\n                },\n                target: \"axum::rejection\".to_owned(),\n                level: \"TRACE\".to_owned(),\n            },\n            TracingEvent {\n                fields: RejectionEvent {\n                    message: \"rejecting request\".to_owned(),\n                    status: 400,\n                    body: \"Request body didn't contain valid UTF-8: \\\n                        invalid utf-8 sequence of 1 bytes from index 1\"\n                        .to_owned(),\n                    rejection_type: \"axum_core::extract::rejection::InvalidUtf8\".to_owned(),\n                },\n                target: \"axum::rejection\".to_owned(),\n                level: \"TRACE\".to_owned(),\n            },\n        ])\n    )\n}\n\n// https://github.com/tokio-rs/axum/issues/1955\n#[crate::test]\nasync fn connect_going_to_custom_fallback() {\n    let app = Router::new().fallback(|| async { (StatusCode::NOT_FOUND, \"custom fallback\") });\n\n    let req = Request::builder()\n        .uri(\"example.com:443\")\n        .method(Method::CONNECT)\n        .header(HOST, \"example.com:443\")\n        .body(Body::empty())\n        .unwrap();\n\n    let res = app.oneshot(req).await.unwrap();\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    let text = String::from_utf8(res.collect().await.unwrap().to_bytes().to_vec()).unwrap();\n    assert_eq!(text, \"custom fallback\");\n}\n\n// https://github.com/tokio-rs/axum/issues/1955\n#[crate::test]\nasync fn connect_going_to_default_fallback() {\n    let app = Router::new();\n\n    let req = Request::builder()\n        .uri(\"example.com:443\")\n        .method(Method::CONNECT)\n        .header(HOST, \"example.com:443\")\n        .body(Body::empty())\n        .unwrap();\n\n    let res = app.oneshot(req).await.unwrap();\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n    let body = res.collect().await.unwrap().to_bytes();\n    assert!(body.is_empty());\n}\n\n#[crate::test]\nasync fn impl_handler_for_into_response() {\n    let app = Router::new().route(\"/things\", post((StatusCode::CREATED, \"thing created\")));\n\n    let client = TestClient::new(app);\n\n    let res = client.post(\"/things\").await;\n    assert_eq!(res.status(), StatusCode::CREATED);\n    assert_eq!(res.text().await, \"thing created\");\n}\n\n#[crate::test]\n#[should_panic(\n    expected = \"Path segments must not start with `:`. For capture groups, use `{capture}`. If you meant to literally match a segment starting with a colon, call `without_v07_checks` on the router.\"\n)]\nasync fn colon_in_route() {\n    _ = Router::<()>::new().route(\"/:foo\", get(|| async move {}));\n}\n\n#[crate::test]\n#[should_panic(\n    expected = \"Path segments must not start with `*`. For wildcard capture, use `{*wildcard}`. If you meant to literally match a segment starting with an asterisk, call `without_v07_checks` on the router.\"\n)]\nasync fn asterisk_in_route() {\n    _ = Router::<()>::new().route(\"/*foo\", get(|| async move {}));\n}\n\n#[crate::test]\nasync fn middleware_adding_body() {\n    let app = Router::new()\n        .route(\"/\", get(()))\n        .layer(MapResponseLayer::new(|mut res: Response| -> Response {\n            // If there is a content-length header, its value will be zero and axum will avoid\n            // overwriting it. But this means our content-length doesn’t match the length of the\n            // body, which leads to panics in Hyper. Thus we have to ensure that axum doesn’t add\n            // on content-length headers until after middleware has been run.\n            assert!(!res.headers().contains_key(\"content-length\"));\n            *res.body_mut() = \"…\".into();\n            res\n        }));\n\n    let client = TestClient::new(app);\n    let res = client.get(\"/\").await;\n\n    let headers = res.headers();\n    let header = headers.get(\"content-length\");\n    assert!(header.is_some());\n    assert_eq!(header.unwrap().to_str().unwrap(), \"3\");\n\n    assert_eq!(res.text().await, \"…\");\n}\n"
  },
  {
    "path": "axum/src/routing/tests/nest.rs",
    "content": "use super::*;\nuse std::collections::HashMap;\nuse tower_http::services::ServeDir;\n\n#[crate::test]\nasync fn nesting_apps() {\n    let api_routes = Router::new()\n        .route(\n            \"/users\",\n            get(|| async { \"users#index\" }).post(|| async { \"users#create\" }),\n        )\n        .route(\n            \"/users/{id}\",\n            get(\n                |params: extract::Path<HashMap<String, String>>| async move {\n                    format!(\n                        \"{}: users#show ({})\",\n                        params.get(\"version\").unwrap(),\n                        params.get(\"id\").unwrap()\n                    )\n                },\n            ),\n        )\n        .route(\n            \"/games/{id}\",\n            get(\n                |params: extract::Path<HashMap<String, String>>| async move {\n                    format!(\n                        \"{}: games#show ({})\",\n                        params.get(\"version\").unwrap(),\n                        params.get(\"id\").unwrap()\n                    )\n                },\n            ),\n        );\n\n    let app = Router::new()\n        .route(\"/\", get(|| async { \"hi\" }))\n        .nest(\"/{version}/api\", api_routes);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"hi\");\n\n    let res = client.get(\"/v0/api/users\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"users#index\");\n\n    let res = client.get(\"/v0/api/users/123\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"v0: users#show (123)\");\n\n    let res = client.get(\"/v0/api/games/123\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"v0: games#show (123)\");\n}\n\n#[crate::test]\nasync fn wrong_method_nest() {\n    let nested_app = Router::new().route(\"/\", get(|| async {}));\n    let app = Router::new().nest(\"/foo\", nested_app);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.post(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);\n    assert_eq!(res.headers()[ALLOW], \"GET,HEAD\");\n\n    let res = client.patch(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n}\n\n#[test]\n#[should_panic(expected = \"Nesting at the root is no longer supported. Use merge instead.\")]\nfn nest_router_at_root() {\n    let nested = Router::new().route(\"/foo\", get(|| async {}));\n    let _: Router = Router::new().nest(\"/\", nested);\n}\n\n#[test]\n#[should_panic(expected = \"Nesting at the root is no longer supported. Use merge instead.\")]\nfn nest_router_at_empty_path() {\n    let nested = Router::new().route(\"/foo\", get(|| async {}));\n    let _: Router = Router::new().nest(\"\", nested);\n}\n\n#[test]\n#[should_panic(\n    expected = \"Nesting at the root is no longer supported. Use fallback_service instead.\"\n)]\nfn nest_service_at_root() {\n    let _: Router = Router::new().nest_service(\"/\", get(|| async {}));\n}\n\n#[test]\n#[should_panic(\n    expected = \"Nesting at the root is no longer supported. Use fallback_service instead.\"\n)]\nfn nest_service_at_empty_path() {\n    let _: Router = Router::new().nest_service(\"\", get(|| async {}));\n}\n\n#[test]\n#[should_panic(expected = \"Nesting paths must start with a `/`.\")]\nfn nest_no_slash() {\n    let _: Router = Router::new().nest(\"x\", Router::new());\n}\n\n#[test]\n#[should_panic(expected = \"Nesting paths must start with a `/`.\")]\nfn nest_service_no_slash() {\n    let _: Router = Router::new().nest_service(\"x\", get(|| async {}));\n}\n\n#[crate::test]\nasync fn nested_url_extractor() {\n    let app = Router::new().nest(\n        \"/foo\",\n        Router::new().nest(\n            \"/bar\",\n            Router::new()\n                .route(\"/baz\", get(|uri: Uri| async move { uri.to_string() }))\n                .route(\n                    \"/qux\",\n                    get(|req: Request| async move { req.uri().to_string() }),\n                ),\n        ),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"/baz\");\n\n    let res = client.get(\"/foo/bar/qux\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"/qux\");\n}\n\n#[crate::test]\nasync fn nested_url_original_extractor() {\n    let app = Router::new().nest(\n        \"/foo\",\n        Router::new().nest(\n            \"/bar\",\n            Router::new().route(\n                \"/baz\",\n                get(|uri: extract::OriginalUri| async move { uri.0.to_string() }),\n            ),\n        ),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"/foo/bar/baz\");\n}\n\n#[crate::test]\nasync fn nested_service_sees_stripped_uri() {\n    let app = Router::new().nest(\n        \"/foo\",\n        Router::new().nest(\n            \"/bar\",\n            Router::new().route_service(\n                \"/baz\",\n                service_fn(|req: Request| async move {\n                    let body = Body::from(req.uri().to_string());\n                    Ok::<_, Infallible>(Response::new(body))\n                }),\n            ),\n        ),\n    );\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar/baz\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"/baz\");\n}\n\n#[crate::test]\nasync fn nest_static_file_server() {\n    let app = Router::new().nest_service(\"/static\", ServeDir::new(\".\"));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/static/README.md\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[crate::test]\nasync fn nested_multiple_routes() {\n    let app = Router::new()\n        .nest(\n            \"/api\",\n            Router::new()\n                .route(\"/users\", get(|| async { \"users\" }))\n                .route(\"/teams\", get(|| async { \"teams\" })),\n        )\n        .route(\"/\", get(|| async { \"root\" }));\n\n    let client = TestClient::new(app);\n\n    assert_eq!(client.get(\"/\").await.text().await, \"root\");\n    assert_eq!(client.get(\"/api/users\").await.text().await, \"users\");\n    assert_eq!(client.get(\"/api/teams\").await.text().await, \"teams\");\n}\n\n#[crate::test]\nasync fn multiple_top_level_nests() {\n    let app = Router::new()\n        .nest(\n            \"/one\",\n            Router::new().route(\"/route\", get(|| async { \"one\" })),\n        )\n        .nest(\n            \"/two\",\n            Router::new().route(\"/route\", get(|| async { \"two\" })),\n        );\n\n    let client = TestClient::new(app);\n\n    assert_eq!(client.get(\"/one/route\").await.text().await, \"one\");\n    assert_eq!(client.get(\"/two/route\").await.text().await, \"two\");\n}\n\n#[crate::test]\n#[should_panic(expected = \"Invalid route: nested routes cannot contain wildcards (*)\")]\nasync fn nest_cannot_contain_wildcards() {\n    _ = Router::<()>::new().nest(\"/one/{*rest}\", Router::new());\n}\n\n#[crate::test]\nasync fn outer_middleware_still_see_whole_url() {\n    #[derive(Clone)]\n    struct SetUriExtension<S>(S);\n\n    #[derive(Clone)]\n    struct Uri(http::Uri);\n\n    impl<S, B> Service<Request<B>> for SetUriExtension<S>\n    where\n        S: Service<Request<B>>,\n    {\n        type Response = S::Response;\n        type Error = S::Error;\n        type Future = S::Future;\n\n        fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n            self.0.poll_ready(cx)\n        }\n\n        fn call(&mut self, mut req: Request<B>) -> Self::Future {\n            let uri = Uri(req.uri().clone());\n            req.extensions_mut().insert(uri);\n            self.0.call(req)\n        }\n    }\n\n    async fn handler(Extension(Uri(middleware_uri)): Extension<Uri>) -> impl IntoResponse {\n        middleware_uri.to_string()\n    }\n\n    let app = Router::new()\n        .route(\"/\", get(handler))\n        .route(\"/foo\", get(handler))\n        .route(\"/foo/bar\", get(handler))\n        .nest(\"/one\", Router::new().route(\"/two\", get(handler)))\n        .fallback(handler)\n        .layer(tower::layer::layer_fn(SetUriExtension));\n\n    let client = TestClient::new(app);\n\n    assert_eq!(client.get(\"/\").await.text().await, \"/\");\n    assert_eq!(client.get(\"/foo\").await.text().await, \"/foo\");\n    assert_eq!(client.get(\"/foo/bar\").await.text().await, \"/foo/bar\");\n    assert_eq!(client.get(\"/not-found\").await.text().await, \"/not-found\");\n    assert_eq!(client.get(\"/one/two\").await.text().await, \"/one/two\");\n}\n\n#[crate::test]\nasync fn nest_at_capture() {\n    let api_routes = Router::new().route(\n        \"/{b}\",\n        get(|Path((a, b)): Path<(String, String)>| async move { format!(\"a={a} b={b}\") }),\n    );\n\n    let app = Router::new().nest(\"/{a}\", api_routes);\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n    assert_eq!(res.text().await, \"a=foo b=bar\");\n}\n\n#[crate::test]\nasync fn nest_with_and_without_trailing() {\n    let app = Router::new().nest_service(\"/foo\", get(|| async {}));\n\n    let client = TestClient::new(app);\n\n    let res = client.get(\"/foo\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/foo/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/foo/bar\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\n#[tokio::test]\nasync fn nesting_with_root_inner_router() {\n    let app = Router::new()\n        .nest_service(\"/service\", Router::new().route(\"/\", get(|| async {})))\n        .nest(\"/router\", Router::new().route(\"/\", get(|| async {})))\n        .nest(\"/router-slash/\", Router::new().route(\"/\", get(|| async {})));\n\n    let client = TestClient::new(app);\n\n    // `/service/` does match the `/service` prefix and the remaining path is technically\n    // empty, which is the same as `/` which matches `.route(\"/\", _)`\n    let res = client.get(\"/service\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    // `/service/` does match the `/service` prefix and the remaining path is `/`\n    // which matches `.route(\"/\", _)`\n    //\n    // this is perhaps a little surprising but don't think there is much we can do\n    let res = client.get(\"/service/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    // at least it does work like you'd expect when using `nest`\n\n    let res = client.get(\"/router\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n\n    let res = client.get(\"/router/\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n    let res = client.get(\"/router-slash\").await;\n    assert_eq!(res.status(), StatusCode::NOT_FOUND);\n\n    let res = client.get(\"/router-slash/\").await;\n    assert_eq!(res.status(), StatusCode::OK);\n}\n\nmacro_rules! nested_route_test {\n    (\n        $name:ident,\n        // the path we nest the inner router at\n        nest = $nested_path:literal,\n        // the route the inner router accepts\n        route = $route_path:literal,\n        // the route we expect to be able to call\n        expected = $expected_path:literal $(,)?\n    ) => {\n        #[crate::test]\n        async fn $name() {\n            let inner = Router::new().route($route_path, get(|| async {}));\n            let app = Router::new().nest($nested_path, inner);\n            let client = TestClient::new(app);\n            let res = client.get($expected_path).await;\n            let status = res.status();\n            assert_eq!(status, StatusCode::OK, \"Router\");\n        }\n    };\n}\n\n// test cases taken from https://github.com/tokio-rs/axum/issues/714#issuecomment-1058144460\nnested_route_test!(nest_1, nest = \"/a\", route = \"/\", expected = \"/a\");\nnested_route_test!(nest_2, nest = \"/a\", route = \"/a\", expected = \"/a/a\");\nnested_route_test!(nest_3, nest = \"/a\", route = \"/a/\", expected = \"/a/a/\");\nnested_route_test!(nest_4, nest = \"/a/\", route = \"/\", expected = \"/a/\");\nnested_route_test!(nest_5, nest = \"/a/\", route = \"/a\", expected = \"/a/a\");\nnested_route_test!(nest_6, nest = \"/a/\", route = \"/a/\", expected = \"/a/a/\");\n\n#[crate::test]\n#[should_panic(\n    expected = \"Path segments must not start with `:`. For capture groups, use `{capture}`. If you meant to literally match a segment starting with a colon, call `without_v07_checks` on the router.\"\n)]\nasync fn colon_in_route() {\n    _ = Router::<()>::new().nest(\"/:foo\", Router::new());\n}\n\n#[crate::test]\n#[should_panic(\n    expected = \"Path segments must not start with `*`. For wildcard capture, use `{*wildcard}`. If you meant to literally match a segment starting with an asterisk, call `without_v07_checks` on the router.\"\n)]\nasync fn asterisk_in_route() {\n    _ = Router::<()>::new().nest(\"/*foo\", Router::new());\n}\n\n#[crate::test]\nasync fn nesting_router_with_fallback() {\n    let nested = Router::new().fallback(|| async { \"nested\" });\n    let router = Router::new().route(\"/{x}/{y}\", get(|| async { \"two segments\" }));\n\n    let client = TestClient::new(router.nest(\"/nest\", nested));\n\n    let res = client.get(\"/a/b\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"two segments\");\n\n    let res = client.get(\"/nest/b\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"nested\");\n}\n\n#[crate::test]\nasync fn defining_missing_routes_in_nested_router() {\n    let router = Router::new()\n        .route(\"/nest/before\", get(|| async { \"before\" }))\n        .nest(\n            \"/nest\",\n            Router::new()\n                .route(\"/mid\", get(|| async { \"nested mid\" }))\n                .fallback(|| async { \"nested fallback\" }),\n        )\n        .route(\"/nest/after\", get(|| async { \"after\" }));\n\n    let client = TestClient::new(router);\n\n    let res = client.get(\"/nest/before\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"before\");\n\n    let res = client.get(\"/nest/after\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"after\");\n\n    let res = client.get(\"/nest/mid\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"nested mid\");\n\n    let res = client.get(\"/nest/fallback\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"nested fallback\");\n}\n\n#[test]\n#[should_panic(\n    expected = \"Overlapping method route. Handler for `GET /nest/override` already exists\"\n)]\nfn overriding_by_nested_router() {\n    _ = Router::<()>::new()\n        .route(\"/nest/override\", get(|| async { \"outer\" }))\n        .nest(\n            \"/nest\",\n            Router::new().route(\"/override\", get(|| async { \"inner\" })),\n        );\n}\n\n#[test]\n#[should_panic(\n    expected = \"Overlapping method route. Handler for `GET /nest/override` already exists\"\n)]\nfn overriding_nested_router_() {\n    _ = Router::<()>::new()\n        .nest(\n            \"/nest\",\n            Router::new().route(\"/override\", get(|| async { \"inner\" })),\n        )\n        .route(\"/nest/override\", get(|| async { \"outer\" }));\n}\n\n// This is just documenting current state, not intended behavior.\n#[crate::test]\nasync fn overriding_nested_service_router() {\n    let router = Router::new()\n        .route(\"/nest/before\", get(|| async { \"outer\" }))\n        .nest_service(\n            \"/nest\",\n            Router::new()\n                .route(\"/before\", get(|| async { \"inner\" }))\n                .route(\"/after\", get(|| async { \"inner\" })),\n        )\n        .route(\"/nest/after\", get(|| async { \"outer\" }));\n\n    let client = TestClient::new(router);\n\n    let res = client.get(\"/nest/before\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"outer\");\n\n    let res = client.get(\"/nest/after\").await;\n    let body = res.text().await;\n    assert_eq!(body, \"outer\");\n}\n"
  },
  {
    "path": "axum/src/routing/url_params.rs",
    "content": "use crate::util::PercentDecodedStr;\nuse http::Extensions;\nuse matchit::Params;\nuse std::sync::Arc;\n\n#[derive(Clone)]\npub(crate) enum UrlParams {\n    Params(Vec<(Arc<str>, PercentDecodedStr)>),\n    InvalidUtf8InPathParam { key: Arc<str> },\n}\n\npub(super) fn insert_url_params(extensions: &mut Extensions, params: &Params<'_, '_>) {\n    let current_params = extensions.get_mut();\n\n    if let Some(UrlParams::InvalidUtf8InPathParam { .. }) = current_params {\n        // nothing to do here since an error was stored earlier\n        return;\n    }\n\n    let params = params\n        .iter()\n        .filter(|(key, _)| !key.starts_with(super::NEST_TAIL_PARAM))\n        .filter(|(key, _)| !key.starts_with(super::FALLBACK_PARAM))\n        .map(|(k, v)| {\n            if let Some(decoded) = PercentDecodedStr::new(v) {\n                Ok((Arc::from(k), decoded))\n            } else {\n                Err(Arc::from(k))\n            }\n        })\n        .collect::<Result<Vec<_>, _>>();\n\n    match (current_params, params) {\n        (Some(UrlParams::InvalidUtf8InPathParam { .. }), _) => {\n            unreachable!(\"we check for this state earlier in this method\")\n        }\n        (_, Err(invalid_key)) => {\n            extensions.insert(UrlParams::InvalidUtf8InPathParam { key: invalid_key });\n        }\n        (Some(UrlParams::Params(current)), Ok(params)) => {\n            current.extend(params);\n        }\n        (None, Ok(params)) => {\n            extensions.insert(UrlParams::Params(params));\n        }\n    }\n}\n"
  },
  {
    "path": "axum/src/serve/listener.rs",
    "content": "use std::{\n    fmt,\n    future::Future,\n    pin::Pin,\n    sync::Arc,\n    task::{Context, Poll},\n    time::Duration,\n};\n\nuse pin_project_lite::pin_project;\nuse tokio::{\n    io::{self, AsyncRead, AsyncWrite},\n    net::{TcpListener, TcpStream},\n    sync::{OwnedSemaphorePermit, Semaphore},\n};\n\n/// Types that can listen for connections.\npub trait Listener: Send + 'static {\n    /// The listener's IO type.\n    type Io: AsyncRead + AsyncWrite + Unpin + Send + 'static;\n\n    /// The listener's address type.\n    type Addr: Send;\n\n    /// Accept a new incoming connection to this listener.\n    ///\n    /// If the underlying accept call can return an error, this function must\n    /// take care of logging and retrying.\n    fn accept(&mut self) -> impl Future<Output = (Self::Io, Self::Addr)> + Send;\n\n    /// Returns the local address that this listener is bound to.\n    fn local_addr(&self) -> io::Result<Self::Addr>;\n}\n\nimpl Listener for TcpListener {\n    type Io = TcpStream;\n    type Addr = std::net::SocketAddr;\n\n    async fn accept(&mut self) -> (Self::Io, Self::Addr) {\n        loop {\n            match Self::accept(self).await {\n                Ok(tup) => return tup,\n                Err(e) => handle_accept_error(e).await,\n            }\n        }\n    }\n\n    #[inline]\n    fn local_addr(&self) -> io::Result<Self::Addr> {\n        Self::local_addr(self)\n    }\n}\n\n#[cfg(unix)]\nimpl Listener for tokio::net::UnixListener {\n    type Io = tokio::net::UnixStream;\n    type Addr = tokio::net::unix::SocketAddr;\n\n    async fn accept(&mut self) -> (Self::Io, Self::Addr) {\n        loop {\n            match Self::accept(self).await {\n                Ok(tup) => return tup,\n                Err(e) => handle_accept_error(e).await,\n            }\n        }\n    }\n\n    #[inline]\n    fn local_addr(&self) -> io::Result<Self::Addr> {\n        Self::local_addr(self)\n    }\n}\n\n/// Extensions to [`Listener`].\npub trait ListenerExt: Listener + Sized {\n    /// Limit the number of concurrent connections. Once the limit has\n    /// been reached, no additional connections will be accepted until\n    /// an existing connection is closed. Listener implementations will\n    /// typically continue to queue incoming connections, up to an OS\n    /// and implementation-specific listener backlog limit.\n    ///\n    /// Compare [`tower::limit::concurrency`], which provides ways to\n    /// limit concurrent in-flight requests, but does not limit connections\n    /// that are idle or in the process of sending request headers.\n    ///\n    /// [`tower::limit::concurrency`]: https://docs.rs/tower/latest/tower/limit/concurrency/\n    fn limit_connections(self, limit: usize) -> ConnLimiter<Self> {\n        ConnLimiter {\n            listener: self,\n            sem: Arc::new(Semaphore::new(limit)),\n        }\n    }\n\n    /// Run a mutable closure on every accepted `Io`.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{Router, routing::get, serve::ListenerExt};\n    /// use tracing::trace;\n    ///\n    /// # async {\n    /// let router = Router::new().route(\"/\", get(|| async { \"Hello, World!\" }));\n    ///\n    /// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\")\n    ///     .await\n    ///     .unwrap()\n    ///     .tap_io(|tcp_stream| {\n    ///         if let Err(err) = tcp_stream.set_nodelay(true) {\n    ///             trace!(\"failed to set TCP_NODELAY on incoming connection: {err:#}\");\n    ///         }\n    ///     });\n    /// axum::serve(listener, router).await;\n    /// # };\n    /// ```\n    fn tap_io<F>(self, tap_fn: F) -> TapIo<Self, F>\n    where\n        F: FnMut(&mut Self::Io) + Send + 'static,\n    {\n        TapIo {\n            listener: self,\n            tap_fn,\n        }\n    }\n}\n\nimpl<L: Listener> ListenerExt for L {}\n\n/// Return type of [`ListenerExt::limit_connections`].\n///\n/// See that method for details.\n#[derive(Debug)]\npub struct ConnLimiter<T> {\n    listener: T,\n    sem: Arc<Semaphore>,\n}\n\nimpl<T: Listener> Listener for ConnLimiter<T> {\n    type Io = ConnLimiterIo<T::Io>;\n    type Addr = T::Addr;\n\n    async fn accept(&mut self) -> (Self::Io, Self::Addr) {\n        let permit = self.sem.clone().acquire_owned().await.unwrap();\n        let (io, addr) = self.listener.accept().await;\n        (ConnLimiterIo { io, permit }, addr)\n    }\n\n    fn local_addr(&self) -> tokio::io::Result<Self::Addr> {\n        self.listener.local_addr()\n    }\n}\n\npin_project! {\n    /// A connection counted by [`ConnLimiter`].\n    ///\n    /// See [`ListenerExt::limit_connections`] for details.\n    #[derive(Debug)]\n    pub struct ConnLimiterIo<T> {\n        #[pin]\n        io: T,\n        permit: OwnedSemaphorePermit,\n    }\n}\n\n// Simply forward implementation to `io` field.\nimpl<T: AsyncRead> AsyncRead for ConnLimiterIo<T> {\n    fn poll_read(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        buf: &mut io::ReadBuf<'_>,\n    ) -> Poll<io::Result<()>> {\n        self.project().io.poll_read(cx, buf)\n    }\n}\n\n// Simply forward implementation to `io` field.\nimpl<T: AsyncWrite> AsyncWrite for ConnLimiterIo<T> {\n    fn is_write_vectored(&self) -> bool {\n        self.io.is_write_vectored()\n    }\n\n    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.project().io.poll_flush(cx)\n    }\n\n    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        self.project().io.poll_shutdown(cx)\n    }\n\n    fn poll_write(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        buf: &[u8],\n    ) -> Poll<io::Result<usize>> {\n        self.project().io.poll_write(cx, buf)\n    }\n\n    fn poll_write_vectored(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n        bufs: &[std::io::IoSlice<'_>],\n    ) -> Poll<io::Result<usize>> {\n        self.project().io.poll_write_vectored(cx, bufs)\n    }\n}\n\n/// Return type of [`ListenerExt::tap_io`].\n///\n/// See that method for details.\npub struct TapIo<L, F> {\n    listener: L,\n    tap_fn: F,\n}\n\nimpl<L, F> fmt::Debug for TapIo<L, F>\nwhere\n    L: Listener + fmt::Debug,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"TapIo\")\n            .field(\"listener\", &self.listener)\n            .finish_non_exhaustive()\n    }\n}\n\nimpl<L, F> Listener for TapIo<L, F>\nwhere\n    L: Listener,\n    F: FnMut(&mut L::Io) + Send + 'static,\n{\n    type Io = L::Io;\n    type Addr = L::Addr;\n\n    async fn accept(&mut self) -> (Self::Io, Self::Addr) {\n        let (mut io, addr) = self.listener.accept().await;\n        (self.tap_fn)(&mut io);\n        (io, addr)\n    }\n\n    fn local_addr(&self) -> io::Result<Self::Addr> {\n        self.listener.local_addr()\n    }\n}\n\nasync fn handle_accept_error(e: io::Error) {\n    if is_connection_error(&e) {\n        return;\n    }\n\n    // [From `hyper::Server` in 0.14](https://github.com/hyperium/hyper/blob/v0.14.27/src/server/tcp.rs#L186)\n    //\n    // > A possible scenario is that the process has hit the max open files\n    // > allowed, and so trying to accept a new connection will fail with\n    // > `EMFILE`. In some cases, it's preferable to just wait for some time, if\n    // > the application will likely close some files (or connections), and try\n    // > to accept the connection again. If this option is `true`, the error\n    // > will be logged at the `error` level, since it is still a big deal,\n    // > and then the listener will sleep for 1 second.\n    //\n    // hyper allowed customizing this but axum does not.\n    error!(\"accept error: {e}\");\n    tokio::time::sleep(Duration::from_secs(1)).await;\n}\n\nfn is_connection_error(e: &io::Error) -> bool {\n    matches!(\n        e.kind(),\n        io::ErrorKind::ConnectionRefused\n            | io::ErrorKind::ConnectionAborted\n            | io::ErrorKind::ConnectionReset\n    )\n}\n\n#[cfg(test)]\nmod tests {\n    use std::sync::atomic::{AtomicUsize, Ordering};\n\n    use tokio::{io, time};\n\n    use super::{Listener, ListenerExt};\n\n    #[tokio::test(start_paused = true)]\n    async fn limit_connections() {\n        static COUNT: AtomicUsize = AtomicUsize::new(0);\n\n        struct MyListener;\n\n        impl Listener for MyListener {\n            type Io = io::DuplexStream;\n            type Addr = ();\n\n            async fn accept(&mut self) -> (Self::Io, Self::Addr) {\n                COUNT.fetch_add(1, Ordering::SeqCst);\n                (io::duplex(0).0, ()) // dummy connection\n            }\n\n            fn local_addr(&self) -> io::Result<Self::Addr> {\n                Ok(())\n            }\n        }\n\n        let mut listener = MyListener.limit_connections(1);\n\n        assert_eq!(COUNT.load(Ordering::SeqCst), 0);\n\n        // First 'accept' succeeds immediately.\n        let conn1 = listener.accept().await;\n        assert_eq!(COUNT.load(Ordering::SeqCst), 1);\n\n        time::timeout(time::Duration::from_secs(1), listener.accept())\n            .await\n            .expect_err(\"Second 'accept' should time out.\");\n        // It never reaches MyListener::accept to be counted.\n        assert_eq!(COUNT.load(Ordering::SeqCst), 1);\n\n        // Close the first connection.\n        drop(conn1);\n\n        // Now 'accept' again succeeds immediately.\n        let _conn2 = listener.accept().await;\n        assert_eq!(COUNT.load(Ordering::SeqCst), 2);\n    }\n}\n"
  },
  {
    "path": "axum/src/serve/mod.rs",
    "content": "//! Serve services.\n\nuse std::{\n    convert::Infallible,\n    error::Error as StdError,\n    fmt::Debug,\n    future::{Future, IntoFuture},\n    io,\n    marker::PhantomData,\n    pin::pin,\n};\n\nuse axum_core::{body::Body, extract::Request, response::Response};\nuse futures_util::FutureExt;\nuse http_body::Body as HttpBody;\nuse hyper::body::Incoming;\nuse hyper_util::rt::{TokioExecutor, TokioIo, TokioTimer};\n#[cfg(any(feature = \"http1\", feature = \"http2\"))]\nuse hyper_util::{server::conn::auto::Builder, service::TowerToHyperService};\nuse tokio::sync::watch;\nuse tower::ServiceExt as _;\nuse tower_service::Service;\n\nmod listener;\n\npub use self::listener::{ConnLimiter, ConnLimiterIo, Listener, ListenerExt, TapIo};\n\n/// Serve the service with the supplied listener.\n///\n/// This method of running a service is intentionally simple and doesn't support any configuration.\n/// hyper's default configuration applies (including [timeouts]); use hyper or hyper-util if you\n/// need configuration.\n///\n/// It supports both HTTP/1 as well as HTTP/2.\n///\n/// # Examples\n///\n/// Serving a [`Router`]:\n///\n/// ```\n/// use axum::{Router, routing::get};\n///\n/// # async {\n/// let router = Router::new().route(\"/\", get(|| async { \"Hello, World!\" }));\n///\n/// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n/// axum::serve(listener, router).await;\n/// # };\n/// ```\n///\n/// See also [`Router::into_make_service_with_connect_info`].\n///\n/// Serving a [`MethodRouter`]:\n///\n/// ```\n/// use axum::routing::get;\n///\n/// # async {\n/// let router = get(|| async { \"Hello, World!\" });\n///\n/// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n/// axum::serve(listener, router).await;\n/// # };\n/// ```\n///\n/// See also [`MethodRouter::into_make_service_with_connect_info`].\n///\n/// Serving a [`Handler`]:\n///\n/// ```\n/// use axum::handler::HandlerWithoutStateExt;\n///\n/// # async {\n/// async fn handler() -> &'static str {\n///     \"Hello, World!\"\n/// }\n///\n/// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n/// axum::serve(listener, handler.into_make_service()).await;\n/// # };\n/// ```\n///\n/// See also [`HandlerWithoutStateExt::into_make_service_with_connect_info`] and\n/// [`HandlerService::into_make_service_with_connect_info`].\n///\n/// # Return Value\n///\n/// Although this future resolves to `io::Result<()>`, it will never actually complete or return an\n/// error. Errors on the TCP socket will be handled by sleeping for a short while (currently, one\n/// second).\n///\n/// [timeouts]: hyper::server::conn::http1::Builder::header_read_timeout\n/// [`Router`]: crate::Router\n/// [`Router::into_make_service_with_connect_info`]: crate::Router::into_make_service_with_connect_info\n/// [`MethodRouter`]: crate::routing::MethodRouter\n/// [`MethodRouter::into_make_service_with_connect_info`]: crate::routing::MethodRouter::into_make_service_with_connect_info\n/// [`Handler`]: crate::handler::Handler\n/// [`HandlerWithoutStateExt::into_make_service_with_connect_info`]: crate::handler::HandlerWithoutStateExt::into_make_service_with_connect_info\n/// [`HandlerService::into_make_service_with_connect_info`]: crate::handler::HandlerService::into_make_service_with_connect_info\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\npub fn serve<L, M, S, B>(listener: L, make_service: M) -> Serve<L, M, S, B>\nwhere\n    L: Listener,\n    M: for<'a> Service<IncomingStream<'a, L>, Error = Infallible, Response = S>,\n    S: Service<Request, Response = Response<B>, Error = Infallible> + Clone + Send + 'static,\n    S::Future: Send,\n    B: HttpBody + Send + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn StdError + Send + Sync>>,\n{\n    Serve {\n        listener,\n        make_service,\n        _marker: PhantomData,\n    }\n}\n\n/// Future returned by [`serve`].\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\n#[must_use = \"futures must be awaited or polled\"]\npub struct Serve<L, M, S, B> {\n    listener: L,\n    make_service: M,\n    _marker: PhantomData<fn(B) -> S>,\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, B> Serve<L, M, S, B>\nwhere\n    L: Listener,\n{\n    /// Prepares a server to handle graceful shutdown when the provided future completes.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{Router, routing::get};\n    ///\n    /// # async {\n    /// let router = Router::new().route(\"/\", get(|| async { \"Hello, World!\" }));\n    ///\n    /// let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    /// axum::serve(listener, router)\n    ///     .with_graceful_shutdown(shutdown_signal())\n    ///     .await;\n    /// # };\n    ///\n    /// async fn shutdown_signal() {\n    ///     // ...\n    /// }\n    /// ```\n    ///\n    /// # Return Value\n    ///\n    /// Similarly to [`serve`], although this future resolves to `io::Result<()>`, it will never\n    /// error. It returns `Ok(())` only after the `signal` future completes.\n    pub fn with_graceful_shutdown<F>(self, signal: F) -> WithGracefulShutdown<L, M, S, F, B>\n    where\n        F: Future<Output = ()> + Send + 'static,\n    {\n        WithGracefulShutdown {\n            listener: self.listener,\n            make_service: self.make_service,\n            signal,\n            _marker: PhantomData,\n        }\n    }\n\n    /// Returns the local address this server is bound to.\n    pub fn local_addr(&self) -> io::Result<L::Addr> {\n        self.listener.local_addr()\n    }\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, B> Serve<L, M, S, B>\nwhere\n    L: Listener,\n    L::Addr: Debug,\n    M: for<'a> Service<IncomingStream<'a, L>, Error = Infallible, Response = S> + Send + 'static,\n    for<'a> <M as Service<IncomingStream<'a, L>>>::Future: Send,\n    S: Service<Request, Response = Response<B>, Error = Infallible> + Clone + Send + 'static,\n    S::Future: Send,\n    B: HttpBody + Send + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn StdError + Send + Sync>>,\n{\n    async fn run(self) -> ! {\n        let Self {\n            mut listener,\n            mut make_service,\n            _marker,\n        } = self;\n\n        let (signal_tx, _signal_rx) = watch::channel(());\n        let (_close_tx, close_rx) = watch::channel(());\n\n        loop {\n            let (io, remote_addr) = listener.accept().await;\n            handle_connection(&mut make_service, &signal_tx, &close_rx, io, remote_addr).await;\n        }\n    }\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, B> Debug for Serve<L, M, S, B>\nwhere\n    L: Debug + 'static,\n    M: Debug,\n{\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let Self {\n            listener,\n            make_service,\n            _marker: _,\n        } = self;\n\n        let mut s = f.debug_struct(\"Serve\");\n        s.field(\"listener\", listener)\n            .field(\"make_service\", make_service);\n\n        s.finish()\n    }\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, B> IntoFuture for Serve<L, M, S, B>\nwhere\n    L: Listener,\n    L::Addr: Debug,\n    M: for<'a> Service<IncomingStream<'a, L>, Error = Infallible, Response = S> + Send + 'static,\n    for<'a> <M as Service<IncomingStream<'a, L>>>::Future: Send,\n    S: Service<Request, Response = Response<B>, Error = Infallible> + Clone + Send + 'static,\n    S::Future: Send,\n    B: HttpBody + Send + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn StdError + Send + Sync>>,\n{\n    type Output = Infallible;\n    type IntoFuture = private::ServeFuture;\n\n    fn into_future(self) -> Self::IntoFuture {\n        private::ServeFuture(Box::pin(async move { self.run().await }))\n    }\n}\n\n/// Serve future with graceful shutdown enabled.\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\n#[must_use = \"futures must be awaited or polled\"]\npub struct WithGracefulShutdown<L, M, S, F, B> {\n    listener: L,\n    make_service: M,\n    signal: F,\n    _marker: PhantomData<fn(B) -> S>,\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, F, B> WithGracefulShutdown<L, M, S, F, B>\nwhere\n    L: Listener,\n{\n    /// Returns the local address this server is bound to.\n    pub fn local_addr(&self) -> io::Result<L::Addr> {\n        self.listener.local_addr()\n    }\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, F, B> WithGracefulShutdown<L, M, S, F, B>\nwhere\n    L: Listener,\n    L::Addr: Debug,\n    M: for<'a> Service<IncomingStream<'a, L>, Error = Infallible, Response = S> + Send + 'static,\n    for<'a> <M as Service<IncomingStream<'a, L>>>::Future: Send,\n    S: Service<Request, Response = Response<B>, Error = Infallible> + Clone + Send + 'static,\n    S::Future: Send,\n    F: Future<Output = ()> + Send + 'static,\n    B: HttpBody + Send + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn StdError + Send + Sync>>,\n{\n    async fn run(self) {\n        let Self {\n            mut listener,\n            mut make_service,\n            signal,\n            _marker,\n        } = self;\n\n        let (signal_tx, signal_rx) = watch::channel(());\n        tokio::spawn(async move {\n            signal.await;\n            trace!(\"received graceful shutdown signal. Telling tasks to shutdown\");\n            drop(signal_rx);\n        });\n\n        let (close_tx, close_rx) = watch::channel(());\n\n        loop {\n            let (io, remote_addr) = tokio::select! {\n                conn = listener.accept() => conn,\n                _ = signal_tx.closed() => {\n                    trace!(\"signal received, not accepting new connections\");\n                    break;\n                }\n            };\n\n            handle_connection(&mut make_service, &signal_tx, &close_rx, io, remote_addr).await;\n        }\n\n        drop(close_rx);\n        drop(listener);\n\n        trace!(\n            \"waiting for {} task(s) to finish\",\n            close_tx.receiver_count()\n        );\n        close_tx.closed().await;\n    }\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, F, B> Debug for WithGracefulShutdown<L, M, S, F, B>\nwhere\n    L: Debug + 'static,\n    M: Debug,\n    S: Debug,\n    F: Debug,\n{\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let Self {\n            listener,\n            make_service,\n            signal,\n            _marker: _,\n        } = self;\n\n        f.debug_struct(\"WithGracefulShutdown\")\n            .field(\"listener\", listener)\n            .field(\"make_service\", make_service)\n            .field(\"signal\", signal)\n            .finish()\n    }\n}\n\n#[cfg(all(feature = \"tokio\", any(feature = \"http1\", feature = \"http2\")))]\nimpl<L, M, S, F, B> IntoFuture for WithGracefulShutdown<L, M, S, F, B>\nwhere\n    L: Listener,\n    L::Addr: Debug,\n    M: for<'a> Service<IncomingStream<'a, L>, Error = Infallible, Response = S> + Send + 'static,\n    for<'a> <M as Service<IncomingStream<'a, L>>>::Future: Send,\n    S: Service<Request, Response = Response<B>, Error = Infallible> + Clone + Send + 'static,\n    S::Future: Send,\n    F: Future<Output = ()> + Send + 'static,\n    B: HttpBody + Send + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn StdError + Send + Sync>>,\n{\n    type Output = ();\n    type IntoFuture = private::ServeFuture<()>;\n\n    fn into_future(self) -> Self::IntoFuture {\n        private::ServeFuture(Box::pin(async move { self.run().await }))\n    }\n}\n\nasync fn handle_connection<L, M, S, B>(\n    make_service: &mut M,\n    signal_tx: &watch::Sender<()>,\n    close_rx: &watch::Receiver<()>,\n    io: <L as Listener>::Io,\n    remote_addr: <L as Listener>::Addr,\n) where\n    L: Listener,\n    L::Addr: Debug,\n    M: for<'a> Service<IncomingStream<'a, L>, Error = Infallible, Response = S> + Send + 'static,\n    for<'a> <M as Service<IncomingStream<'a, L>>>::Future: Send,\n    S: Service<Request, Response = Response<B>, Error = Infallible> + Clone + Send + 'static,\n    S::Future: Send,\n    B: HttpBody + Send + 'static,\n    B::Data: Send,\n    B::Error: Into<Box<dyn StdError + Send + Sync>>,\n{\n    let io = TokioIo::new(io);\n\n    trace!(\"connection {remote_addr:?} accepted\");\n\n    make_service\n        .ready()\n        .await\n        .unwrap_or_else(|err| match err {});\n\n    let tower_service = make_service\n        .call(IncomingStream {\n            io: &io,\n            remote_addr,\n        })\n        .await\n        .unwrap_or_else(|err| match err {})\n        .map_request(|req: Request<Incoming>| req.map(Body::new));\n\n    let hyper_service = TowerToHyperService::new(tower_service);\n    let signal_tx = signal_tx.clone();\n    let close_rx = close_rx.clone();\n\n    tokio::spawn(async move {\n        #[allow(unused_mut)]\n        let mut builder = Builder::new(TokioExecutor::new());\n\n        // Enable Hyper's default HTTP/1 request header timeout.\n        #[cfg(feature = \"http1\")]\n        builder.http1().timer(TokioTimer::new());\n\n        // CONNECT protocol needed for HTTP/2 websockets\n        #[cfg(feature = \"http2\")]\n        builder.http2().enable_connect_protocol();\n\n        let mut conn = pin!(builder.serve_connection_with_upgrades(io, hyper_service));\n        let mut signal_closed = pin!(signal_tx.closed().fuse());\n\n        loop {\n            tokio::select! {\n                result = conn.as_mut() => {\n                    if let Err(_err) = result {\n                        trace!(\"failed to serve connection: {_err:#}\");\n                    }\n                    break;\n                }\n                _ = &mut signal_closed => {\n                    trace!(\"signal received in task, starting graceful shutdown\");\n                    conn.as_mut().graceful_shutdown();\n                }\n            }\n        }\n\n        drop(close_rx);\n    });\n}\n\n/// An incoming stream.\n///\n/// Used with [`serve`] and [`IntoMakeServiceWithConnectInfo`].\n///\n/// [`IntoMakeServiceWithConnectInfo`]: crate::extract::connect_info::IntoMakeServiceWithConnectInfo\n#[derive(Debug)]\npub struct IncomingStream<'a, L>\nwhere\n    L: Listener,\n{\n    io: &'a TokioIo<L::Io>,\n    remote_addr: L::Addr,\n}\n\nimpl<L> IncomingStream<'_, L>\nwhere\n    L: Listener,\n{\n    /// Get a reference to the inner IO type.\n    pub fn io(&self) -> &L::Io {\n        self.io.inner()\n    }\n\n    /// Returns the remote address that this stream is bound to.\n    pub fn remote_addr(&self) -> &L::Addr {\n        &self.remote_addr\n    }\n}\n\nmod private {\n    use std::{\n        convert::Infallible,\n        future::Future,\n        pin::Pin,\n        task::{Context, Poll},\n    };\n\n    pub struct ServeFuture<T = Infallible>(pub(super) futures_core::future::BoxFuture<'static, T>);\n\n    impl<T> Future for ServeFuture<T> {\n        type Output = T;\n\n        #[inline]\n        fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n            self.0.as_mut().poll(cx)\n        }\n    }\n\n    impl std::fmt::Debug for ServeFuture {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            f.debug_struct(\"ServeFuture\").finish_non_exhaustive()\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::{\n        future::{pending, IntoFuture as _},\n        net::{IpAddr, Ipv4Addr},\n        time::Duration,\n    };\n\n    use axum_core::{body::Body, extract::Request};\n    use http::{Response, StatusCode};\n    use hyper_util::rt::TokioIo;\n    #[cfg(unix)]\n    use tokio::net::UnixListener;\n    use tokio::{\n        io::{self, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},\n        net::TcpListener,\n    };\n    use tower::ServiceBuilder;\n\n    #[cfg(unix)]\n    use super::IncomingStream;\n    use super::{serve, Listener};\n    #[cfg(unix)]\n    use crate::extract::connect_info::Connected;\n    use crate::{\n        body::to_bytes,\n        handler::{Handler, HandlerWithoutStateExt},\n        routing::get,\n        serve::ListenerExt,\n        Router, ServiceExt,\n    };\n\n    struct ReadyListener<T>(Option<T>);\n\n    impl<T> Listener for ReadyListener<T>\n    where\n        T: AsyncRead + AsyncWrite + Unpin + Send + 'static,\n    {\n        type Io = T;\n        type Addr = ();\n\n        async fn accept(&mut self) -> (Self::Io, Self::Addr) {\n            match self.0.take() {\n                Some(server) => (server, ()),\n                None => std::future::pending().await,\n            }\n        }\n\n        fn local_addr(&self) -> io::Result<Self::Addr> {\n            Ok(())\n        }\n    }\n\n    #[allow(dead_code, unused_must_use)]\n    async fn if_it_compiles_it_works() {\n        #[derive(Clone, Debug)]\n        struct UdsConnectInfo;\n\n        #[cfg(unix)]\n        impl Connected<IncomingStream<'_, UnixListener>> for UdsConnectInfo {\n            fn connect_info(_stream: IncomingStream<'_, UnixListener>) -> Self {\n                Self\n            }\n        }\n\n        let router: Router = Router::new();\n\n        let addr = \"0.0.0.0:0\";\n\n        let tcp_nodelay_listener = || async {\n            TcpListener::bind(addr).await.unwrap().tap_io(|tcp_stream| {\n                if let Err(err) = tcp_stream.set_nodelay(true) {\n                    eprintln!(\"failed to set TCP_NODELAY on incoming connection: {err:#}\");\n                }\n            })\n        };\n\n        // router\n        serve(TcpListener::bind(addr).await.unwrap(), router.clone());\n        serve(tcp_nodelay_listener().await, router.clone()).await;\n        #[cfg(unix)]\n        serve(UnixListener::bind(\"\").unwrap(), router.clone());\n\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            router.clone().into_make_service(),\n        );\n        serve(\n            tcp_nodelay_listener().await,\n            router.clone().into_make_service(),\n        );\n        #[cfg(unix)]\n        serve(\n            UnixListener::bind(\"\").unwrap(),\n            router.clone().into_make_service(),\n        );\n\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            router\n                .clone()\n                .into_make_service_with_connect_info::<std::net::SocketAddr>(),\n        );\n        serve(\n            tcp_nodelay_listener().await,\n            router\n                .clone()\n                .into_make_service_with_connect_info::<std::net::SocketAddr>(),\n        );\n        #[cfg(unix)]\n        serve(\n            UnixListener::bind(\"\").unwrap(),\n            router.into_make_service_with_connect_info::<UdsConnectInfo>(),\n        );\n\n        // method router\n        serve(TcpListener::bind(addr).await.unwrap(), get(handler));\n        serve(tcp_nodelay_listener().await, get(handler));\n        #[cfg(unix)]\n        serve(UnixListener::bind(\"\").unwrap(), get(handler));\n\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            get(handler).into_make_service(),\n        );\n        serve(\n            tcp_nodelay_listener().await,\n            get(handler).into_make_service(),\n        );\n        #[cfg(unix)]\n        serve(\n            UnixListener::bind(\"\").unwrap(),\n            get(handler).into_make_service(),\n        );\n\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            get(handler).into_make_service_with_connect_info::<std::net::SocketAddr>(),\n        );\n        serve(\n            tcp_nodelay_listener().await,\n            get(handler).into_make_service_with_connect_info::<std::net::SocketAddr>(),\n        );\n        #[cfg(unix)]\n        serve(\n            UnixListener::bind(\"\").unwrap(),\n            get(handler).into_make_service_with_connect_info::<UdsConnectInfo>(),\n        );\n\n        // handler\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            handler.into_service(),\n        );\n        serve(tcp_nodelay_listener().await, handler.into_service());\n        #[cfg(unix)]\n        serve(UnixListener::bind(\"\").unwrap(), handler.into_service());\n\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            handler.with_state(()),\n        );\n        serve(tcp_nodelay_listener().await, handler.with_state(()));\n        #[cfg(unix)]\n        serve(UnixListener::bind(\"\").unwrap(), handler.with_state(()));\n\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            handler.into_make_service(),\n        );\n        serve(tcp_nodelay_listener().await, handler.into_make_service());\n        #[cfg(unix)]\n        serve(UnixListener::bind(\"\").unwrap(), handler.into_make_service());\n\n        serve(\n            TcpListener::bind(addr).await.unwrap(),\n            handler.into_make_service_with_connect_info::<std::net::SocketAddr>(),\n        );\n        serve(\n            tcp_nodelay_listener().await,\n            handler.into_make_service_with_connect_info::<std::net::SocketAddr>(),\n        );\n        #[cfg(unix)]\n        serve(\n            UnixListener::bind(\"\").unwrap(),\n            handler.into_make_service_with_connect_info::<UdsConnectInfo>(),\n        );\n    }\n\n    async fn handler() {}\n\n    #[crate::test]\n    async fn test_serve_local_addr() {\n        let router: Router = Router::new();\n        let addr = \"0.0.0.0:0\";\n\n        let server = serve(TcpListener::bind(addr).await.unwrap(), router.clone());\n        let address = server.local_addr().unwrap();\n\n        assert_eq!(address.ip(), IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));\n        assert_ne!(address.port(), 0);\n    }\n\n    #[crate::test]\n    async fn test_with_graceful_shutdown_local_addr() {\n        let router: Router = Router::new();\n        let addr = \"0.0.0.0:0\";\n\n        let server = serve(TcpListener::bind(addr).await.unwrap(), router.clone())\n            .with_graceful_shutdown(pending());\n        let address = server.local_addr().unwrap();\n\n        assert_eq!(address.ip(), IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)));\n        assert_ne!(address.port(), 0);\n    }\n\n    #[tokio::test(start_paused = true)]\n    async fn test_with_graceful_shutdown_request_header_timeout() {\n        for (timeout, req) in [\n            // Idle connections (between requests) are closed immediately\n            // when a graceful shutdown is triggered.\n            (0, \"\"),                       // idle before request sent\n            (0, \"GET / HTTP/1.1\\r\\n\\r\\n\"), // idle after complete exchange\n            // hyper times stalled request lines/headers out after 30 sec,\n            // after which the graceful shutdown can be completed.\n            (30, \"GET / HT\"),                   // stall during request line\n            (30, \"GET / HTTP/1.0\\r\\nAccept: \"), // stall during request headers\n        ] {\n            let (mut client, server) = io::duplex(1024);\n            client.write_all(req.as_bytes()).await.unwrap();\n\n            let server_task = async {\n                serve(ReadyListener(Some(server)), Router::new())\n                    .with_graceful_shutdown(tokio::time::sleep(Duration::from_secs(1)))\n                    .await;\n            };\n\n            tokio::time::timeout(Duration::from_secs(timeout + 2), server_task)\n                .await\n                .expect(\"server_task didn't exit in time\");\n        }\n    }\n\n    #[tokio::test(start_paused = true)]\n    async fn test_hyper_header_read_timeout_is_enabled() {\n        let header_read_timeout_default = 30;\n        for req in [\n            \"GET / HT\",                   // stall during request line\n            \"GET / HTTP/1.0\\r\\nAccept: \", // stall during request headers\n        ] {\n            let (mut client, server) = io::duplex(1024);\n            client.write_all(req.as_bytes()).await.unwrap();\n\n            let server_task = async {\n                serve(ReadyListener(Some(server)), Router::new()).await;\n            };\n\n            let wait_for_server_to_close_conn = async {\n                tokio::time::timeout(\n                    Duration::from_secs(header_read_timeout_default + 1),\n                    client.read_to_end(&mut Vec::new()),\n                )\n                .await\n                .expect(\"timeout: server didn't close connection in time\")\n                .expect(\"read_to_end\");\n            };\n\n            tokio::select! {\n                _ = server_task => unreachable!(),\n                _ = wait_for_server_to_close_conn => (),\n            };\n        }\n    }\n\n    #[test]\n    fn into_future_outside_tokio() {\n        let router: Router = Router::new();\n        let addr = \"0.0.0.0:0\";\n\n        let rt = tokio::runtime::Builder::new_multi_thread()\n            .enable_all()\n            .build()\n            .unwrap();\n\n        let listener = rt.block_on(tokio::net::TcpListener::bind(addr)).unwrap();\n\n        // Call Serve::into_future outside of a tokio context. This used to panic.\n        _ = serve(listener, router).into_future();\n    }\n\n    #[crate::test]\n    async fn serving_on_custom_io_type() {\n        let (client, server) = io::duplex(1024);\n        let listener = ReadyListener(Some(server));\n\n        let app = Router::new().route(\"/\", get(|| async { \"Hello, World!\" }));\n\n        tokio::spawn(serve(listener, app).into_future());\n\n        let stream = TokioIo::new(client);\n        let (mut sender, conn) = hyper::client::conn::http1::handshake(stream).await.unwrap();\n        tokio::spawn(conn);\n\n        let request = Request::builder().body(Body::empty()).unwrap();\n\n        let response = sender.send_request(request).await.unwrap();\n        assert_eq!(response.status(), StatusCode::OK);\n\n        let body = Body::new(response.into_body());\n        let body = to_bytes(body, usize::MAX).await.unwrap();\n        let body = String::from_utf8(body.to_vec()).unwrap();\n        assert_eq!(body, \"Hello, World!\");\n    }\n\n    #[crate::test]\n    async fn serving_with_custom_body_type() {\n        struct CustomBody;\n        impl http_body::Body for CustomBody {\n            type Data = bytes::Bytes;\n            type Error = std::convert::Infallible;\n            fn poll_frame(\n                self: std::pin::Pin<&mut Self>,\n                _cx: &mut std::task::Context<'_>,\n            ) -> std::task::Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>>\n            {\n                #![allow(clippy::unreachable)] // The implementation is not used, we just need to provide one.\n                unreachable!();\n            }\n        }\n\n        let app = ServiceBuilder::new()\n            .layer_fn(|_| tower::service_fn(|_| std::future::ready(Ok(Response::new(CustomBody)))))\n            .service(Router::<()>::new().route(\"/hello\", get(|| async {})));\n        let addr = \"0.0.0.0:0\";\n\n        _ = serve(\n            TcpListener::bind(addr).await.unwrap(),\n            app.into_make_service(),\n        );\n    }\n}\n"
  },
  {
    "path": "axum/src/service_ext.rs",
    "content": "use crate::error_handling::HandleError;\n#[cfg(feature = \"tokio\")]\nuse crate::extract::connect_info::IntoMakeServiceWithConnectInfo;\nuse crate::routing::IntoMakeService;\nuse tower_service::Service;\n\n/// Extension trait that adds additional methods to any [`Service`].\npub trait ServiceExt<R>: Service<R> + Sized {\n    /// Convert this service into a [`MakeService`], that is a [`Service`] whose\n    /// response is another service.\n    ///\n    /// This is commonly used when applying middleware around an entire [`Router`]. See [\"Rewriting\n    /// request URI in middleware\"] for more details.\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    /// [\"Rewriting request URI in middleware\"]: crate::middleware#rewriting-request-uri-in-middleware\n    /// [`Router`]: crate::Router\n    fn into_make_service(self) -> IntoMakeService<Self>;\n\n    /// Convert this service into a [`MakeService`], that will store `C`'s\n    /// associated `ConnectInfo` in a request extension such that [`ConnectInfo`]\n    /// can extract it.\n    ///\n    /// This enables extracting things like the client's remote address.\n    /// This is commonly used when applying middleware around an entire [`Router`]. See [\"Rewriting\n    /// request URI in middleware\"] for more details.\n    ///\n    /// [`MakeService`]: tower::make::MakeService\n    /// [\"Rewriting request URI in middleware\"]: crate::middleware#rewriting-request-uri-in-middleware\n    /// [`Router`]: crate::Router\n    /// [`ConnectInfo`]: crate::extract::connect_info::ConnectInfo\n    #[cfg(feature = \"tokio\")]\n    fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C>;\n\n    /// Convert this service into a [`HandleError`], that will handle errors\n    /// by converting them into responses.\n    ///\n    ///  See [\"error handling model\"] for more details.\n    ///\n    /// [`HandleError`]: crate::error_handling::HandleError\n    /// [\"error handling model\"]: crate::error_handling#axums-error-handling-model\n    fn handle_error<F, T>(self, f: F) -> HandleError<Self, F, T> {\n        HandleError::new(self, f)\n    }\n}\n\nimpl<S, R> ServiceExt<R> for S\nwhere\n    S: Service<R> + Sized,\n{\n    fn into_make_service(self) -> IntoMakeService<Self> {\n        IntoMakeService::new(self)\n    }\n\n    #[cfg(feature = \"tokio\")]\n    fn into_make_service_with_connect_info<C>(self) -> IntoMakeServiceWithConnectInfo<Self, C> {\n        IntoMakeServiceWithConnectInfo::new(self)\n    }\n}\n"
  },
  {
    "path": "axum/src/test_helpers/counting_cloneable_state.rs",
    "content": "use std::sync::{\n    atomic::{AtomicBool, AtomicUsize, Ordering},\n    Arc,\n};\n\npub(crate) struct CountingCloneableState {\n    state: Arc<InnerState>,\n}\n\nstruct InnerState {\n    setup_done: AtomicBool,\n    count: AtomicUsize,\n}\n\nimpl CountingCloneableState {\n    pub(crate) fn new() -> Self {\n        let inner_state = InnerState {\n            setup_done: AtomicBool::new(false),\n            count: AtomicUsize::new(0),\n        };\n        Self {\n            state: Arc::new(inner_state),\n        }\n    }\n\n    pub(crate) fn setup_done(&self) {\n        self.state.setup_done.store(true, Ordering::SeqCst);\n    }\n\n    pub(crate) fn count(&self) -> usize {\n        self.state.count.load(Ordering::SeqCst)\n    }\n}\n\nimpl Clone for CountingCloneableState {\n    fn clone(&self) -> Self {\n        let state = self.state.clone();\n        if state.setup_done.load(Ordering::SeqCst) {\n            let bt = std::backtrace::Backtrace::force_capture();\n            let bt = bt\n                .to_string()\n                .lines()\n                .filter(|line| line.contains(\"axum\") || line.contains(\"./src\"))\n                .collect::<Vec<_>>()\n                .join(\"\\n\");\n            println!(\"AppState::Clone:\\n===============\\n{bt}\\n\");\n            state.count.fetch_add(1, Ordering::SeqCst);\n        }\n\n        Self { state }\n    }\n}\n"
  },
  {
    "path": "axum/src/test_helpers/mod.rs",
    "content": "#![allow(clippy::disallowed_names)]\n\nuse crate::{extract::Request, response::Response, serve};\n\nmod test_client;\npub use self::test_client::*;\n\n#[cfg(test)]\npub(crate) mod tracing_helpers;\n\n#[cfg(test)]\npub(crate) mod counting_cloneable_state;\n\n#[cfg(test)]\npub(crate) fn assert_send<T: Send>() {}\n#[cfg(test)]\npub(crate) fn assert_sync<T: Sync>() {}\n\n#[allow(dead_code)]\npub(crate) struct NotSendSync(*const ());\n"
  },
  {
    "path": "axum/src/test_helpers/test_client.rs",
    "content": "use super::{serve, Request, Response};\nuse bytes::Bytes;\nuse futures_core::future::BoxFuture;\nuse http::header::{HeaderName, HeaderValue};\nuse std::ops::Deref;\nuse std::{convert::Infallible, future::IntoFuture, net::SocketAddr};\nuse tokio::net::TcpListener;\nuse tower::make::Shared;\nuse tower_service::Service;\n\npub(crate) fn spawn_service<S>(svc: S) -> SocketAddr\nwhere\n    S: Service<Request, Response = Response, Error = Infallible> + Clone + Send + 'static,\n    S::Future: Send,\n{\n    let std_listener = std::net::TcpListener::bind(\"127.0.0.1:0\").unwrap();\n    std_listener.set_nonblocking(true).unwrap();\n    let listener = TcpListener::from_std(std_listener).unwrap();\n\n    let addr = listener.local_addr().unwrap();\n    println!(\"Listening on {addr}\");\n\n    tokio::spawn(async move {\n        serve(listener, Shared::new(svc)).await;\n    });\n\n    addr\n}\n\npub struct TestClient {\n    client: reqwest::Client,\n    addr: SocketAddr,\n}\n\nimpl TestClient {\n    pub fn new<S>(svc: S) -> Self\n    where\n        S: Service<Request, Response = Response, Error = Infallible> + Clone + Send + 'static,\n        S::Future: Send,\n    {\n        let addr = spawn_service(svc);\n\n        let client = reqwest::Client::builder()\n            .redirect(reqwest::redirect::Policy::none())\n            .build()\n            .unwrap();\n\n        Self { client, addr }\n    }\n\n    pub fn get(&self, url: &str) -> RequestBuilder {\n        RequestBuilder {\n            builder: self.client.get(format!(\"http://{}{url}\", self.addr)),\n        }\n    }\n\n    pub fn head(&self, url: &str) -> RequestBuilder {\n        RequestBuilder {\n            builder: self.client.head(format!(\"http://{}{url}\", self.addr)),\n        }\n    }\n\n    pub fn post(&self, url: &str) -> RequestBuilder {\n        RequestBuilder {\n            builder: self.client.post(format!(\"http://{}{url}\", self.addr)),\n        }\n    }\n\n    #[allow(dead_code)]\n    pub fn put(&self, url: &str) -> RequestBuilder {\n        RequestBuilder {\n            builder: self.client.put(format!(\"http://{}{url}\", self.addr)),\n        }\n    }\n\n    #[allow(dead_code)]\n    pub fn patch(&self, url: &str) -> RequestBuilder {\n        RequestBuilder {\n            builder: self.client.patch(format!(\"http://{}{url}\", self.addr)),\n        }\n    }\n\n    #[allow(dead_code)]\n    #[must_use]\n    pub fn server_port(&self) -> u16 {\n        self.addr.port()\n    }\n}\n\n#[must_use]\npub struct RequestBuilder {\n    builder: reqwest::RequestBuilder,\n}\n\nimpl RequestBuilder {\n    pub fn body(mut self, body: impl Into<reqwest::Body>) -> Self {\n        self.builder = self.builder.body(body);\n        self\n    }\n\n    pub fn json<T>(mut self, json: &T) -> Self\n    where\n        T: serde_core::Serialize,\n    {\n        self.builder = self.builder.json(json);\n        self\n    }\n\n    pub fn header<K, V>(mut self, key: K, value: V) -> Self\n    where\n        HeaderName: TryFrom<K>,\n        <HeaderName as TryFrom<K>>::Error: Into<http::Error>,\n        HeaderValue: TryFrom<V>,\n        <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,\n    {\n        self.builder = self.builder.header(key, value);\n        self\n    }\n\n    #[allow(dead_code)]\n    pub fn multipart(mut self, form: reqwest::multipart::Form) -> Self {\n        self.builder = self.builder.multipart(form);\n        self\n    }\n}\n\nimpl IntoFuture for RequestBuilder {\n    type Output = TestResponse;\n    type IntoFuture = BoxFuture<'static, Self::Output>;\n\n    fn into_future(self) -> Self::IntoFuture {\n        Box::pin(async {\n            TestResponse {\n                response: self.builder.send().await.unwrap(),\n            }\n        })\n    }\n}\n\n#[derive(Debug)]\npub struct TestResponse {\n    response: reqwest::Response,\n}\n\nimpl Deref for TestResponse {\n    type Target = reqwest::Response;\n\n    fn deref(&self) -> &Self::Target {\n        &self.response\n    }\n}\n\nimpl TestResponse {\n    #[allow(dead_code)]\n    pub async fn bytes(self) -> Bytes {\n        self.response.bytes().await.unwrap()\n    }\n\n    pub async fn text(self) -> String {\n        self.response.text().await.unwrap()\n    }\n\n    #[allow(dead_code)]\n    pub async fn json<T>(self) -> T\n    where\n        T: serde_core::de::DeserializeOwned,\n    {\n        self.response.json().await.unwrap()\n    }\n\n    pub async fn chunk(&mut self) -> Option<Bytes> {\n        self.response.chunk().await.unwrap()\n    }\n\n    pub async fn chunk_text(&mut self) -> Option<String> {\n        let chunk = self.chunk().await?;\n        Some(String::from_utf8(chunk.to_vec()).unwrap())\n    }\n}\n"
  },
  {
    "path": "axum/src/test_helpers/tracing_helpers.rs",
    "content": "use std::{\n    future::{Future, IntoFuture},\n    io,\n    marker::PhantomData,\n    pin::Pin,\n    sync::{Arc, Mutex},\n};\n\nuse serde::{de::DeserializeOwned, Deserialize};\nuse tracing::instrument::WithSubscriber;\nuse tracing_subscriber::prelude::*;\nuse tracing_subscriber::{filter::Targets, fmt::MakeWriter};\n\n#[derive(Deserialize, Eq, PartialEq, Debug)]\n#[serde(deny_unknown_fields)]\npub(crate) struct TracingEvent<T> {\n    pub(crate) fields: T,\n    pub(crate) target: String,\n    pub(crate) level: String,\n}\n\n/// Run an async closure and capture the tracing output it produces.\npub(crate) fn capture_tracing<T, F>(f: F) -> CaptureTracing<T, F>\nwhere\n    T: DeserializeOwned,\n{\n    CaptureTracing {\n        f,\n        filter: None,\n        _phantom: PhantomData,\n    }\n}\n\npub(crate) struct CaptureTracing<T, F> {\n    f: F,\n    filter: Option<Targets>,\n    _phantom: PhantomData<fn() -> T>,\n}\n\nimpl<T, F> CaptureTracing<T, F> {\n    pub(crate) fn with_filter(mut self, filter_string: &str) -> Self {\n        self.filter = Some(filter_string.parse().unwrap());\n        self\n    }\n}\n\nimpl<T, F, Fut> IntoFuture for CaptureTracing<T, F>\nwhere\n    F: Fn() -> Fut + Send + Sync + 'static,\n    Fut: Future + Send,\n    T: DeserializeOwned,\n{\n    type Output = Vec<TracingEvent<T>>;\n    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;\n\n    fn into_future(self) -> Self::IntoFuture {\n        let Self { f, filter, .. } = self;\n        Box::pin(async move {\n            let (make_writer, handle) = TestMakeWriter::new();\n\n            let filter = filter.unwrap_or_else(|| \"axum=trace\".parse().unwrap());\n            let subscriber = tracing_subscriber::registry().with(\n                tracing_subscriber::fmt::layer()\n                    .with_writer(make_writer)\n                    .with_target(true)\n                    .without_time()\n                    .with_ansi(false)\n                    .json()\n                    .flatten_event(false)\n                    .with_filter(filter),\n            );\n\n            let guard = tracing::subscriber::set_default(subscriber);\n\n            f().with_current_subscriber().await;\n\n            drop(guard);\n\n            handle\n                .take()\n                .lines()\n                .map(|line| serde_json::from_str(line).unwrap())\n                .collect()\n        })\n    }\n}\n\nstruct TestMakeWriter {\n    write: Arc<Mutex<Option<Vec<u8>>>>,\n}\n\nimpl TestMakeWriter {\n    fn new() -> (Self, Handle) {\n        let write = Arc::new(Mutex::new(Some(Vec::<u8>::new())));\n\n        (\n            Self {\n                write: write.clone(),\n            },\n            Handle { write },\n        )\n    }\n}\n\nimpl<'a> MakeWriter<'a> for TestMakeWriter {\n    type Writer = Writer<'a>;\n\n    fn make_writer(&'a self) -> Self::Writer {\n        Writer(self)\n    }\n}\n\nstruct Writer<'a>(&'a TestMakeWriter);\n\nimpl io::Write for Writer<'_> {\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        match &mut *self.0.write.lock().unwrap() {\n            Some(vec) => {\n                let len = buf.len();\n                vec.extend(buf);\n                Ok(len)\n            }\n            None => Err(io::Error::other(\"inner writer has been taken\")),\n        }\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        Ok(())\n    }\n}\n\nstruct Handle {\n    write: Arc<Mutex<Option<Vec<u8>>>>,\n}\n\nimpl Handle {\n    fn take(self) -> String {\n        let vec = self.write.lock().unwrap().take().unwrap();\n        String::from_utf8(vec).unwrap()\n    }\n}\n"
  },
  {
    "path": "axum/src/util.rs",
    "content": "use axum_core::response::{IntoResponse, Response};\nuse pin_project_lite::pin_project;\nuse std::{\n    future::Future,\n    ops::Deref,\n    pin::Pin,\n    sync::Arc,\n    task::{ready, Context, Poll},\n};\nuse tower::Service;\n\n#[derive(Clone, Debug, PartialEq, Eq, Hash)]\npub(crate) struct PercentDecodedStr(Arc<str>);\n\nimpl PercentDecodedStr {\n    pub(crate) fn new<S>(s: S) -> Option<Self>\n    where\n        S: AsRef<str>,\n    {\n        percent_encoding::percent_decode(s.as_ref().as_bytes())\n            .decode_utf8()\n            .ok()\n            .map(|decoded| Self(decoded.as_ref().into()))\n    }\n\n    pub(crate) fn as_str(&self) -> &str {\n        &self.0\n    }\n}\n\nimpl Deref for PercentDecodedStr {\n    type Target = str;\n\n    #[inline]\n    fn deref(&self) -> &Self::Target {\n        self.as_str()\n    }\n}\n\npin_project! {\n    #[project = EitherProj]\n    pub(crate) enum Either<A, B> {\n        A { #[pin] inner: A },\n        B { #[pin] inner: B },\n    }\n}\n\n#[derive(Clone)]\npub(crate) struct MapIntoResponse<S> {\n    inner: S,\n}\n\nimpl<S> MapIntoResponse<S> {\n    pub(crate) fn new(inner: S) -> Self {\n        Self { inner }\n    }\n}\n\nimpl<B, S> Service<http::Request<B>> for MapIntoResponse<S>\nwhere\n    S: Service<http::Request<B>>,\n    S::Response: IntoResponse,\n{\n    type Response = Response;\n    type Error = S::Error;\n    type Future = MapIntoResponseFuture<S::Future>;\n\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        self.inner.poll_ready(cx)\n    }\n\n    fn call(&mut self, req: http::Request<B>) -> Self::Future {\n        MapIntoResponseFuture {\n            inner: self.inner.call(req),\n        }\n    }\n}\n\npin_project! {\n    pub(crate) struct MapIntoResponseFuture<F> {\n        #[pin]\n        inner: F,\n    }\n}\n\nimpl<F, T, E> Future for MapIntoResponseFuture<F>\nwhere\n    F: Future<Output = Result<T, E>>,\n    T: IntoResponse,\n{\n    type Output = Result<Response, E>;\n\n    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        let res = ready!(self.project().inner.poll(cx)?);\n        Poll::Ready(Ok(res.into_response()))\n    }\n}\n\npub(crate) fn try_downcast<T, K>(k: K) -> Result<T, K>\nwhere\n    T: 'static,\n    K: Send + 'static,\n{\n    let mut k = Some(k);\n    if let Some(k) = <dyn std::any::Any>::downcast_mut::<Option<T>>(&mut k) {\n        Ok(k.take().unwrap())\n    } else {\n        Err(k.unwrap())\n    }\n}\n\n#[test]\nfn test_try_downcast() {\n    assert_eq!(try_downcast::<i32, _>(5_u32), Err(5_u32));\n    assert_eq!(try_downcast::<i32, _>(5_i32), Ok(5_i32));\n}\n"
  },
  {
    "path": "axum/tests/panic_location.rs",
    "content": "//! Separate test binary, because the panic hook is a global resource\n\nuse std::{\n    panic::{catch_unwind, set_hook, take_hook},\n    path::Path,\n    sync::OnceLock,\n};\n\nuse axum::{routing::get, Router};\n\n#[test]\nfn routes_with_overlapping_method_routes() {\n    static PANIC_LOCATION_FILE: OnceLock<String> = OnceLock::new();\n\n    let default_hook = take_hook();\n    set_hook(Box::new(|panic_info| {\n        if let Some(location) = panic_info.location() {\n            _ = PANIC_LOCATION_FILE.set(location.file().to_owned());\n        }\n    }));\n\n    let result = catch_unwind(|| {\n        async fn handler() {}\n\n        let _: Router = Router::new()\n            .route(\"/foo/bar\", get(handler))\n            .route(\"/foo/bar\", get(handler));\n    });\n    set_hook(default_hook);\n\n    let panic_payload = result.unwrap_err();\n    let panic_msg = panic_payload.downcast_ref::<String>().unwrap();\n\n    assert_eq!(\n        panic_msg,\n        \"Overlapping method route. Handler for `GET /foo/bar` already exists\"\n    );\n\n    let file = PANIC_LOCATION_FILE.get().unwrap();\n    assert_eq!(Path::new(file).file_name().unwrap(), \"panic_location.rs\");\n}\n"
  },
  {
    "path": "axum-core/CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n# 0.5.6\n\nImprove error messages with `#[diagnostic::do_not_recommend]`.\n\n# 0.5.5\n\nReleased without changes to fix docs.rs build.\n\n# 0.5.4\n\n- **fixed:** Removed unused `rustversion` dependency ([#3502])\n\n[#3502]: https://github.com/tokio-rs/axum/pull/3502\n\n# 0.5.3\n\n- **added:** `DefaultBodyLimit::apply` for changing the `DefaultBodyLimit` inside extractors.\n  ([#3368])\n- **changed:** Update minimum rust version to 1.78 ([#3412])\n\n[#3368]: https://github.com/tokio-rs/axum/pull/3366\n\n# 0.5.2\n\n- **added:** Implement `Stream::size_hint` for `BodyDataStream` ([#3195])\n\n[#3195]: https://github.com/tokio-rs/axum/pull/3195\n\n# 0.5.1\n\nYanked from crates.io due to unforeseen breaking change, see [#3190] for details.\n\n[#3190]: https://github.com/tokio-rs/axum/pull/3190\n\n# 0.5.0\n\n## since rc.1\n\n<details>\n\n- **change:** The `Display` impl of all rejections generated by the\n  `define_rejection!()` will now include the `Display` output of the\n  inner error too. This matches the `body_text()` fn output now. ([#3118])\n\n</details>\n\n## full changelog\n\n- **breaking:** Replace `#[async_trait]` with [return-position `impl Trait` in traits][RPITIT] ([#2308])\n- **breaking:** `Option<T>` as an extractor now requires `T` to implement the\n  new trait `OptionalFromRequest` (if used as the last extractor) or\n  `OptionalFromRequestParts` (other extractors) ([#2475])\n- **change:** Update minimum rust version to 1.75 ([#2943])\n- **change:** The `Display` impl of all rejections generated by the\n  `define_rejection!()` will now include the `Display` output of the\n  inner error too. This matches the `body_text()` fn output now. ([#3118])\n\n[#3118]: https://github.com/tokio-rs/axum/pull/3118\n\n## rc.1\n\n- **breaking:** `Option<T>` as an extractor now requires `T` to implement the\n  new trait `OptionalFromRequest` (if used as the last extractor) or\n  `OptionalFromRequestParts` (other extractors) ([#2475])\n\n[#2475]: https://github.com/tokio-rs/axum/pull/2475\n\n## alpha.1\n\n- **breaking:** Replace `#[async_trait]` with [return-position `impl Trait` in traits][RPITIT] ([#2308])\n- **change:** Update minimum rust version to 1.75 ([#2943])\n\n[RPITIT]: https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html\n[#2308]: https://github.com/tokio-rs/axum/pull/2308\n[#2943]: https://github.com/tokio-rs/axum/pull/2943\n\n# 0.4.5\n\n- **fixed:** Compile errors from the internal `__log_rejection` macro under\n  certain Cargo feature combinations between axum crates ([#2933])\n\n[#2933]: https://github.com/tokio-rs/axum/pull/2933\n\n# 0.4.4\n\n- **added:** Derive `Clone` and `Copy` for `AppendHeaders` ([#2776])\n- **added:** `must_use` attribute on `AppendHeaders` ([#2846])\n- **added:** `must_use` attribute on `ErrorResponse` ([#2846])\n- **added:** `must_use` attribute on `IntoResponse::into_response` ([#2846])\n- **added:** `must_use` attribute on `IntoResponseParts` trait methods ([#2846])\n- **added:** Implement `Copy` for `DefaultBodyLimit` ([#2875])\n- **added**: `DefaultBodyLimit::max` and `DefaultBodyLimit::disable` are now\n  allowed in const context ([#2875])\n\n[#2776]: https://github.com/tokio-rs/axum/pull/2776\n[#2846]: https://github.com/tokio-rs/axum/pull/2846\n[#2875]: https://github.com/tokio-rs/axum/pull/2875\n\n# 0.4.3 (13. January, 2024)\n\n- **added:** Implement `IntoResponseParts` for `()` ([#2471])\n\n[#2471]: https://github.com/tokio-rs/axum/pull/2471\n\n# 0.4.2 (29. December, 2023)\n\n- **added:** `Body` implements `From<()>` now ([#2411])\n\n[#2411]: https://github.com/tokio-rs/axum/pull/2411\n\n# 0.4.1 (03. December, 2023)\n\n- Fix from_stream doc link to `Stream` in docs ([#2391])\n\n[#2391]: https://github.com/tokio-rs/axum/pull/2391\n\n# 0.4.0 (27. November, 2023)\n\n- **added:** Implement `IntoResponse` for `(R,) where R: IntoResponse` ([#2143])\n- **fixed:** Fix broken docs links ([#2164])\n- **fixed:** Clearly document applying `DefaultBodyLimit` to individual routes ([#2157])\n- **breaking:** The following types/traits are no longer generic over the request body\n  (i.e. the `B` type param has been removed) ([#1751] and [#1789]):\n  - `FromRequestParts`\n  - `FromRequest`\n  - `RequestExt`\n- **breaking:** axum no longer re-exports `hyper::Body` as that type is removed\n  in hyper 1.0. Instead axum has its own body type at `axum_core::body::Body` ([#1751])\n\n[#2143]: https://github.com/tokio-rs/axum/pull/2143\n[#2164]: https://github.com/tokio-rs/axum/pull/2164\n[#2157]: https://github.com/tokio-rs/axum/pull/2157\n\n# 0.3.4 (11. April, 2023)\n\n- Changes to private APIs.\n\n# 0.3.3 (03. March, 2023)\n\n- **fixed:** Add `#[must_use]` attributes to types that do nothing unless used ([#1809])\n\n[#1809]: https://github.com/tokio-rs/axum/pull/1809\n\n# 0.3.2 (20. January, 2023)\n\n- **added:** Implement `IntoResponse` for `&'static [u8; N]` and `[u8; N]` ([#1690])\n\n[#1690]: https://github.com/tokio-rs/axum/pull/1690\n\n# 0.3.1 (9. January, 2023)\n\n- **added:** Add `body_text` and `status` methods to built-in rejections ([#1612])\n\n[#1612]: https://github.com/tokio-rs/axum/pull/1612\n\n# 0.3.0 (25. November, 2022)\n\n- **added:** Added new `FromRequestParts` trait. See axum's changelog for more\n  details ([#1272])\n- **breaking:** `FromRequest` has been reworked and `RequestParts` has been\n  removed. See axum's changelog for more details ([#1272])\n- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272])\n- **breaking:** `AppendHeaders` now works on any `impl IntoIterator` ([#1495])\n\n[#1272]: https://github.com/tokio-rs/axum/pull/1272\n[#1495]: https://github.com/tokio-rs/axum/pull/1495\n\n<details>\n<summary>0.3.0 Pre-Releases</summary>\n\n# 0.3.0-rc.3 (8. November, 2022)\n\n- **added:** Add `DefaultBodyLimit::max` for changing the default body limit ([#1397])\n- **added:** Add `Error::into_inner` for converting `Error` to `BoxError` without allocating ([#1476])\n- **breaking:** `AppendHeaders` now works on any `impl IntoIterator` ([#1495])\n\n[#1397]: https://github.com/tokio-rs/axum/pull/1397\n[#1476]: https://github.com/tokio-rs/axum/pull/1476\n[#1495]: https://github.com/tokio-rs/axum/pull/1495\n\n# 0.3.0-rc.2 (10. September, 2022)\n\n- **breaking:** Added default limit to how much data `Bytes::from_request` will\n  consume. Previously it would attempt to consume the entire request body\n  without checking its length. This meant if a malicious peer sent an large (or\n  infinite) request body your server might run out of memory and crash.\n\n  The default limit is at 2 MB and can be disabled by adding the new\n  `DefaultBodyLimit::disable()` middleware. See its documentation for more\n  details.\n\n  This also applies to `String` which used `Bytes::from_request` internally.\n\n  ([#1346])\n\n[#1346]: https://github.com/tokio-rs/axum/pull/1346\n\n# 0.3.0-rc.1 (23. August, 2022)\n\n- **breaking:** `FromRequest` has been reworked and `RequestParts` has been\n  removed. See axum's changelog for more details ([#1272])\n- **added:** Added new `FromRequestParts` trait. See axum's changelog for more\n  details ([#1272])\n- **breaking:** `BodyAlreadyExtracted` has been removed ([#1272])\n\n[#1155]: https://github.com/tokio-rs/axum/pull/1155\n[#1272]: https://github.com/tokio-rs/axum/pull/1272\n\n</details>\n\n# 0.2.8 (10. September, 2022)\n\n- **breaking:** Added default limit to how much data `Bytes::from_request` will\n  consume. Previously it would attempt to consume the entire request body\n  without checking its length. This meant if a malicious peer sent an large (or\n  infinite) request body your server might run out of memory and crash.\n\n  The default limit is at 2 MB and can be disabled by adding the new\n  `DefaultBodyLimit::disable()` middleware. See its documentation for more\n  details.\n\n  This also applies to `String` which used `Bytes::from_request` internally.\n\n  ([#1346])\n\n[#1346]: https://github.com/tokio-rs/axum/pull/1346\n\n# 0.2.7 (10. July, 2022)\n\n- **fix:** Fix typos in `RequestParts` docs ([#1147])\n\n[#1147]: https://github.com/tokio-rs/axum/pull/1147\n\n# 0.2.6 (18. June, 2022)\n\n- **change:** axum-core's MSRV is now 1.56 ([#1098])\n\n[#1098]: https://github.com/tokio-rs/axum/pull/1098\n\n# 0.2.5 (08. June, 2022)\n\n- **added:** Automatically handle `http_body::LengthLimitError` in `FailedToBufferBody` and map\n  such errors to `413 Payload Too Large` ([#1048])\n- **fixed:** Use `impl IntoResponse` less in docs ([#1049])\n\n[#1048]: https://github.com/tokio-rs/axum/pull/1048\n[#1049]: https://github.com/tokio-rs/axum/pull/1049\n\n# 0.2.4 (02. May, 2022)\n\n- **added:** Implement `IntoResponse` and `IntoResponseParts` for `http::Extensions` ([#975])\n- **added:** Implement `IntoResponse` for `(http::response::Parts, impl IntoResponse)` ([#950])\n- **added:** Implement `IntoResponse` for `(http::response::Response<()>, impl IntoResponse)` ([#950])\n- **added:** Implement `IntoResponse for (Parts | Request<()>, $(impl IntoResponseParts)+, impl IntoResponse)` ([#980])\n\n[#950]: https://github.com/tokio-rs/axum/pull/950\n[#975]: https://github.com/tokio-rs/axum/pull/975\n[#980]: https://github.com/tokio-rs/axum/pull/980\n\n# 0.2.3 (25. April, 2022)\n\n- **added:** Add `response::ErrorResponse` and `response::Result` for\n  `IntoResponse`-based error handling ([#921])\n\n[#921]: https://github.com/tokio-rs/axum/pull/921\n\n# 0.2.2 (19. April, 2022)\n\n- **added:** Add `AppendHeaders` for appending headers to a response rather than overriding them ([#927])\n\n[#927]: https://github.com/tokio-rs/axum/pull/927\n\n# 0.2.1 (03. April, 2022)\n\n- **added:** Add `RequestParts::extract` which allows applying an extractor as a method call ([#897])\n\n[#897]: https://github.com/tokio-rs/axum/pull/897\n\n# 0.2.0 (31. March, 2022)\n\n- **added:** Add `IntoResponseParts` trait which allows defining custom response\n  types for adding headers or extensions to responses ([#797])\n- **breaking:** Using `HeaderMap` as an extractor will no longer remove the headers and thus\n  they'll still be accessible to other extractors, such as `axum::extract::Json`. Instead\n  `HeaderMap` will clone the headers. You should prefer to use `TypedHeader` to extract only the\n  headers you need ([#698])\n\n  This includes these breaking changes:\n    - `RequestParts::take_headers` has been removed.\n    - `RequestParts::headers` returns `&HeaderMap`.\n    - `RequestParts::headers_mut` returns `&mut HeaderMap`.\n    - `HeadersAlreadyExtracted` has been removed.\n    - The `HeadersAlreadyExtracted` variant has been removed from these rejections:\n        - `RequestAlreadyExtracted`\n        - `RequestPartsAlreadyExtracted`\n    - `<HeaderMap as FromRequest<_>>::Rejection` has been changed to `std::convert::Infallible`.\n- **breaking:** `axum::http::Extensions` is no longer an extractor (ie it\n  doesn't implement `FromRequest`). The `axum::extract::Extension` extractor is\n  _not_ impacted by this and works the same. This change makes it harder to\n  accidentally remove all extensions which would result in confusing errors\n  elsewhere ([#699])\n  This includes these breaking changes:\n    - `RequestParts::take_extensions` has been removed.\n    - `RequestParts::extensions` returns `&Extensions`.\n    - `RequestParts::extensions_mut` returns `&mut Extensions`.\n    - `RequestAlreadyExtracted` has been removed.\n    - `<Request as FromRequest>::Rejection` is now `BodyAlreadyExtracted`.\n    - `<http::request::Parts as FromRequest>::Rejection` is now `Infallible`.\n    - `ExtensionsAlreadyExtracted` has been removed.\n- **breaking:** `RequestParts::body_mut` now returns `&mut Option<B>` so the\n  body can be swapped ([#869])\n\n[#698]: https://github.com/tokio-rs/axum/pull/698\n[#699]: https://github.com/tokio-rs/axum/pull/699\n[#797]: https://github.com/tokio-rs/axum/pull/797\n[#869]: https://github.com/tokio-rs/axum/pull/869\n\n# 0.1.2 (22. February, 2022)\n\n- **added:** Implement `IntoResponse` for `bytes::BytesMut` and `bytes::Chain<T, U>` ([#767])\n\n[#767]: https://github.com/tokio-rs/axum/pull/767\n\n# 0.1.1 (06. December, 2021)\n\n- **added:** `axum_core::response::Response` now exists as a shorthand for writing `Response<BoxBody>` ([#590])\n\n[#590]: https://github.com/tokio-rs/axum/pull/590\n\n# 0.1.0 (02. December, 2021)\n\n- Initial release.\n"
  },
  {
    "path": "axum-core/Cargo.toml",
    "content": "[package]\ncategories = [\"asynchronous\", \"network-programming\", \"web-programming\"]\ndescription = \"Core types and traits for axum\"\nedition = \"2021\"\nrust-version = { workspace = true }\nhomepage = \"https://github.com/tokio-rs/axum\"\nkeywords = [\"http\", \"web\", \"routing\"]\nlicense = \"MIT\"\nname = \"axum-core\"\nreadme = \"README.md\"\nrepository = \"https://github.com/tokio-rs/axum\"\nversion = \"0.5.6\" # remember to bump the version that axum and axum-extra depend on\n\n[package.metadata.cargo_check_external_types]\nallowed_external_types = [\n    # not 1.0\n    \"futures_core::*\",\n    \"tower_layer::*\",\n    # >=1.0\n    \"bytes::*\",\n    \"http::*\",\n    \"http_body::*\",\n]\n\n[package.metadata.cargo-machete]\nignored = [\"tower-http\"] # See __private_docs feature\n\n[package.metadata.docs.rs]\nall-features = true\n\n[features]\ntracing = [\"dep:tracing\"]\n\n# Required for intra-doc links to resolve correctly\n__private_docs = [\"dep:tower-http\"]\n\n[dependencies]\nbytes = \"1.2\"\nfutures-core = \"0.3\"\nhttp = \"1.0.0\"\nhttp-body = \"1.0.0\"\nhttp-body-util = \"0.1.0\"\nmime = \"0.3.16\"\npin-project-lite = \"0.2.7\"\nsync_wrapper = \"1.0.0\"\ntower-layer = \"0.3\"\ntower-service = \"0.3\"\n\n# optional dependencies\ntower-http = { version = \"0.6.0\", optional = true, features = [\"limit\"] }\ntracing = { version = \"0.1.37\", default-features = false, optional = true }\n\n[dev-dependencies]\naxum = { path = \"../axum\", features = [\"__private\"] }\naxum-extra = { path = \"../axum-extra\", features = [\"typed-header\"] }\naxum-macros = { path = \"../axum-macros\", features = [\"__private\"] }\nhyper = \"1.0.0\"\nserde = { version = \"1.0.200\", features = [\"derive\"] }\ntokio = { version = \"1.25.0\", features = [\"macros\"] }\ntower-http = { version = \"0.6.0\", features = [\"limit\"] }\n\n[lints]\nworkspace = true\n"
  },
  {
    "path": "axum-core/README.md",
    "content": "# axum-core\n\n[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum-core/actions/workflows/CI.yml)\n[![Crates.io](https://img.shields.io/crates/v/axum-core)](https://crates.io/crates/axum-core)\n[![Documentation](https://docs.rs/axum-core/badge.svg)](https://docs.rs/axum-core)\n\nCore types and traits for axum.\n\nMore information about this crate can be found in the [crate documentation][docs].\n\n## Safety\n\nThis crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% safe Rust.\n\n## Minimum supported Rust version\n\naxum-core's MSRV is 1.75.\n\n## Getting Help\n\nYou're also welcome to ask in the [Discord channel][chat] or open an [issue]\nwith your question.\n\n## Contributing\n\n🎈 Thanks for your help improving the project! We are so happy to have\nyou! We have a [contributing guide][contributing] to help you get involved in the\n`axum` project.\n\n## License\n\nThis project is licensed under the [MIT license][license].\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `axum` by you, shall be licensed as MIT, without any\nadditional terms or conditions.\n\n[`axum`]: https://crates.io/crates/axum\n[chat]: https://discord.gg/tokio\n[contributing]: /CONTRIBUTING.md\n[docs]: https://docs.rs/axum-core\n[license]: /axum-core/LICENSE\n[issue]: https://github.com/tokio-rs/axum/issues/new\n"
  },
  {
    "path": "axum-core/src/body.rs",
    "content": "//! HTTP body utilities.\n\nuse crate::{BoxError, Error};\nuse bytes::Bytes;\nuse futures_core::{Stream, TryStream};\nuse http_body::{Body as _, Frame};\nuse http_body_util::BodyExt;\nuse pin_project_lite::pin_project;\nuse std::pin::Pin;\nuse std::task::{ready, Context, Poll};\nuse sync_wrapper::SyncWrapper;\n\ntype BoxBody = http_body_util::combinators::UnsyncBoxBody<Bytes, Error>;\n\nfn boxed<B>(body: B) -> BoxBody\nwhere\n    B: http_body::Body<Data = Bytes> + Send + 'static,\n    B::Error: Into<BoxError>,\n{\n    try_downcast(body).unwrap_or_else(|body| body.map_err(Error::new).boxed_unsync())\n}\n\npub(crate) fn try_downcast<T, K>(k: K) -> Result<T, K>\nwhere\n    T: 'static,\n    K: Send + 'static,\n{\n    let mut k = Some(k);\n    if let Some(k) = <dyn std::any::Any>::downcast_mut::<Option<T>>(&mut k) {\n        Ok(k.take().unwrap())\n    } else {\n        Err(k.unwrap())\n    }\n}\n\n/// The body type used in axum requests and responses.\n#[must_use]\n#[derive(Debug)]\npub struct Body(BoxBody);\n\nimpl Body {\n    /// Create a new `Body` that wraps another [`http_body::Body`].\n    pub fn new<B>(body: B) -> Self\n    where\n        B: http_body::Body<Data = Bytes> + Send + 'static,\n        B::Error: Into<BoxError>,\n    {\n        try_downcast(body).unwrap_or_else(|body| Self(boxed(body)))\n    }\n\n    /// Create an empty body.\n    pub fn empty() -> Self {\n        Self::new(http_body_util::Empty::new())\n    }\n\n    /// Create a new `Body` from a [`Stream`].\n    ///\n    /// [`Stream`]: https://docs.rs/futures-core/latest/futures_core/stream/trait.Stream.html\n    pub fn from_stream<S>(stream: S) -> Self\n    where\n        S: TryStream + Send + 'static,\n        S::Ok: Into<Bytes>,\n        S::Error: Into<BoxError>,\n    {\n        Self::new(StreamBody {\n            stream: SyncWrapper::new(stream),\n        })\n    }\n\n    /// Convert the body into a [`Stream`] of data frames.\n    ///\n    /// Non-data frames (such as trailers) will be discarded. Use [`http_body_util::BodyStream`] if\n    /// you need a [`Stream`] of all frame types.\n    ///\n    /// [`http_body_util::BodyStream`]: https://docs.rs/http-body-util/latest/http_body_util/struct.BodyStream.html\n    pub fn into_data_stream(self) -> BodyDataStream {\n        BodyDataStream { inner: self }\n    }\n}\n\nimpl Default for Body {\n    fn default() -> Self {\n        Self::empty()\n    }\n}\n\nimpl From<()> for Body {\n    fn from(_: ()) -> Self {\n        Self::empty()\n    }\n}\n\nmacro_rules! body_from_impl {\n    ($ty:ty) => {\n        impl From<$ty> for Body {\n            fn from(buf: $ty) -> Self {\n                Self::new(http_body_util::Full::from(buf))\n            }\n        }\n    };\n}\n\nbody_from_impl!(&'static [u8]);\nbody_from_impl!(std::borrow::Cow<'static, [u8]>);\nbody_from_impl!(Vec<u8>);\n\nbody_from_impl!(&'static str);\nbody_from_impl!(std::borrow::Cow<'static, str>);\nbody_from_impl!(String);\n\nbody_from_impl!(Bytes);\n\nimpl http_body::Body for Body {\n    type Data = Bytes;\n    type Error = Error;\n\n    #[inline]\n    fn poll_frame(\n        mut self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {\n        Pin::new(&mut self.0).poll_frame(cx)\n    }\n\n    #[inline]\n    fn size_hint(&self) -> http_body::SizeHint {\n        self.0.size_hint()\n    }\n\n    #[inline]\n    fn is_end_stream(&self) -> bool {\n        self.0.is_end_stream()\n    }\n}\n\n/// A stream of data frames.\n///\n/// Created with [`Body::into_data_stream`].\n#[must_use]\n#[derive(Debug)]\npub struct BodyDataStream {\n    inner: Body,\n}\n\nimpl Stream for BodyDataStream {\n    type Item = Result<Bytes, Error>;\n\n    #[inline]\n    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {\n        loop {\n            match ready!(Pin::new(&mut self.inner).poll_frame(cx)?) {\n                Some(frame) => match frame.into_data() {\n                    Ok(data) => return Poll::Ready(Some(Ok(data))),\n                    Err(_frame) => {}\n                },\n                None => return Poll::Ready(None),\n            }\n        }\n    }\n\n    #[inline]\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let size_hint = self.inner.size_hint();\n        let lower = usize::try_from(size_hint.lower()).unwrap_or_default();\n        let upper = size_hint.upper().and_then(|v| usize::try_from(v).ok());\n        (lower, upper)\n    }\n}\n\nimpl http_body::Body for BodyDataStream {\n    type Data = Bytes;\n    type Error = Error;\n\n    #[inline]\n    fn poll_frame(\n        mut self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {\n        Pin::new(&mut self.inner).poll_frame(cx)\n    }\n\n    #[inline]\n    fn is_end_stream(&self) -> bool {\n        self.inner.is_end_stream()\n    }\n\n    #[inline]\n    fn size_hint(&self) -> http_body::SizeHint {\n        self.inner.size_hint()\n    }\n}\n\npin_project! {\n    struct StreamBody<S> {\n        #[pin]\n        stream: SyncWrapper<S>,\n    }\n}\n\nimpl<S> http_body::Body for StreamBody<S>\nwhere\n    S: TryStream,\n    S::Ok: Into<Bytes>,\n    S::Error: Into<BoxError>,\n{\n    type Data = Bytes;\n    type Error = Error;\n\n    fn poll_frame(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {\n        let stream = self.project().stream.get_pin_mut();\n        match ready!(stream.try_poll_next(cx)) {\n            Some(Ok(chunk)) => Poll::Ready(Some(Ok(Frame::data(chunk.into())))),\n            Some(Err(err)) => Poll::Ready(Some(Err(Error::new(err)))),\n            None => Poll::Ready(None),\n        }\n    }\n}\n\n#[test]\nfn test_try_downcast() {\n    assert_eq!(try_downcast::<i32, _>(5_u32), Err(5_u32));\n    assert_eq!(try_downcast::<i32, _>(5_i32), Ok(5_i32));\n}\n"
  },
  {
    "path": "axum-core/src/error.rs",
    "content": "use crate::BoxError;\nuse std::{error::Error as StdError, fmt};\n\n/// Errors that can happen when using axum.\n#[derive(Debug)]\npub struct Error {\n    inner: BoxError,\n}\n\nimpl Error {\n    /// Create a new `Error` from a boxable error.\n    pub fn new(error: impl Into<BoxError>) -> Self {\n        Self {\n            inner: error.into(),\n        }\n    }\n\n    /// Convert an `Error` back into the underlying boxed trait object.\n    #[must_use]\n    pub fn into_inner(self) -> BoxError {\n        self.inner\n    }\n}\n\nimpl fmt::Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.inner.fmt(f)\n    }\n}\n\nimpl StdError for Error {\n    fn source(&self) -> Option<&(dyn StdError + 'static)> {\n        Some(&*self.inner)\n    }\n}\n"
  },
  {
    "path": "axum-core/src/ext_traits/mod.rs",
    "content": "pub(crate) mod request;\npub(crate) mod request_parts;\n\n#[cfg(test)]\nmod tests {\n    use std::convert::Infallible;\n\n    use crate::extract::{FromRef, FromRequestParts};\n    use http::request::Parts;\n\n    #[derive(Debug, Default, Clone, Copy)]\n    pub(crate) struct State<S>(pub(crate) S);\n\n    impl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>\n    where\n        InnerState: FromRef<OuterState>,\n        OuterState: Send + Sync,\n    {\n        type Rejection = Infallible;\n\n        async fn from_request_parts(\n            _parts: &mut Parts,\n            state: &OuterState,\n        ) -> Result<Self, Self::Rejection> {\n            let inner_state = InnerState::from_ref(state);\n            Ok(Self(inner_state))\n        }\n    }\n\n    // some extractor that requires the state, such as `SignedCookieJar`\n    #[allow(dead_code)]\n    pub(crate) struct RequiresState(pub(crate) String);\n\n    impl<S> FromRequestParts<S> for RequiresState\n    where\n        S: Send + Sync,\n        String: FromRef<S>,\n    {\n        type Rejection = Infallible;\n\n        async fn from_request_parts(\n            _parts: &mut Parts,\n            state: &S,\n        ) -> Result<Self, Self::Rejection> {\n            Ok(Self(String::from_ref(state)))\n        }\n    }\n}\n"
  },
  {
    "path": "axum-core/src/ext_traits/request.rs",
    "content": "use crate::body::Body;\nuse crate::extract::{DefaultBodyLimitKind, FromRequest, FromRequestParts, Request};\nuse std::future::Future;\n\nmod sealed {\n    pub trait Sealed {}\n    impl Sealed for http::Request<crate::body::Body> {}\n}\n\n/// Extension trait that adds additional methods to [`Request`].\npub trait RequestExt: sealed::Sealed + Sized {\n    /// Apply an extractor to this `Request`.\n    ///\n    /// This is just a convenience for `E::from_request(req, &())`.\n    ///\n    /// Note this consumes the request. Use [`RequestExt::extract_parts`] if you're not extracting\n    /// the body and don't want to consume the request.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::{Request, FromRequest},\n    ///     body::Body,\n    ///     http::{header::CONTENT_TYPE, StatusCode},\n    ///     response::{IntoResponse, Response},\n    ///     Form, Json, RequestExt,\n    /// };\n    ///\n    /// struct FormOrJson<T>(T);\n    ///\n    /// impl<S, T> FromRequest<S> for FormOrJson<T>\n    /// where\n    ///     Json<T>: FromRequest<()>,\n    ///     Form<T>: FromRequest<()>,\n    ///     T: 'static,\n    ///     S: Send + Sync,\n    /// {\n    ///     type Rejection = Response;\n    ///\n    ///     async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n    ///         let content_type = req\n    ///             .headers()\n    ///             .get(CONTENT_TYPE)\n    ///             .and_then(|value| value.to_str().ok())\n    ///             .ok_or_else(|| StatusCode::BAD_REQUEST.into_response())?;\n    ///\n    ///         if content_type.starts_with(\"application/json\") {\n    ///             let Json(payload) = req\n    ///                 .extract::<Json<T>, _>()\n    ///                 .await\n    ///                 .map_err(|err| err.into_response())?;\n    ///\n    ///             Ok(Self(payload))\n    ///         } else if content_type.starts_with(\"application/x-www-form-urlencoded\") {\n    ///             let Form(payload) = req\n    ///                 .extract::<Form<T>, _>()\n    ///                 .await\n    ///                 .map_err(|err| err.into_response())?;\n    ///\n    ///             Ok(Self(payload))\n    ///         } else {\n    ///             Err(StatusCode::BAD_REQUEST.into_response())\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    fn extract<E, M>(self) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequest<(), M> + 'static,\n        M: 'static;\n\n    /// Apply an extractor that requires some state to this `Request`.\n    ///\n    /// This is just a convenience for `E::from_request(req, state)`.\n    ///\n    /// Note this consumes the request. Use [`RequestExt::extract_parts_with_state`] if you're not\n    /// extracting the body and don't want to consume the request.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     body::Body,\n    ///     extract::{Request, FromRef, FromRequest},\n    ///     RequestExt,\n    /// };\n    ///\n    /// struct MyExtractor {\n    ///     requires_state: RequiresState,\n    /// }\n    ///\n    /// impl<S> FromRequest<S> for MyExtractor\n    /// where\n    ///     String: FromRef<S>,\n    ///     S: Send + Sync,\n    /// {\n    ///     type Rejection = std::convert::Infallible;\n    ///\n    ///     async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n    ///         let requires_state = req.extract_with_state::<RequiresState, _, _>(state).await?;\n    ///\n    ///         Ok(Self { requires_state })\n    ///     }\n    /// }\n    ///\n    /// // some extractor that consumes the request body and requires state\n    /// struct RequiresState { /* ... */ }\n    ///\n    /// impl<S> FromRequest<S> for RequiresState\n    /// where\n    ///     String: FromRef<S>,\n    ///     S: Send + Sync,\n    /// {\n    ///     // ...\n    ///     # type Rejection = std::convert::Infallible;\n    ///     # async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n    ///     #     todo!()\n    ///     # }\n    /// }\n    /// ```\n    fn extract_with_state<E, S, M>(\n        self,\n        state: &S,\n    ) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequest<S, M> + 'static,\n        S: Send + Sync;\n\n    /// Apply a parts extractor to this `Request`.\n    ///\n    /// This is just a convenience for `E::from_request_parts(parts, state)`.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::{Path, Request, FromRequest},\n    ///     response::{IntoResponse, Response},\n    ///     body::Body,\n    ///     Json, RequestExt,\n    /// };\n    /// use axum_extra::{\n    ///     TypedHeader,\n    ///     headers::{authorization::Bearer, Authorization},\n    /// };\n    /// use std::collections::HashMap;\n    ///\n    /// struct MyExtractor<T> {\n    ///     path_params: HashMap<String, String>,\n    ///     payload: T,\n    /// }\n    ///\n    /// impl<S, T> FromRequest<S> for MyExtractor<T>\n    /// where\n    ///     S: Send + Sync,\n    ///     Json<T>: FromRequest<()>,\n    ///     T: 'static,\n    /// {\n    ///     type Rejection = Response;\n    ///\n    ///     async fn from_request(mut req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n    ///         let path_params = req\n    ///             .extract_parts::<Path<_>>()\n    ///             .await\n    ///             .map(|Path(path_params)| path_params)\n    ///             .map_err(|err| err.into_response())?;\n    ///\n    ///         let Json(payload) = req\n    ///             .extract::<Json<T>, _>()\n    ///             .await\n    ///             .map_err(|err| err.into_response())?;\n    ///\n    ///         Ok(Self { path_params, payload })\n    ///     }\n    /// }\n    /// ```\n    fn extract_parts<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequestParts<()> + 'static;\n\n    /// Apply a parts extractor that requires some state to this `Request`.\n    ///\n    /// This is just a convenience for `E::from_request_parts(parts, state)`.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::{Request, FromRef, FromRequest, FromRequestParts},\n    ///     http::request::Parts,\n    ///     response::{IntoResponse, Response},\n    ///     body::Body,\n    ///     Json, RequestExt,\n    /// };\n    ///\n    /// struct MyExtractor<T> {\n    ///     requires_state: RequiresState,\n    ///     payload: T,\n    /// }\n    ///\n    /// impl<S, T> FromRequest<S> for MyExtractor<T>\n    /// where\n    ///     String: FromRef<S>,\n    ///     Json<T>: FromRequest<()>,\n    ///     T: 'static,\n    ///     S: Send + Sync,\n    /// {\n    ///     type Rejection = Response;\n    ///\n    ///     async fn from_request(mut req: Request, state: &S) -> Result<Self, Self::Rejection> {\n    ///         let requires_state = req\n    ///             .extract_parts_with_state::<RequiresState, _>(state)\n    ///             .await\n    ///             .map_err(|err| err.into_response())?;\n    ///\n    ///         let Json(payload) = req\n    ///             .extract::<Json<T>, _>()\n    ///             .await\n    ///             .map_err(|err| err.into_response())?;\n    ///\n    ///         Ok(Self {\n    ///             requires_state,\n    ///             payload,\n    ///         })\n    ///     }\n    /// }\n    ///\n    /// struct RequiresState {}\n    ///\n    /// impl<S> FromRequestParts<S> for RequiresState\n    /// where\n    ///     String: FromRef<S>,\n    ///     S: Send + Sync,\n    /// {\n    ///     // ...\n    ///     # type Rejection = std::convert::Infallible;\n    ///     # async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n    ///     #     todo!()\n    ///     # }\n    /// }\n    /// ```\n    fn extract_parts_with_state<'a, E, S>(\n        &'a mut self,\n        state: &'a S,\n    ) -> impl Future<Output = Result<E, E::Rejection>> + Send + 'a\n    where\n        E: FromRequestParts<S> + 'static,\n        S: Send + Sync;\n\n    /// Apply the [default body limit](crate::extract::DefaultBodyLimit).\n    ///\n    /// If it is disabled, the request is returned as-is.\n    fn with_limited_body(self) -> Request;\n\n    /// Consumes the request, returning the body wrapped in [`http_body_util::Limited`] if a\n    /// [default limit](crate::extract::DefaultBodyLimit) is in place, or not wrapped if the\n    /// default limit is disabled.\n    fn into_limited_body(self) -> Body;\n}\n\nimpl RequestExt for Request {\n    fn extract<E, M>(self) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequest<(), M> + 'static,\n        M: 'static,\n    {\n        self.extract_with_state(&())\n    }\n\n    fn extract_with_state<E, S, M>(\n        self,\n        state: &S,\n    ) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequest<S, M> + 'static,\n        S: Send + Sync,\n    {\n        E::from_request(self, state)\n    }\n\n    fn extract_parts<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequestParts<()> + 'static,\n    {\n        self.extract_parts_with_state(&())\n    }\n\n    async fn extract_parts_with_state<'a, E, S>(\n        &'a mut self,\n        state: &'a S,\n    ) -> Result<E, E::Rejection>\n    where\n        E: FromRequestParts<S> + 'static,\n        S: Send + Sync,\n    {\n        let mut req = Request::new(());\n        *req.version_mut() = self.version();\n        *req.method_mut() = self.method().clone();\n        *req.uri_mut() = self.uri().clone();\n        *req.headers_mut() = std::mem::take(self.headers_mut());\n        *req.extensions_mut() = std::mem::take(self.extensions_mut());\n        let (mut parts, ()) = req.into_parts();\n\n        let result = E::from_request_parts(&mut parts, state).await;\n\n        *self.version_mut() = parts.version;\n        *self.method_mut() = parts.method.clone();\n        *self.uri_mut() = parts.uri.clone();\n        *self.headers_mut() = std::mem::take(&mut parts.headers);\n        *self.extensions_mut() = std::mem::take(&mut parts.extensions);\n\n        result\n    }\n\n    fn with_limited_body(self) -> Request {\n        // update docs in `axum-core/src/extract/default_body_limit.rs` and\n        // `axum/src/docs/extract.md` if this changes\n        const DEFAULT_LIMIT: usize = 2_097_152; // 2 mb\n\n        match self.extensions().get::<DefaultBodyLimitKind>().copied() {\n            Some(DefaultBodyLimitKind::Disable) => self,\n            Some(DefaultBodyLimitKind::Limit(limit)) => {\n                self.map(|b| Body::new(http_body_util::Limited::new(b, limit)))\n            }\n            None => self.map(|b| Body::new(http_body_util::Limited::new(b, DEFAULT_LIMIT))),\n        }\n    }\n\n    fn into_limited_body(self) -> Body {\n        self.with_limited_body().into_body()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::{\n        ext_traits::tests::{RequiresState, State},\n        extract::FromRef,\n    };\n    use http::Method;\n\n    #[tokio::test]\n    async fn extract_without_state() {\n        let req = Request::new(Body::empty());\n\n        let method: Method = req.extract().await.unwrap();\n\n        assert_eq!(method, Method::GET);\n    }\n\n    #[tokio::test]\n    async fn extract_body_without_state() {\n        let req = Request::new(Body::from(\"foobar\"));\n\n        let body: String = req.extract().await.unwrap();\n\n        assert_eq!(body, \"foobar\");\n    }\n\n    #[tokio::test]\n    async fn extract_with_state() {\n        let req = Request::new(Body::empty());\n\n        let state = \"state\".to_owned();\n\n        let State(extracted_state): State<String> = req.extract_with_state(&state).await.unwrap();\n\n        assert_eq!(extracted_state, state);\n    }\n\n    #[tokio::test]\n    async fn extract_parts_without_state() {\n        let mut req = Request::builder()\n            .header(\"x-foo\", \"foo\")\n            .body(Body::empty())\n            .unwrap();\n\n        let method: Method = req.extract_parts().await.unwrap();\n\n        assert_eq!(method, Method::GET);\n        assert_eq!(req.headers()[\"x-foo\"], \"foo\");\n    }\n\n    #[tokio::test]\n    async fn extract_parts_with_state() {\n        let mut req = Request::builder()\n            .header(\"x-foo\", \"foo\")\n            .body(Body::empty())\n            .unwrap();\n\n        let state = \"state\".to_owned();\n\n        let State(extracted_state): State<String> =\n            req.extract_parts_with_state(&state).await.unwrap();\n\n        assert_eq!(extracted_state, state);\n        assert_eq!(req.headers()[\"x-foo\"], \"foo\");\n    }\n\n    // this stuff just needs to compile\n    #[allow(dead_code)]\n    struct WorksForCustomExtractor {\n        method: Method,\n        from_state: String,\n        body: String,\n    }\n\n    impl<S> FromRequest<S> for WorksForCustomExtractor\n    where\n        S: Send + Sync,\n        String: FromRef<S> + FromRequest<()>,\n    {\n        type Rejection = <String as FromRequest<()>>::Rejection;\n\n        async fn from_request(mut req: Request, state: &S) -> Result<Self, Self::Rejection> {\n            let RequiresState(from_state) = req.extract_parts_with_state(state).await.unwrap();\n            let method = req.extract_parts().await.unwrap();\n            let body = req.extract().await?;\n\n            Ok(Self {\n                method,\n                from_state,\n                body,\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "axum-core/src/ext_traits/request_parts.rs",
    "content": "use crate::extract::FromRequestParts;\nuse http::request::Parts;\nuse std::future::Future;\n\nmod sealed {\n    pub trait Sealed {}\n    impl Sealed for http::request::Parts {}\n}\n\n/// Extension trait that adds additional methods to [`Parts`].\npub trait RequestPartsExt: sealed::Sealed + Sized {\n    /// Apply an extractor to this `Parts`.\n    ///\n    /// This is just a convenience for `E::from_request_parts(parts, &())`.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::{Query, Path, FromRequestParts},\n    ///     response::{Response, IntoResponse},\n    ///     http::request::Parts,\n    ///     RequestPartsExt,\n    /// };\n    /// use std::collections::HashMap;\n    ///\n    /// struct MyExtractor {\n    ///     path_params: HashMap<String, String>,\n    ///     query_params: HashMap<String, String>,\n    /// }\n    ///\n    /// impl<S> FromRequestParts<S> for MyExtractor\n    /// where\n    ///     S: Send + Sync,\n    /// {\n    ///     type Rejection = Response;\n    ///\n    ///     async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n    ///         let path_params = parts\n    ///             .extract::<Path<HashMap<String, String>>>()\n    ///             .await\n    ///             .map(|Path(path_params)| path_params)\n    ///             .map_err(|err| err.into_response())?;\n    ///\n    ///         let query_params = parts\n    ///             .extract::<Query<HashMap<String, String>>>()\n    ///             .await\n    ///             .map(|Query(params)| params)\n    ///             .map_err(|err| err.into_response())?;\n    ///\n    ///         Ok(MyExtractor { path_params, query_params })\n    ///     }\n    /// }\n    /// ```\n    fn extract<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequestParts<()> + 'static;\n\n    /// Apply an extractor that requires some state to this `Parts`.\n    ///\n    /// This is just a convenience for `E::from_request_parts(parts, state)`.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::{FromRef, FromRequestParts},\n    ///     response::{Response, IntoResponse},\n    ///     http::request::Parts,\n    ///     RequestPartsExt,\n    /// };\n    ///\n    /// struct MyExtractor {\n    ///     requires_state: RequiresState,\n    /// }\n    ///\n    /// impl<S> FromRequestParts<S> for MyExtractor\n    /// where\n    ///     String: FromRef<S>,\n    ///     S: Send + Sync,\n    /// {\n    ///     type Rejection = std::convert::Infallible;\n    ///\n    ///     async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n    ///         let requires_state = parts\n    ///             .extract_with_state::<RequiresState, _>(state)\n    ///             .await?;\n    ///\n    ///         Ok(MyExtractor { requires_state })\n    ///     }\n    /// }\n    ///\n    /// struct RequiresState { /* ... */ }\n    ///\n    /// // some extractor that requires a `String` in the state\n    /// impl<S> FromRequestParts<S> for RequiresState\n    /// where\n    ///     String: FromRef<S>,\n    ///     S: Send + Sync,\n    /// {\n    ///     // ...\n    ///     # type Rejection = std::convert::Infallible;\n    ///     # async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n    ///     #     unimplemented!()\n    ///     # }\n    /// }\n    /// ```\n    fn extract_with_state<'a, E, S>(\n        &'a mut self,\n        state: &'a S,\n    ) -> impl Future<Output = Result<E, E::Rejection>> + Send + 'a\n    where\n        E: FromRequestParts<S> + 'static,\n        S: Send + Sync;\n}\n\nimpl RequestPartsExt for Parts {\n    fn extract<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + Send\n    where\n        E: FromRequestParts<()> + 'static,\n    {\n        self.extract_with_state(&())\n    }\n\n    fn extract_with_state<'a, E, S>(\n        &'a mut self,\n        state: &'a S,\n    ) -> impl Future<Output = Result<E, E::Rejection>> + Send + 'a\n    where\n        E: FromRequestParts<S> + 'static,\n        S: Send + Sync,\n    {\n        E::from_request_parts(self, state)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::convert::Infallible;\n\n    use super::*;\n    use crate::{\n        ext_traits::tests::{RequiresState, State},\n        extract::FromRef,\n    };\n    use http::{Method, Request};\n\n    #[tokio::test]\n    async fn extract_without_state() {\n        let (mut parts, _) = Request::new(()).into_parts();\n\n        let method: Method = parts.extract().await.unwrap();\n\n        assert_eq!(method, Method::GET);\n    }\n\n    #[tokio::test]\n    async fn extract_with_state() {\n        let (mut parts, _) = Request::new(()).into_parts();\n\n        let state = \"state\".to_owned();\n\n        let State(extracted_state): State<String> = parts\n            .extract_with_state::<State<String>, String>(&state)\n            .await\n            .unwrap();\n\n        assert_eq!(extracted_state, state);\n    }\n\n    // this stuff just needs to compile\n    #[allow(dead_code)]\n    struct WorksForCustomExtractor {\n        method: Method,\n        from_state: String,\n    }\n\n    impl<S> FromRequestParts<S> for WorksForCustomExtractor\n    where\n        S: Send + Sync,\n        String: FromRef<S>,\n    {\n        type Rejection = Infallible;\n\n        async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n            let RequiresState(from_state) = parts.extract_with_state(state).await?;\n            let method = parts.extract().await?;\n\n            Ok(Self { method, from_state })\n        }\n    }\n}\n"
  },
  {
    "path": "axum-core/src/extract/default_body_limit.rs",
    "content": "use self::private::DefaultBodyLimitService;\nuse http::Request;\nuse tower_layer::Layer;\n\n/// Layer for configuring the default request body limit.\n///\n/// For security reasons, [`Bytes`] will, by default, not accept bodies larger than 2MB. This also\n/// applies to extractors that uses [`Bytes`] internally such as `String`, [`Json`], and [`Form`].\n///\n/// This middleware provides ways to configure that.\n///\n/// Note that if an extractor consumes the body directly with [`Body::poll_frame`], or similar, the\n/// default limit is _not_ applied.\n///\n/// # Difference between `DefaultBodyLimit` and [`RequestBodyLimit`]\n///\n/// `DefaultBodyLimit` and [`RequestBodyLimit`] serve similar functions but in different ways.\n///\n/// `DefaultBodyLimit` is local in that it only applies to [`FromRequest`] implementations that\n/// explicitly apply it (or call another extractor that does). You can apply the limit with\n/// [`RequestExt::with_limited_body`] or [`RequestExt::into_limited_body`]\n///\n/// [`RequestBodyLimit`] is applied globally to all requests, regardless of which extractors are\n/// used or how the body is consumed.\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::post,\n///     body::Body,\n///     extract::{Request, DefaultBodyLimit},\n/// };\n///\n/// let app = Router::new()\n///     .route(\"/\", post(|request: Request| async {}))\n///     // change the default limit\n///     .layer(DefaultBodyLimit::max(1024));\n/// # let _: Router = app;\n/// ```\n///\n/// In general using `DefaultBodyLimit` is recommended but if you need to use third party\n/// extractors and want to make sure a limit is also applied there then [`RequestBodyLimit`] should\n/// be used.\n///\n/// # Different limits for different routes\n///\n/// `DefaultBodyLimit` can also be selectively applied to have different limits for different\n/// routes:\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::post,\n///     body::Body,\n///     extract::{Request, DefaultBodyLimit},\n/// };\n///\n/// let app = Router::new()\n///     // this route has a different limit\n///     .route(\"/\", post(|request: Request| async {}).layer(DefaultBodyLimit::max(1024)))\n///     // this route still has the default limit\n///     .route(\"/foo\", post(|request: Request| async {}));\n/// # let _: Router = app;\n/// ```\n///\n/// [`Body::poll_frame`]: http_body::Body::poll_frame\n/// [`Bytes`]: bytes::Bytes\n/// [`Json`]: https://docs.rs/axum/0.8/axum/struct.Json.html\n/// [`Form`]: https://docs.rs/axum/0.8/axum/struct.Form.html\n/// [`FromRequest`]: crate::extract::FromRequest\n/// [`RequestBodyLimit`]: tower_http::limit::RequestBodyLimit\n/// [`RequestExt::with_limited_body`]: crate::RequestExt::with_limited_body\n/// [`RequestExt::into_limited_body`]: crate::RequestExt::into_limited_body\n#[derive(Debug, Clone, Copy)]\n#[must_use]\npub struct DefaultBodyLimit {\n    kind: DefaultBodyLimitKind,\n}\n\n#[derive(Debug, Clone, Copy)]\npub(crate) enum DefaultBodyLimitKind {\n    Disable,\n    Limit(usize),\n}\n\nimpl DefaultBodyLimit {\n    /// Disable the default request body limit.\n    ///\n    /// This must be used to receive bodies larger than the default limit of 2MB using [`Bytes`] or\n    /// an extractor built on it such as `String`, [`Json`], [`Form`].\n    ///\n    /// Note that if you're accepting data from untrusted remotes it is recommend to add your own\n    /// limit such as [`tower_http::limit`].\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     Router,\n    ///     routing::get,\n    ///     body::{Bytes, Body},\n    ///     extract::DefaultBodyLimit,\n    /// };\n    /// use tower_http::limit::RequestBodyLimitLayer;\n    ///\n    /// let app: Router<()> = Router::new()\n    ///     .route(\"/\", get(|body: Bytes| async {}))\n    ///     // Disable the default limit\n    ///     .layer(DefaultBodyLimit::disable())\n    ///     // Set a different limit\n    ///     .layer(RequestBodyLimitLayer::new(10 * 1000 * 1000));\n    /// ```\n    ///\n    /// [`Bytes`]: bytes::Bytes\n    /// [`Json`]: https://docs.rs/axum/0.8/axum/struct.Json.html\n    /// [`Form`]: https://docs.rs/axum/0.8/axum/struct.Form.html\n    pub const fn disable() -> Self {\n        Self {\n            kind: DefaultBodyLimitKind::Disable,\n        }\n    }\n\n    /// Set the default request body limit.\n    ///\n    /// By default the limit of request body sizes that [`Bytes::from_request`] (and other\n    /// extractors built on top of it such as `String`, [`Json`], and [`Form`]) is 2MB. This method\n    /// can be used to change that limit.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///     Router,\n    ///     routing::get,\n    ///     body::{Bytes, Body},\n    ///     extract::DefaultBodyLimit,\n    /// };\n    ///\n    /// let app: Router<()> = Router::new()\n    ///     .route(\"/\", get(|body: Bytes| async {}))\n    ///     // Replace the default of 2MB with 1024 bytes.\n    ///     .layer(DefaultBodyLimit::max(1024));\n    /// ```\n    ///\n    /// [`Bytes::from_request`]: bytes::Bytes\n    /// [`Json`]: https://docs.rs/axum/0.8/axum/struct.Json.html\n    /// [`Form`]: https://docs.rs/axum/0.8/axum/struct.Form.html\n    pub const fn max(limit: usize) -> Self {\n        Self {\n            kind: DefaultBodyLimitKind::Limit(limit),\n        }\n    }\n\n    /// Apply a request body limit to the given request.\n    ///\n    /// This can be used, for example, to modify the default body limit inside a specific\n    /// extractor.\n    ///\n    /// # Example\n    ///\n    /// An extractor similar to [`Bytes`](bytes::Bytes), but limiting the body to 1 KB.\n    ///\n    /// ```\n    /// use axum::{\n    ///     extract::{DefaultBodyLimit, FromRequest, rejection::BytesRejection, Request},\n    ///     body::Bytes,\n    /// };\n    ///\n    /// struct Bytes1KB(Bytes);\n    ///\n    /// impl<S: Sync> FromRequest<S> for Bytes1KB {\n    ///     type Rejection = BytesRejection;\n    ///\n    ///     async fn from_request(mut req: Request, _: &S) -> Result<Self, Self::Rejection> {\n    ///         DefaultBodyLimit::max(1024).apply(&mut req);\n    ///         Ok(Self(Bytes::from_request(req, &()).await?))\n    ///     }\n    /// }\n    /// ```\n    pub fn apply<B>(self, req: &mut Request<B>) {\n        req.extensions_mut().insert(self.kind);\n    }\n}\n\nimpl<S> Layer<S> for DefaultBodyLimit {\n    type Service = DefaultBodyLimitService<S>;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        DefaultBodyLimitService {\n            inner,\n            kind: self.kind,\n        }\n    }\n}\n\nmod private {\n    use super::DefaultBodyLimitKind;\n    use http::Request;\n    use std::task::Context;\n    use tower_service::Service;\n\n    #[derive(Debug, Clone, Copy)]\n    pub struct DefaultBodyLimitService<S> {\n        pub(super) inner: S,\n        pub(super) kind: DefaultBodyLimitKind,\n    }\n\n    impl<B, S> Service<Request<B>> for DefaultBodyLimitService<S>\n    where\n        S: Service<Request<B>>,\n    {\n        type Response = S::Response;\n        type Error = S::Error;\n        type Future = S::Future;\n\n        #[inline]\n        fn poll_ready(&mut self, cx: &mut Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {\n            self.inner.poll_ready(cx)\n        }\n\n        #[inline]\n        fn call(&mut self, mut req: Request<B>) -> Self::Future {\n            req.extensions_mut().insert(self.kind);\n            self.inner.call(req)\n        }\n    }\n}\n"
  },
  {
    "path": "axum-core/src/extract/from_ref.rs",
    "content": "/// Used to do reference-to-value conversions thus not consuming the input value.\n///\n/// This is mainly used with [`State`] to extract \"substates\" from a reference to main application\n/// state.\n///\n/// See [`State`] for more details on how library authors should use this trait.\n///\n/// This trait can be derived using `#[derive(FromRef)]`.\n///\n/// [`State`]: https://docs.rs/axum/0.8/axum/extract/struct.State.html\n// NOTE: This trait is defined in axum-core, even though it is mainly used with `State` which is\n// defined in axum. That allows crate authors to use it when implementing extractors.\npub trait FromRef<T> {\n    /// Converts to this type from a reference to the input type.\n    fn from_ref(input: &T) -> Self;\n}\n\nimpl<T> FromRef<T> for T\nwhere\n    T: Clone,\n{\n    fn from_ref(input: &T) -> Self {\n        input.clone()\n    }\n}\n"
  },
  {
    "path": "axum-core/src/extract/mod.rs",
    "content": "//! Types and traits for extracting data from requests.\n//!\n//! See [`axum::extract`] for more details.\n//!\n//! [`axum::extract`]: https://docs.rs/axum/0.8/axum/extract/index.html\n\nuse crate::{body::Body, response::IntoResponse};\nuse http::request::Parts;\nuse std::convert::Infallible;\nuse std::future::Future;\n\npub mod rejection;\n\nmod default_body_limit;\nmod from_ref;\nmod option;\nmod request_parts;\nmod tuple;\n\npub(crate) use self::default_body_limit::DefaultBodyLimitKind;\npub use self::{\n    default_body_limit::DefaultBodyLimit,\n    from_ref::FromRef,\n    option::{OptionalFromRequest, OptionalFromRequestParts},\n};\n\n/// Type alias for [`http::Request`] whose body type defaults to [`Body`], the most common body\n/// type used with axum.\npub type Request<T = Body> = http::Request<T>;\n\nmod private {\n    #[derive(Debug, Clone, Copy)]\n    pub enum ViaParts {}\n\n    #[derive(Debug, Clone, Copy)]\n    pub enum ViaRequest {}\n}\n\n/// Types that can be created from request parts.\n///\n/// Extractors that implement `FromRequestParts` cannot consume the request body and can thus be\n/// run in any order for handlers.\n///\n/// If your extractor needs to consume the request body then you should implement [`FromRequest`]\n/// and not [`FromRequestParts`].\n///\n/// See [`axum::extract`] for more general docs about extractors.\n///\n/// [`axum::extract`]: https://docs.rs/axum/0.8/axum/extract/index.html\n#[diagnostic::on_unimplemented(\n    note = \"Function argument is not a valid axum extractor. \\nSee `https://docs.rs/axum/0.8/axum/extract/index.html` for details\"\n)]\npub trait FromRequestParts<S>: Sized {\n    /// If the extractor fails it'll use this \"rejection\" type. A rejection is\n    /// a kind of error that can be converted into a response.\n    type Rejection: IntoResponse;\n\n    /// Perform the extraction.\n    fn from_request_parts(\n        parts: &mut Parts,\n        state: &S,\n    ) -> impl Future<Output = Result<Self, Self::Rejection>> + Send;\n}\n\n/// Types that can be created from requests.\n///\n/// Extractors that implement `FromRequest` can consume the request body and can thus only be run\n/// once for handlers.\n///\n/// If your extractor doesn't need to consume the request body then you should implement\n/// [`FromRequestParts`] and not [`FromRequest`].\n///\n/// See [`axum::extract`] for more general docs about extractors.\n///\n/// [`axum::extract`]: https://docs.rs/axum/0.8/axum/extract/index.html\n#[diagnostic::on_unimplemented(\n    note = \"Function argument is not a valid axum extractor. \\nSee `https://docs.rs/axum/0.8/axum/extract/index.html` for details\"\n)]\npub trait FromRequest<S, M = private::ViaRequest>: Sized {\n    /// If the extractor fails it'll use this \"rejection\" type. A rejection is\n    /// a kind of error that can be converted into a response.\n    type Rejection: IntoResponse;\n\n    /// Perform the extraction.\n    fn from_request(\n        req: Request,\n        state: &S,\n    ) -> impl Future<Output = Result<Self, Self::Rejection>> + Send;\n}\n\nimpl<S, T> FromRequest<S, private::ViaParts> for T\nwhere\n    S: Send + Sync,\n    T: FromRequestParts<S>,\n{\n    type Rejection = <Self as FromRequestParts<S>>::Rejection;\n\n    fn from_request(\n        req: Request,\n        state: &S,\n    ) -> impl Future<Output = Result<Self, Self::Rejection>> {\n        let (mut parts, _) = req.into_parts();\n        async move { Self::from_request_parts(&mut parts, state).await }\n    }\n}\n\nimpl<S, T> FromRequestParts<S> for Result<T, T::Rejection>\nwhere\n    T: FromRequestParts<S>,\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        Ok(T::from_request_parts(parts, state).await)\n    }\n}\n\nimpl<S, T> FromRequest<S> for Result<T, T::Rejection>\nwhere\n    T: FromRequest<S>,\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        Ok(T::from_request(req, state).await)\n    }\n}\n"
  },
  {
    "path": "axum-core/src/extract/option.rs",
    "content": "use std::future::Future;\n\nuse http::request::Parts;\n\nuse crate::response::IntoResponse;\n\nuse super::{private, FromRequest, FromRequestParts, Request};\n\n/// Customize the behavior of `Option<Self>` as a [`FromRequestParts`]\n/// extractor.\npub trait OptionalFromRequestParts<S>: Sized {\n    /// If the extractor fails, it will use this \"rejection\" type.\n    ///\n    /// A rejection is a kind of error that can be converted into a response.\n    type Rejection: IntoResponse;\n\n    /// Perform the extraction.\n    fn from_request_parts(\n        parts: &mut Parts,\n        state: &S,\n    ) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;\n}\n\n/// Customize the behavior of `Option<Self>` as a [`FromRequest`] extractor.\npub trait OptionalFromRequest<S, M = private::ViaRequest>: Sized {\n    /// If the extractor fails, it will use this \"rejection\" type.\n    ///\n    /// A rejection is a kind of error that can be converted into a response.\n    type Rejection: IntoResponse;\n\n    /// Perform the extraction.\n    fn from_request(\n        req: Request,\n        state: &S,\n    ) -> impl Future<Output = Result<Option<Self>, Self::Rejection>> + Send;\n}\n\n// Compiler hint just says that there is an impl for Option<T>, not mentioning\n// the bounds, which is not very helpful.\n#[diagnostic::do_not_recommend]\nimpl<S, T> FromRequestParts<S> for Option<T>\nwhere\n    T: OptionalFromRequestParts<S>,\n    S: Send + Sync,\n{\n    type Rejection = T::Rejection;\n\n    #[allow(clippy::use_self)]\n    fn from_request_parts(\n        parts: &mut Parts,\n        state: &S,\n    ) -> impl Future<Output = Result<Option<T>, Self::Rejection>> {\n        T::from_request_parts(parts, state)\n    }\n}\n\n#[diagnostic::do_not_recommend]\nimpl<S, T> FromRequest<S> for Option<T>\nwhere\n    T: OptionalFromRequest<S>,\n    S: Send + Sync,\n{\n    type Rejection = T::Rejection;\n\n    #[allow(clippy::use_self)]\n    async fn from_request(req: Request, state: &S) -> Result<Option<T>, Self::Rejection> {\n        T::from_request(req, state).await\n    }\n}\n"
  },
  {
    "path": "axum-core/src/extract/rejection.rs",
    "content": "//! Rejection response types.\n\nuse crate::__composite_rejection as composite_rejection;\nuse crate::__define_rejection as define_rejection;\n\nuse crate::{BoxError, Error};\n\ncomposite_rejection! {\n    /// Rejection type for extractors that buffer the request body. Used if the\n    /// request body cannot be buffered due to an error.\n    pub enum FailedToBufferBody {\n        LengthLimitError,\n        UnknownBodyError,\n    }\n}\n\nimpl FailedToBufferBody {\n    pub(crate) fn from_err<E>(err: E) -> Self\n    where\n        E: Into<BoxError>,\n    {\n        // two layers of boxes here because `with_limited_body`\n        // wraps the `http_body_util::Limited` in a `axum_core::Body`\n        // which also wraps the error type\n        let box_error = match err.into().downcast::<Error>() {\n            Ok(err) => err.into_inner(),\n            Err(err) => err,\n        };\n        let box_error = match box_error.downcast::<Error>() {\n            Ok(err) => err.into_inner(),\n            Err(err) => err,\n        };\n        match box_error.downcast::<http_body_util::LengthLimitError>() {\n            Ok(err) => Self::LengthLimitError(LengthLimitError::from_err(err)),\n            Err(err) => Self::UnknownBodyError(UnknownBodyError::from_err(err)),\n        }\n    }\n}\n\ndefine_rejection! {\n    #[status = PAYLOAD_TOO_LARGE]\n    #[body = \"Failed to buffer the request body\"]\n    /// Encountered some other error when buffering the body.\n    ///\n    /// This can _only_ happen when you're using [`tower_http::limit::RequestBodyLimitLayer`] or\n    /// otherwise wrapping request bodies in [`http_body_util::Limited`].\n    pub struct LengthLimitError(Error);\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Failed to buffer the request body\"]\n    /// Encountered an unknown error when buffering the body.\n    pub struct UnknownBodyError(Error);\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Request body didn't contain valid UTF-8\"]\n    /// Rejection type used when buffering the request into a [`String`] if the\n    /// body doesn't contain valid UTF-8.\n    pub struct InvalidUtf8(Error);\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Bytes`](bytes::Bytes).\n    ///\n    /// Contains one variant for each way the [`Bytes`](bytes::Bytes) extractor\n    /// can fail.\n    pub enum BytesRejection {\n        FailedToBufferBody,\n    }\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`String`].\n    ///\n    /// Contains one variant for each way the [`String`] extractor can fail.\n    pub enum StringRejection {\n        FailedToBufferBody,\n        InvalidUtf8,\n    }\n}\n"
  },
  {
    "path": "axum-core/src/extract/request_parts.rs",
    "content": "use super::{rejection::*, FromRequest, FromRequestParts, Request};\nuse crate::{body::Body, RequestExt};\nuse bytes::{BufMut, Bytes, BytesMut};\nuse http::{request::Parts, Extensions, HeaderMap, Method, Uri, Version};\nuse http_body_util::BodyExt;\nuse std::convert::Infallible;\n\nimpl<S> FromRequest<S> for Request\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {\n        Ok(req)\n    }\n}\n\nimpl<S> FromRequestParts<S> for Method\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {\n        Ok(parts.method.clone())\n    }\n}\n\nimpl<S> FromRequestParts<S> for Uri\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {\n        Ok(parts.uri.clone())\n    }\n}\n\nimpl<S> FromRequestParts<S> for Version\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {\n        Ok(parts.version)\n    }\n}\n\n/// Clone the headers from the request.\n///\n/// Prefer using [`TypedHeader`] to extract only the headers you need.\n///\n/// [`TypedHeader`]: https://docs.rs/axum-extra/0.10/axum_extra/struct.TypedHeader.html\nimpl<S> FromRequestParts<S> for HeaderMap\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {\n        Ok(parts.headers.clone())\n    }\n}\n\n#[diagnostic::do_not_recommend] // pretty niche impl\nimpl<S> FromRequest<S> for BytesMut\nwhere\n    S: Send + Sync,\n{\n    type Rejection = BytesRejection;\n\n    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {\n        let mut body = req.into_limited_body();\n        #[allow(clippy::use_self)]\n        let mut bytes = BytesMut::new();\n        body_to_bytes_mut(&mut body, &mut bytes).await?;\n        Ok(bytes)\n    }\n}\n\nasync fn body_to_bytes_mut(body: &mut Body, bytes: &mut BytesMut) -> Result<(), BytesRejection> {\n    while let Some(frame) = body\n        .frame()\n        .await\n        .transpose()\n        .map_err(FailedToBufferBody::from_err)?\n    {\n        let Ok(data) = frame.into_data() else {\n            return Ok(());\n        };\n        bytes.put(data);\n    }\n\n    Ok(())\n}\n\nimpl<S> FromRequest<S> for Bytes\nwhere\n    S: Send + Sync,\n{\n    type Rejection = BytesRejection;\n\n    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {\n        let bytes = req\n            .into_limited_body()\n            .collect()\n            .await\n            .map_err(FailedToBufferBody::from_err)?\n            .to_bytes();\n\n        Ok(bytes)\n    }\n}\n\nimpl<S> FromRequest<S> for String\nwhere\n    S: Send + Sync,\n{\n    type Rejection = StringRejection;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        let bytes = Bytes::from_request(req, state)\n            .await\n            .map_err(|err| match err {\n                BytesRejection::FailedToBufferBody(inner) => {\n                    StringRejection::FailedToBufferBody(inner)\n                }\n            })?;\n\n        #[allow(clippy::use_self)]\n        let string = String::from_utf8(bytes.into()).map_err(InvalidUtf8::from_err)?;\n\n        Ok(string)\n    }\n}\n\n#[diagnostic::do_not_recommend] // pretty niche impl\nimpl<S> FromRequestParts<S> for Parts\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        Ok(parts.clone())\n    }\n}\n\n#[diagnostic::do_not_recommend] // pretty niche impl\nimpl<S> FromRequestParts<S> for Extensions\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        Ok(parts.extensions.clone())\n    }\n}\n\nimpl<S> FromRequest<S> for Body\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {\n        Ok(req.into_body())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use axum::{extract::Extension, routing::get, test_helpers::*, Router};\n    use http::{Method, StatusCode};\n\n    #[crate::test]\n    async fn extract_request_parts() {\n        #[derive(Clone)]\n        struct Ext;\n\n        async fn handler(parts: http::request::Parts) {\n            assert_eq!(parts.method, Method::GET);\n            assert_eq!(parts.uri, \"/\");\n            assert_eq!(parts.version, http::Version::HTTP_11);\n            assert_eq!(parts.headers[\"x-foo\"], \"123\");\n            parts.extensions.get::<Ext>().unwrap();\n        }\n\n        let client = TestClient::new(Router::new().route(\"/\", get(handler)).layer(Extension(Ext)));\n\n        let res = client.get(\"/\").header(\"x-foo\", \"123\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n}\n"
  },
  {
    "path": "axum-core/src/extract/tuple.rs",
    "content": "use super::{FromRequest, FromRequestParts, Request};\nuse crate::response::{IntoResponse, Response};\nuse http::request::Parts;\nuse std::{convert::Infallible, future::Future};\n\n#[diagnostic::do_not_recommend]\nimpl<S> FromRequestParts<S> for ()\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(_: &mut Parts, _: &S) -> Result<(), Self::Rejection> {\n        Ok(())\n    }\n}\n\nmacro_rules! impl_from_request {\n    (\n        [$($ty:ident),*], $last:ident\n    ) => {\n        #[diagnostic::do_not_recommend]\n        #[allow(non_snake_case, unused_mut, unused_variables)]\n        impl<S, $($ty,)* $last> FromRequestParts<S> for ($($ty,)* $last,)\n        where\n            $( $ty: FromRequestParts<S> + Send, )*\n            $last: FromRequestParts<S> + Send,\n            S: Send + Sync,\n        {\n            type Rejection = Response;\n\n            async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n                $(\n                    let $ty = $ty::from_request_parts(parts, state)\n                        .await\n                        .map_err(|err| err.into_response())?;\n                )*\n                let $last = $last::from_request_parts(parts, state)\n                    .await\n                    .map_err(|err| err.into_response())?;\n\n                Ok(($($ty,)* $last,))\n            }\n        }\n\n        // This impl must not be generic over M, otherwise it would conflict with the blanket\n        // implementation of `FromRequest<S, Mut>` for `T: FromRequestParts<S>`.\n        #[diagnostic::do_not_recommend]\n        #[allow(non_snake_case, unused_mut, unused_variables)]\n        impl<S, $($ty,)* $last> FromRequest<S> for ($($ty,)* $last,)\n        where\n            $( $ty: FromRequestParts<S> + Send, )*\n            $last: FromRequest<S> + Send,\n            S: Send + Sync,\n        {\n            type Rejection = Response;\n\n            fn from_request(req: Request, state: &S) -> impl Future<Output = Result<Self, Self::Rejection>> {\n                let (mut parts, body) = req.into_parts();\n\n                async move {\n                    $(\n                        let $ty = $ty::from_request_parts(&mut parts, state).await.map_err(|err| err.into_response())?;\n                    )*\n\n                    let req = Request::from_parts(parts, body);\n\n                    let $last = $last::from_request(req, state).await.map_err(|err| err.into_response())?;\n\n                    Ok(($($ty,)* $last,))\n                }\n            }\n        }\n    };\n}\n\nall_the_tuples!(impl_from_request);\n\n#[cfg(test)]\nmod tests {\n    use bytes::Bytes;\n    use http::Method;\n\n    use crate::extract::{FromRequest, FromRequestParts};\n\n    fn assert_from_request<M, T>()\n    where\n        T: FromRequest<(), M>,\n    {\n    }\n\n    fn assert_from_request_parts<T: FromRequestParts<()>>() {}\n\n    #[test]\n    fn unit() {\n        assert_from_request_parts::<()>();\n        assert_from_request::<_, ()>();\n    }\n\n    #[test]\n    fn tuple_of_one() {\n        assert_from_request_parts::<(Method,)>();\n        assert_from_request::<_, (Method,)>();\n        assert_from_request::<_, (Bytes,)>();\n    }\n\n    #[test]\n    fn tuple_of_two() {\n        assert_from_request_parts::<((), ())>();\n        assert_from_request::<_, ((), ())>();\n        assert_from_request::<_, (Method, Bytes)>();\n    }\n\n    #[test]\n    fn nested_tuple() {\n        assert_from_request_parts::<(((Method,),),)>();\n        assert_from_request::<_, ((((Bytes,),),),)>();\n    }\n}\n"
  },
  {
    "path": "axum-core/src/lib.rs",
    "content": "//! Core types and traits for [`axum`].\n//!\n//! Libraries authors that want to provide [`FromRequest`] or [`IntoResponse`] implementations\n//! should depend on the [`axum-core`] crate, instead of `axum` if possible.\n//!\n//! [`FromRequest`]: crate::extract::FromRequest\n//! [`IntoResponse`]: crate::response::IntoResponse\n//! [`axum`]: https://crates.io/crates/axum\n//! [`axum-core`]: http://crates.io/crates/axum-core\n\n#![cfg_attr(test, allow(clippy::float_cmp))]\n#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]\n\n#[macro_use]\npub(crate) mod macros;\n#[doc(hidden)] // macro helpers\npub mod __private {\n    #[cfg(feature = \"tracing\")]\n    pub use tracing;\n}\n\nmod error;\nmod ext_traits;\npub use self::error::Error;\n\npub mod body;\npub mod extract;\npub mod response;\n\n/// Alias for a type-erased error type.\npub type BoxError = Box<dyn std::error::Error + Send + Sync>;\n\npub use self::ext_traits::{request::RequestExt, request_parts::RequestPartsExt};\n\n#[cfg(test)]\nuse axum_macros::__private_axum_test as test;\n"
  },
  {
    "path": "axum-core/src/macros.rs",
    "content": "/// Private API.\n#[cfg(feature = \"tracing\")]\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __log_rejection {\n    (\n        rejection_type = $ty:ident,\n        body_text = $body_text:expr,\n        status = $status:expr,\n    ) => {\n        {\n            $crate::__private::tracing::event!(\n                target: \"axum::rejection\",\n                $crate::__private::tracing::Level::TRACE,\n                status = $status.as_u16(),\n                body = $body_text,\n                rejection_type = ::std::any::type_name::<$ty>(),\n                \"rejecting request\",\n            );\n        }\n    };\n}\n\n#[cfg(not(feature = \"tracing\"))]\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __log_rejection {\n    (\n        rejection_type = $ty:ident,\n        body_text = $body_text:expr,\n        status = $status:expr,\n    ) => {};\n}\n\n/// Private API.\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __define_rejection {\n    (\n        #[status = $status:ident]\n        #[body = $body:literal]\n        $(#[$m:meta])*\n        pub struct $name:ident;\n    ) => {\n        $(#[$m])*\n        #[derive(Debug)]\n        #[non_exhaustive]\n        pub struct $name;\n\n        impl $name {\n            /// Get the response body text used for this rejection.\n            pub fn body_text(&self) -> String {\n                self.to_string()\n            }\n\n            /// Get the status code used for this rejection.\n            pub fn status(&self) -> http::StatusCode {\n                http::StatusCode::$status\n            }\n        }\n\n        impl $crate::response::IntoResponse for $name {\n            fn into_response(self) -> $crate::response::Response {\n                let status = self.status();\n\n                $crate::__log_rejection!(\n                    rejection_type = $name,\n                    body_text = $body,\n                    status = status,\n                );\n                (status, $body).into_response()\n            }\n        }\n\n        impl std::fmt::Display for $name {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                write!(f, \"{}\", $body)\n            }\n        }\n\n        impl std::error::Error for $name {}\n\n        impl Default for $name {\n            fn default() -> Self {\n                Self\n            }\n        }\n    };\n\n    (\n        #[status = $status:ident]\n        #[body = $body:literal]\n        $(#[$m:meta])*\n        pub struct $name:ident (Error);\n    ) => {\n        $(#[$m])*\n        #[derive(Debug)]\n        pub struct $name(pub(crate) $crate::Error);\n\n        impl $name {\n            pub(crate) fn from_err<E>(err: E) -> Self\n            where\n                E: Into<$crate::BoxError>,\n            {\n                Self($crate::Error::new(err))\n            }\n\n            /// Get the response body text used for this rejection.\n            #[must_use]\n            pub fn body_text(&self) -> String {\n                self.to_string()\n            }\n\n            /// Get the status code used for this rejection.\n            #[must_use]\n            pub fn status(&self) -> http::StatusCode {\n                http::StatusCode::$status\n            }\n        }\n\n        impl $crate::response::IntoResponse for $name {\n            fn into_response(self) -> $crate::response::Response {\n                let status = self.status();\n                let body_text = self.body_text();\n\n                $crate::__log_rejection!(\n                    rejection_type = $name,\n                    body_text = body_text,\n                    status = status,\n                );\n                (status, body_text).into_response()\n            }\n        }\n\n        impl std::fmt::Display for $name {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                f.write_str($body)?;\n                f.write_str(\": \")?;\n                self.0.fmt(f)\n            }\n        }\n\n        impl std::error::Error for $name {\n            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n                Some(&self.0)\n            }\n        }\n    };\n}\n\n/// Private API.\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __composite_rejection {\n    (\n        $(#[$m:meta])*\n        pub enum $name:ident {\n            $($variant:ident),+\n            $(,)?\n        }\n    ) => {\n        $(#[$m])*\n        #[derive(Debug)]\n        #[non_exhaustive]\n        pub enum $name {\n            $(\n                #[allow(missing_docs)]\n                $variant($variant)\n            ),+\n        }\n\n        impl $crate::response::IntoResponse for $name {\n            fn into_response(self) -> $crate::response::Response {\n                match self {\n                    $(\n                        Self::$variant(inner) => inner.into_response(),\n                    )+\n                }\n            }\n        }\n\n        impl $name {\n            /// Get the response body text used for this rejection.\n            #[must_use]\n            pub fn body_text(&self) -> String {\n                match self {\n                    $(\n                        Self::$variant(inner) => inner.body_text(),\n                    )+\n                }\n            }\n\n            /// Get the status code used for this rejection.\n            #[must_use]\n            pub fn status(&self) -> http::StatusCode {\n                match self {\n                    $(\n                        Self::$variant(inner) => inner.status(),\n                    )+\n                }\n            }\n        }\n\n        $(\n            impl From<$variant> for $name {\n                fn from(inner: $variant) -> Self {\n                    Self::$variant(inner)\n                }\n            }\n        )+\n\n        impl std::fmt::Display for $name {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                match self {\n                    $(\n                        Self::$variant(inner) => write!(f, \"{inner}\"),\n                    )+\n                }\n            }\n        }\n\n        impl std::error::Error for $name {\n            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n                match self {\n                    $(\n                        Self::$variant(inner) => inner.source(),\n                    )+\n                }\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmacro_rules! all_the_tuples {\n    ($name:ident) => {\n        $name!([], T1);\n        $name!([T1], T2);\n        $name!([T1, T2], T3);\n        $name!([T1, T2, T3], T4);\n        $name!([T1, T2, T3, T4], T5);\n        $name!([T1, T2, T3, T4, T5], T6);\n        $name!([T1, T2, T3, T4, T5, T6], T7);\n        $name!([T1, T2, T3, T4, T5, T6, T7], T8);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8], T9);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9], T10);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], T11);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], T12);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], T13);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], T14);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], T15);\n        $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], T16);\n    };\n}\n\nmacro_rules! all_the_tuples_no_last_special_case {\n    ($name:ident) => {\n        $name!(T1);\n        $name!(T1, T2);\n        $name!(T1, T2, T3);\n        $name!(T1, T2, T3, T4);\n        $name!(T1, T2, T3, T4, T5);\n        $name!(T1, T2, T3, T4, T5, T6);\n        $name!(T1, T2, T3, T4, T5, T6, T7);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);\n        $name!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);\n    };\n}\n\n/// Private API.\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! __impl_deref {\n    ($ident:ident) => {\n        impl<T> std::ops::Deref for $ident<T> {\n            type Target = T;\n\n            #[inline]\n            fn deref(&self) -> &Self::Target {\n                &self.0\n            }\n        }\n\n        impl<T> std::ops::DerefMut for $ident<T> {\n            #[inline]\n            fn deref_mut(&mut self) -> &mut Self::Target {\n                &mut self.0\n            }\n        }\n    };\n\n    ($ident:ident: $ty:ty) => {\n        impl std::ops::Deref for $ident {\n            type Target = $ty;\n\n            #[inline]\n            fn deref(&self) -> &Self::Target {\n                &self.0\n            }\n        }\n\n        impl std::ops::DerefMut for $ident {\n            #[inline]\n            fn deref_mut(&mut self) -> &mut Self::Target {\n                &mut self.0\n            }\n        }\n    };\n}\n\n#[cfg(test)]\nmod composite_rejection_tests {\n    use self::defs::*;\n    use crate::Error;\n    use std::error::Error as _;\n\n    #[allow(dead_code, unreachable_pub)]\n    mod defs {\n        __define_rejection! {\n            #[status = BAD_REQUEST]\n            #[body = \"error message 1\"]\n            pub struct Inner1;\n        }\n        __define_rejection! {\n            #[status = BAD_REQUEST]\n            #[body = \"error message 2\"]\n            pub struct Inner2(Error);\n        }\n        __composite_rejection! {\n            pub enum Outer { Inner1, Inner2 }\n        }\n    }\n\n    /// The implementation of `.source()` on `Outer` should defer straight to the implementation\n    /// on its inner type instead of returning the inner type itself, because the `Display`\n    /// implementation on `Outer` already forwards to the inner type and so it would result in two\n    /// errors in the chain `Display`ing the same thing.\n    #[test]\n    fn source_gives_inner_source() {\n        let rejection = Outer::Inner1(Inner1);\n        assert!(rejection.source().is_none());\n\n        let msg = \"hello world\";\n        let rejection = Outer::Inner2(Inner2(Error::new(msg)));\n        assert_eq!(rejection.source().unwrap().to_string(), msg);\n    }\n}\n"
  },
  {
    "path": "axum-core/src/response/append_headers.rs",
    "content": "use super::{IntoResponse, IntoResponseParts, Response, ResponseParts, TryIntoHeaderError};\nuse http::header::{HeaderName, HeaderValue};\nuse std::fmt;\n\n/// Append headers to a response.\n///\n/// Returning something like `[(\"content-type\", \"foo=bar\")]` from a handler will override any\n/// existing `content-type` headers. If instead you want to append headers, use `AppendHeaders`:\n///\n/// ```rust\n/// use axum::{\n///     response::{AppendHeaders, IntoResponse},\n///     http::header::SET_COOKIE,\n/// };\n///\n/// async fn handler() -> impl IntoResponse {\n///     // something that sets the `set-cookie` header\n///     let set_some_cookies = /* ... */\n///     # axum::http::HeaderMap::new();\n///\n///     (\n///         set_some_cookies,\n///         // append two `set-cookie` headers to the response\n///         // without overriding the ones added by `set_some_cookies`\n///         AppendHeaders([\n///             (SET_COOKIE, \"foo=bar\"),\n///             (SET_COOKIE, \"baz=qux\"),\n///         ])\n///     )\n/// }\n/// ```\n#[derive(Debug, Clone, Copy)]\n#[must_use]\npub struct AppendHeaders<I>(pub I);\n\nimpl<I, K, V> IntoResponse for AppendHeaders<I>\nwhere\n    I: IntoIterator<Item = (K, V)>,\n    K: TryInto<HeaderName>,\n    K::Error: fmt::Display,\n    V: TryInto<HeaderValue>,\n    V::Error: fmt::Display,\n{\n    fn into_response(self) -> Response {\n        (self, ()).into_response()\n    }\n}\n\nimpl<I, K, V> IntoResponseParts for AppendHeaders<I>\nwhere\n    I: IntoIterator<Item = (K, V)>,\n    K: TryInto<HeaderName>,\n    K::Error: fmt::Display,\n    V: TryInto<HeaderValue>,\n    V::Error: fmt::Display,\n{\n    type Error = TryIntoHeaderError<K::Error, V::Error>;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        for (key, value) in self.0 {\n            let key = key.try_into().map_err(TryIntoHeaderError::key)?;\n            let value = value.try_into().map_err(TryIntoHeaderError::value)?;\n            res.headers_mut().append(key, value);\n        }\n\n        Ok(res)\n    }\n}\n"
  },
  {
    "path": "axum-core/src/response/into_response.rs",
    "content": "use super::{ForceStatusCode, IntoResponseFailed, IntoResponseParts, Response, ResponseParts};\nuse crate::{body::Body, BoxError};\nuse bytes::{buf::Chain, Buf, Bytes, BytesMut};\nuse http::{\n    header::{self, HeaderMap, HeaderName, HeaderValue},\n    Extensions, StatusCode,\n};\nuse http_body::{Frame, SizeHint};\nuse std::{\n    borrow::Cow,\n    convert::Infallible,\n    fmt,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\n/// Trait for generating responses.\n///\n/// Types that implement `IntoResponse` can be returned from handlers.\n///\n/// # Implementing `IntoResponse`\n///\n/// You generally shouldn't have to implement `IntoResponse` manually, as axum\n/// provides implementations for many common types.\n///\n/// However it might be necessary if you have a custom error type that you want\n/// to return from handlers:\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     body::{self, Bytes},\n///     routing::get,\n///     http::StatusCode,\n///     response::{IntoResponse, Response},\n/// };\n///\n/// enum MyError {\n///     SomethingWentWrong,\n///     SomethingElseWentWrong,\n/// }\n///\n/// impl IntoResponse for MyError {\n///     fn into_response(self) -> Response {\n///         let body = match self {\n///             MyError::SomethingWentWrong => \"something went wrong\",\n///             MyError::SomethingElseWentWrong => \"something else went wrong\",\n///         };\n///\n///         // it's often easiest to implement `IntoResponse` by calling other implementations\n///         (StatusCode::INTERNAL_SERVER_ERROR, body).into_response()\n///     }\n/// }\n///\n/// // `Result<impl IntoResponse, MyError>` can now be returned from handlers\n/// let app = Router::new().route(\"/\", get(handler));\n///\n/// async fn handler() -> Result<(), MyError> {\n///     Err(MyError::SomethingWentWrong)\n/// }\n/// # let _: Router = app;\n/// ```\n///\n/// Or if you have a custom body type you'll also need to implement\n/// `IntoResponse` for it:\n///\n/// ```rust\n/// use axum::{\n///     body,\n///     routing::get,\n///     response::{IntoResponse, Response},\n///     body::Body,\n///     Router,\n/// };\n/// use http::HeaderMap;\n/// use bytes::Bytes;\n/// use http_body::Frame;\n/// use std::{\n///     convert::Infallible,\n///     task::{Poll, Context},\n///     pin::Pin,\n/// };\n///\n/// struct MyBody;\n///\n/// // First implement `Body` for `MyBody`. This could for example use\n/// // some custom streaming protocol.\n/// impl http_body::Body for MyBody {\n///     type Data = Bytes;\n///     type Error = Infallible;\n///\n///     fn poll_frame(\n///         self: Pin<&mut Self>,\n///         cx: &mut Context<'_>,\n///     ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {\n///         # unimplemented!()\n///         // ...\n///     }\n/// }\n///\n/// // Now we can implement `IntoResponse` directly for `MyBody`\n/// impl IntoResponse for MyBody {\n///     fn into_response(self) -> Response {\n///         Response::new(Body::new(self))\n///     }\n/// }\n///\n/// // `MyBody` can now be returned from handlers.\n/// let app = Router::new().route(\"/\", get(|| async { MyBody }));\n/// # let _: Router = app;\n/// ```\npub trait IntoResponse {\n    /// Create a response.\n    #[must_use]\n    fn into_response(self) -> Response;\n}\n\nimpl IntoResponse for StatusCode {\n    fn into_response(self) -> Response {\n        let mut res = ().into_response();\n        *res.status_mut() = self;\n        res\n    }\n}\n\nimpl IntoResponse for () {\n    fn into_response(self) -> Response {\n        Body::empty().into_response()\n    }\n}\n\nimpl IntoResponse for Infallible {\n    fn into_response(self) -> Response {\n        match self {}\n    }\n}\n\nimpl<T, E> IntoResponse for Result<T, E>\nwhere\n    T: IntoResponse,\n    E: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        match self {\n            Ok(value) => value.into_response(),\n            Err(err) => err.into_response(),\n        }\n    }\n}\n\nimpl<B> IntoResponse for Response<B>\nwhere\n    B: http_body::Body<Data = Bytes> + Send + 'static,\n    B::Error: Into<BoxError>,\n{\n    fn into_response(self) -> Response {\n        self.map(Body::new)\n    }\n}\n\nimpl IntoResponse for http::response::Parts {\n    fn into_response(self) -> Response {\n        Response::from_parts(self, Body::empty())\n    }\n}\n\nimpl IntoResponse for Body {\n    fn into_response(self) -> Response {\n        Response::new(self)\n    }\n}\n\nimpl IntoResponse for &'static str {\n    fn into_response(self) -> Response {\n        Cow::Borrowed(self).into_response()\n    }\n}\n\nimpl IntoResponse for String {\n    fn into_response(self) -> Response {\n        Cow::<'static, str>::Owned(self).into_response()\n    }\n}\n\nimpl IntoResponse for Box<str> {\n    fn into_response(self) -> Response {\n        String::from(self).into_response()\n    }\n}\n\nimpl IntoResponse for Cow<'static, str> {\n    fn into_response(self) -> Response {\n        let mut res = Body::from(self).into_response();\n        res.headers_mut().insert(\n            header::CONTENT_TYPE,\n            HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),\n        );\n        res\n    }\n}\n\nimpl IntoResponse for Bytes {\n    fn into_response(self) -> Response {\n        let mut res = Body::from(self).into_response();\n        res.headers_mut().insert(\n            header::CONTENT_TYPE,\n            HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),\n        );\n        res\n    }\n}\n\nimpl IntoResponse for BytesMut {\n    fn into_response(self) -> Response {\n        self.freeze().into_response()\n    }\n}\n\nimpl<T, U> IntoResponse for Chain<T, U>\nwhere\n    T: Buf + Unpin + Send + 'static,\n    U: Buf + Unpin + Send + 'static,\n{\n    fn into_response(self) -> Response {\n        let (first, second) = self.into_inner();\n        let mut res = Response::new(Body::new(BytesChainBody {\n            first: Some(first),\n            second: Some(second),\n        }));\n        res.headers_mut().insert(\n            header::CONTENT_TYPE,\n            HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),\n        );\n        res\n    }\n}\n\nstruct BytesChainBody<T, U> {\n    first: Option<T>,\n    second: Option<U>,\n}\n\nimpl<T, U> http_body::Body for BytesChainBody<T, U>\nwhere\n    T: Buf + Unpin,\n    U: Buf + Unpin,\n{\n    type Data = Bytes;\n    type Error = Infallible;\n\n    fn poll_frame(\n        mut self: Pin<&mut Self>,\n        _cx: &mut Context<'_>,\n    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {\n        if let Some(mut buf) = self.first.take() {\n            let bytes = buf.copy_to_bytes(buf.remaining());\n            return Poll::Ready(Some(Ok(Frame::data(bytes))));\n        }\n\n        if let Some(mut buf) = self.second.take() {\n            let bytes = buf.copy_to_bytes(buf.remaining());\n            return Poll::Ready(Some(Ok(Frame::data(bytes))));\n        }\n\n        Poll::Ready(None)\n    }\n\n    fn is_end_stream(&self) -> bool {\n        self.first.is_none() && self.second.is_none()\n    }\n\n    fn size_hint(&self) -> SizeHint {\n        match (self.first.as_ref(), self.second.as_ref()) {\n            (Some(first), Some(second)) => {\n                let total_size = first.remaining() + second.remaining();\n                SizeHint::with_exact(total_size as u64)\n            }\n            (Some(buf), None) => SizeHint::with_exact(buf.remaining() as u64),\n            (None, Some(buf)) => SizeHint::with_exact(buf.remaining() as u64),\n            (None, None) => SizeHint::with_exact(0),\n        }\n    }\n}\n\nimpl IntoResponse for &'static [u8] {\n    fn into_response(self) -> Response {\n        Cow::Borrowed(self).into_response()\n    }\n}\n\nimpl<const N: usize> IntoResponse for &'static [u8; N] {\n    fn into_response(self) -> Response {\n        self.as_slice().into_response()\n    }\n}\n\nimpl<const N: usize> IntoResponse for [u8; N] {\n    fn into_response(self) -> Response {\n        self.to_vec().into_response()\n    }\n}\n\nimpl IntoResponse for Vec<u8> {\n    fn into_response(self) -> Response {\n        Cow::<'static, [u8]>::Owned(self).into_response()\n    }\n}\n\nimpl IntoResponse for Box<[u8]> {\n    fn into_response(self) -> Response {\n        Vec::from(self).into_response()\n    }\n}\n\nimpl IntoResponse for Cow<'static, [u8]> {\n    fn into_response(self) -> Response {\n        let mut res = Body::from(self).into_response();\n        res.headers_mut().insert(\n            header::CONTENT_TYPE,\n            HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),\n        );\n        res\n    }\n}\n\nimpl<R> IntoResponse for (StatusCode, R)\nwhere\n    R: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        let mut res = self.1.into_response();\n        if res.extensions().get::<IntoResponseFailed>().is_none() {\n            *res.status_mut() = self.0;\n        }\n        res\n    }\n}\n\nimpl IntoResponse for HeaderMap {\n    fn into_response(self) -> Response {\n        let mut res = ().into_response();\n        *res.headers_mut() = self;\n        res\n    }\n}\n\nimpl IntoResponse for Extensions {\n    fn into_response(self) -> Response {\n        let mut res = ().into_response();\n        *res.extensions_mut() = self;\n        res\n    }\n}\n\nimpl<K, V, const N: usize> IntoResponse for [(K, V); N]\nwhere\n    K: TryInto<HeaderName>,\n    K::Error: fmt::Display,\n    V: TryInto<HeaderValue>,\n    V::Error: fmt::Display,\n{\n    fn into_response(self) -> Response {\n        (self, ()).into_response()\n    }\n}\n\nimpl<R> IntoResponse for (http::response::Parts, R)\nwhere\n    R: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        let (parts, res) = self;\n        (parts.status, parts.headers, parts.extensions, res).into_response()\n    }\n}\n\nimpl<R> IntoResponse for (http::response::Response<()>, R)\nwhere\n    R: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        let (template, res) = self;\n        let (parts, ()) = template.into_parts();\n        (parts, res).into_response()\n    }\n}\n\nimpl<R> IntoResponse for (R,)\nwhere\n    R: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        let (res,) = self;\n        res.into_response()\n    }\n}\n\nmacro_rules! impl_into_response {\n    ( $($ty:ident),* $(,)? ) => {\n        #[allow(non_snake_case)]\n        impl<R, $($ty,)*> IntoResponse for ($($ty),*, R)\n        where\n            $( $ty: IntoResponseParts, )*\n            R: IntoResponse,\n        {\n            fn into_response(self) -> Response {\n                let ($($ty),*, res) = self;\n\n                let res = res.into_response();\n                if res.extensions().get::<IntoResponseFailed>().is_none() {\n                    let parts = ResponseParts { res };\n                    let parts = match ($($ty,)*).into_response_parts(parts) {\n                        Ok(parts) => parts,\n                        Err(err) => return err.into_response(),\n                    };\n                    parts.res\n                } else {\n                    res\n                }\n            }\n        }\n\n        #[allow(non_snake_case)]\n        impl<R, $($ty,)*> IntoResponse for (StatusCode, $($ty),*, R)\n        where\n            $( $ty: IntoResponseParts, )*\n            R: IntoResponse,\n        {\n            fn into_response(self) -> Response {\n                let (status, $($ty),*, res) = self;\n\n                let res = res.into_response();\n                if res.extensions().get::<IntoResponseFailed>().is_none() {\n                    let parts = ResponseParts { res };\n                    let mut parts = match ($($ty,)*).into_response_parts(parts) {\n                        Ok(parts) => parts,\n                        Err(err) => return err.into_response(),\n                    };\n\n                    // Don't call `(status, parts.res).into_response()` since that checks for\n                    // `IntoResponseFailed` and skips setting the status. We've already done that\n                    // check here so overriding the status is required if returning\n                    // `(IntoResponseFailed, StatusCode::INTERNAL_SERVER_ERROR)`\n                    *parts.res.status_mut() = status;\n                    parts.res\n                } else {\n                    res\n                }\n            }\n        }\n\n        #[allow(non_snake_case)]\n        impl<R, $($ty,)*> IntoResponse for (ForceStatusCode, $($ty),*, R)\n        where\n            $( $ty: IntoResponseParts, )*\n            R: IntoResponse,\n        {\n            fn into_response(self) -> Response {\n                let (status, $($ty),*, res) = self;\n\n                let res = res.into_response();\n                let parts = ResponseParts { res };\n                let parts = match ($($ty,)*).into_response_parts(parts) {\n                    Ok(parts) => parts,\n                    Err(err) => return err.into_response(),\n                };\n\n                (status, parts.res).into_response()\n            }\n        }\n\n        #[allow(non_snake_case)]\n        impl<R, $($ty,)*> IntoResponse for (http::response::Parts, $($ty),*, R)\n        where\n            $( $ty: IntoResponseParts, )*\n            R: IntoResponse,\n        {\n            fn into_response(self) -> Response {\n                let (outer_parts, $($ty),*, res) = self;\n\n                let res = res.into_response();\n                if res.extensions().get::<IntoResponseFailed>().is_none() {\n                    let parts = ResponseParts { res };\n                    let mut parts = match ($($ty,)*).into_response_parts(parts) {\n                        Ok(parts) => parts,\n                        Err(err) => return err.into_response(),\n                    };\n\n                    // Don't call `(outer_parts, parts.res).into_response()` for the same reason we\n                    // don't call `(status, parts.res).into_response()` in the above impl.\n                    *parts.res.status_mut() = outer_parts.status;\n                    parts.res.headers_mut().extend(outer_parts.headers);\n                    parts.res.extensions_mut().extend(outer_parts.extensions);\n                    parts.res\n                } else {\n                    res\n                }\n            }\n        }\n\n        #[allow(non_snake_case)]\n        impl<R, $($ty,)*> IntoResponse for (http::response::Response<()>, $($ty),*, R)\n        where\n            $( $ty: IntoResponseParts, )*\n            R: IntoResponse,\n        {\n            fn into_response(self) -> Response {\n                let (template, $($ty),*, res) = self;\n                let (parts, ()) = template.into_parts();\n                (parts, $($ty),*, res).into_response()\n            }\n        }\n    }\n}\n\nall_the_tuples_no_last_special_case!(impl_into_response);\n"
  },
  {
    "path": "axum-core/src/response/into_response_parts.rs",
    "content": "use super::{IntoResponse, Response};\nuse http::{\n    header::{HeaderMap, HeaderName, HeaderValue},\n    Extensions, StatusCode,\n};\nuse std::{convert::Infallible, fmt};\n\n/// Trait for adding headers and extensions to a response.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     response::{ResponseParts, IntoResponse, IntoResponseParts, Response},\n///     http::{StatusCode, header::{HeaderName, HeaderValue}},\n/// };\n///\n/// // Hypothetical helper type for setting a single header\n/// struct SetHeader<'a>(&'a str, &'a str);\n///\n/// impl<'a> IntoResponseParts for SetHeader<'a> {\n///     type Error = (StatusCode, String);\n///\n///     fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n///         match (self.0.parse::<HeaderName>(), self.1.parse::<HeaderValue>()) {\n///             (Ok(name), Ok(value)) => {\n///                 res.headers_mut().insert(name, value);\n///             },\n///             (Err(_), _) => {\n///                 return Err((\n///                     StatusCode::INTERNAL_SERVER_ERROR,\n///                     format!(\"Invalid header name {}\", self.0),\n///                 ));\n///             },\n///             (_, Err(_)) => {\n///                 return Err((\n///                     StatusCode::INTERNAL_SERVER_ERROR,\n///                     format!(\"Invalid header value {}\", self.1),\n///                 ));\n///             },\n///         }\n///\n///         Ok(res)\n///     }\n/// }\n///\n/// // It's also recommended to implement `IntoResponse` so `SetHeader` can be used on its own as\n/// // the response\n/// impl<'a> IntoResponse for SetHeader<'a> {\n///     fn into_response(self) -> Response {\n///         // This gives an empty response with the header\n///         (self, ()).into_response()\n///     }\n/// }\n///\n/// // We can now return `SetHeader` in responses\n/// //\n/// // Note that returning `impl IntoResponse` might be easier if the response has many parts to\n/// // it. The return type is written out here for clarity.\n/// async fn handler() -> (SetHeader<'static>, SetHeader<'static>, &'static str) {\n///     (\n///         SetHeader(\"server\", \"axum\"),\n///         SetHeader(\"x-foo\", \"custom\"),\n///         \"body\",\n///     )\n/// }\n///\n/// // Or on its own as the whole response\n/// async fn other_handler() -> SetHeader<'static> {\n///     SetHeader(\"x-foo\", \"custom\")\n/// }\n/// ```\npub trait IntoResponseParts {\n    /// The type returned in the event of an error.\n    ///\n    /// This can be used to fallibly convert types into headers or extensions.\n    type Error: IntoResponse;\n\n    /// Set parts of the response\n    fn into_response_parts(self, res: ResponseParts) -> Result<ResponseParts, Self::Error>;\n}\n\nimpl<T> IntoResponseParts for Option<T>\nwhere\n    T: IntoResponseParts,\n{\n    type Error = T::Error;\n\n    fn into_response_parts(self, res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        if let Some(inner) = self {\n            inner.into_response_parts(res)\n        } else {\n            Ok(res)\n        }\n    }\n}\n\n/// Parts of a response.\n///\n/// Used with [`IntoResponseParts`].\n#[derive(Debug)]\npub struct ResponseParts {\n    pub(crate) res: Response,\n}\n\nimpl ResponseParts {\n    /// Gets a reference to the response headers.\n    #[must_use]\n    pub fn headers(&self) -> &HeaderMap {\n        self.res.headers()\n    }\n\n    /// Gets a mutable reference to the response headers.\n    #[must_use]\n    pub fn headers_mut(&mut self) -> &mut HeaderMap {\n        self.res.headers_mut()\n    }\n\n    /// Gets a reference to the response extensions.\n    #[must_use]\n    pub fn extensions(&self) -> &Extensions {\n        self.res.extensions()\n    }\n\n    /// Gets a mutable reference to the response extensions.\n    #[must_use]\n    pub fn extensions_mut(&mut self) -> &mut Extensions {\n        self.res.extensions_mut()\n    }\n}\n\nimpl IntoResponseParts for HeaderMap {\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        res.headers_mut().extend(self);\n        Ok(res)\n    }\n}\n\nimpl<K, V, const N: usize> IntoResponseParts for [(K, V); N]\nwhere\n    K: TryInto<HeaderName>,\n    K::Error: fmt::Display,\n    V: TryInto<HeaderValue>,\n    V::Error: fmt::Display,\n{\n    type Error = TryIntoHeaderError<K::Error, V::Error>;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        for (key, value) in self {\n            let key = key.try_into().map_err(TryIntoHeaderError::key)?;\n            let value = value.try_into().map_err(TryIntoHeaderError::value)?;\n            res.headers_mut().insert(key, value);\n        }\n\n        Ok(res)\n    }\n}\n\n/// Error returned if converting a value to a header fails.\n#[derive(Debug)]\npub struct TryIntoHeaderError<K, V> {\n    kind: TryIntoHeaderErrorKind<K, V>,\n}\n\nimpl<K, V> TryIntoHeaderError<K, V> {\n    pub(super) fn key(err: K) -> Self {\n        Self {\n            kind: TryIntoHeaderErrorKind::Key(err),\n        }\n    }\n\n    pub(super) fn value(err: V) -> Self {\n        Self {\n            kind: TryIntoHeaderErrorKind::Value(err),\n        }\n    }\n}\n\n#[derive(Debug)]\nenum TryIntoHeaderErrorKind<K, V> {\n    Key(K),\n    Value(V),\n}\n\nimpl<K, V> IntoResponse for TryIntoHeaderError<K, V>\nwhere\n    K: fmt::Display,\n    V: fmt::Display,\n{\n    fn into_response(self) -> Response {\n        match self.kind {\n            TryIntoHeaderErrorKind::Key(inner) => {\n                (StatusCode::INTERNAL_SERVER_ERROR, inner.to_string()).into_response()\n            }\n            TryIntoHeaderErrorKind::Value(inner) => {\n                (StatusCode::INTERNAL_SERVER_ERROR, inner.to_string()).into_response()\n            }\n        }\n    }\n}\n\nimpl<K, V> fmt::Display for TryIntoHeaderError<K, V> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self.kind {\n            TryIntoHeaderErrorKind::Key(_) => write!(f, \"failed to convert key to a header name\"),\n            TryIntoHeaderErrorKind::Value(_) => {\n                write!(f, \"failed to convert value to a header value\")\n            }\n        }\n    }\n}\n\nimpl<K, V> std::error::Error for TryIntoHeaderError<K, V>\nwhere\n    K: std::error::Error + 'static,\n    V: std::error::Error + 'static,\n{\n    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n        match &self.kind {\n            TryIntoHeaderErrorKind::Key(inner) => Some(inner),\n            TryIntoHeaderErrorKind::Value(inner) => Some(inner),\n        }\n    }\n}\n\nmacro_rules! impl_into_response_parts {\n    ( $($ty:ident),* $(,)? ) => {\n        #[allow(non_snake_case)]\n        impl<$($ty,)*> IntoResponseParts for ($($ty,)*)\n        where\n            $( $ty: IntoResponseParts, )*\n        {\n            type Error = Response;\n\n            fn into_response_parts(self, res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n                let ($($ty,)*) = self;\n\n                $(\n                    let res = match $ty.into_response_parts(res) {\n                        Ok(res) => res,\n                        Err(err) => {\n                            let mut err_res = err.into_response();\n                            err_res.extensions_mut().insert(super::IntoResponseFailed);\n                            return Err(err_res);\n                        }\n                    };\n                )*\n\n                Ok(res)\n            }\n        }\n    }\n}\n\nall_the_tuples_no_last_special_case!(impl_into_response_parts);\n\nimpl IntoResponseParts for Extensions {\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        res.extensions_mut().extend(self);\n        Ok(res)\n    }\n}\n\nimpl IntoResponseParts for () {\n    type Error = Infallible;\n\n    fn into_response_parts(self, res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        Ok(res)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use http::StatusCode;\n\n    use crate::response::IntoResponse;\n\n    #[test]\n    fn failed_into_response_parts() {\n        let response = (StatusCode::CREATED, [(\"\\n\", \"\\n\")]).into_response();\n        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);\n\n        let response = (StatusCode::CREATED, [(\"\\n\", \"\\n\")], ()).into_response();\n        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);\n    }\n}\n"
  },
  {
    "path": "axum-core/src/response/mod.rs",
    "content": "//! Types and traits for generating responses.\n//!\n//! See [`axum::response`] for more details.\n//!\n//! [`axum::response`]: https://docs.rs/axum/0.8/axum/response/index.html\n\nuse std::convert::Infallible;\n\nuse http::StatusCode;\n\nuse crate::body::Body;\n\nmod append_headers;\nmod into_response;\nmod into_response_parts;\n\npub use self::{\n    append_headers::AppendHeaders,\n    into_response::IntoResponse,\n    into_response_parts::{IntoResponseParts, ResponseParts, TryIntoHeaderError},\n};\n\n/// Type alias for [`http::Response`] whose body type defaults to [`Body`], the most common body\n/// type used with axum.\npub type Response<T = Body> = http::Response<T>;\n\n/// An [`IntoResponse`]-based result type that uses [`ErrorResponse`] as the error type.\n///\n/// All types which implement [`IntoResponse`] can be converted to an [`ErrorResponse`]. This makes\n/// it useful as a general purpose error type for functions which combine multiple distinct error\n/// types that all implement [`IntoResponse`].\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     response::{IntoResponse, Response},\n///     http::StatusCode,\n/// };\n///\n/// // two fallible functions with different error types\n/// fn try_something() -> Result<(), ErrorA> {\n///     // ...\n///     # unimplemented!()\n/// }\n///\n/// fn try_something_else() -> Result<(), ErrorB> {\n///     // ...\n///     # unimplemented!()\n/// }\n///\n/// // each error type implements `IntoResponse`\n/// struct ErrorA;\n///\n/// impl IntoResponse for ErrorA {\n///     fn into_response(self) -> Response {\n///         // ...\n///         # unimplemented!()\n///     }\n/// }\n///\n/// enum ErrorB {\n///     SomethingWentWrong,\n/// }\n///\n/// impl IntoResponse for ErrorB {\n///     fn into_response(self) -> Response {\n///         // ...\n///         # unimplemented!()\n///     }\n/// }\n///\n/// // we can combine them using `axum::response::Result` and still use `?`\n/// async fn handler() -> axum::response::Result<&'static str> {\n///     // the errors are automatically converted to `ErrorResponse`\n///     try_something()?;\n///     try_something_else()?;\n///\n///     Ok(\"it worked!\")\n/// }\n/// ```\n///\n/// # As a replacement for `std::result::Result`\n///\n/// Since `axum::response::Result` has a default error type you only have to specify the `Ok` type:\n///\n/// ```\n/// use axum::{\n///     response::{IntoResponse, Response, Result},\n///     http::StatusCode,\n/// };\n///\n/// // `Result<T>` automatically uses `ErrorResponse` as the error type.\n/// async fn handler() -> Result<&'static str> {\n///     try_something()?;\n///\n///     Ok(\"it worked!\")\n/// }\n///\n/// // You can still specify the error even if you've imported `axum::response::Result`\n/// fn try_something() -> Result<(), StatusCode> {\n///     // ...\n///     # unimplemented!()\n/// }\n/// ```\npub type Result<T, E = ErrorResponse> = std::result::Result<T, E>;\n\nimpl<T> IntoResponse for Result<T>\nwhere\n    T: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        match self {\n            Ok(ok) => ok.into_response(),\n            Err(err) => err.0,\n        }\n    }\n}\n\n/// An [`IntoResponse`]-based error type\n///\n/// See [`Result`] for more details.\n#[derive(Debug)]\n#[must_use]\npub struct ErrorResponse(Response);\n\nimpl<T> From<T> for ErrorResponse\nwhere\n    T: IntoResponse,\n{\n    fn from(value: T) -> Self {\n        Self(value.into_response())\n    }\n}\n\n/// Response part that stops status code overrides.\n///\n/// This type should be used by types implementing [`IntoResponseParts`] or\n/// [`IntoResponse`] when they fail to produce the response usually expected of\n/// them and return some sort of error response instead.\n///\n/// It is checked used by the tuple impls of [`IntoResponse`] that have a\n/// [`StatusCode`] as their first element to ignore that status code.\n/// Consider the following example:\n///\n/// ```no_run\n/// # use axum::Json;\n/// # use http::StatusCode;\n/// # #[derive(serde::Serialize)]\n/// # struct CreatedResponse { }\n/// fn my_handler(/* ... */) -> (StatusCode, Json<CreatedResponse>) {\n///     // This response type's serialization may fail\n///     let response = CreatedResponse { /* ... */ };\n///     (StatusCode::CREATED, Json(response))\n/// }\n/// ```\n///\n/// When `response` serialization succeeds, the server responds with a status\n/// code of 201 Created (overwriting `Json`s default status code of 200 OK),\n/// and the expected JSON payload.\n///\n/// When `response` serialization fails hoewever, `impl IntoResponse for Json`\n/// return a response with status code 500 Internal Server Error, and\n/// `IntoResponseFailed` as a response extension, and the 201 Created override\n/// is ignored.\n///\n/// This is a behavior introduced with axum 0.9.\\\n/// To force a status code override even when an inner [`IntoResponseParts`] /\n/// [`IntoResponse`] failed, use [`ForceStatusCode`].\n#[derive(Copy, Clone, Debug)]\npub struct IntoResponseFailed;\n\nimpl IntoResponseParts for IntoResponseFailed {\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        res.extensions_mut().insert(self);\n        Ok(res)\n    }\n}\n\n/// Not sure it makes sense to return `IntoResponseFailed` as the whole response. You should\n/// probably at least combine it with a status code.\n///\n/// ```compile_fail\n/// fn foo()\n/// where\n///     axum_core::response::IntoResponseFailed: axum_core::response::IntoResponse,\n/// {}\n/// ```\n#[allow(dead_code)]\nfn into_response_failed_doesnt_impl_into_response() {}\n\n/// Set the status code regardless of whether [`IntoResponseFailed`] is used or not.\n///\n/// See the docs for [`IntoResponseFailed`] for more details.\n#[derive(Debug, Copy, Clone, Default)]\npub struct ForceStatusCode(pub StatusCode);\n\nimpl IntoResponse for ForceStatusCode {\n    fn into_response(self) -> Response {\n        let mut res = ().into_response();\n        *res.status_mut() = self.0;\n        res\n    }\n}\n\nimpl<R> IntoResponse for (ForceStatusCode, R)\nwhere\n    R: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        let (ForceStatusCode(status), res) = self;\n        let mut res = res.into_response();\n        *res.status_mut() = status;\n        res\n    }\n}\n"
  },
  {
    "path": "axum-extra/CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog],\nand this project adheres to [Semantic Versioning].\n\n# Unreleased\n\n- **fixed:** Escape backslashes and double quotes in `Content-Disposition` filenames\n  to prevent header parameter injection in `Attachment` and `FileStream` ([#3664])\n- `vpath!` macro now stops the compilation if your path is using deprecated\n  path variables in the old `107` format, such as `:var` and `*var`. the \n  only allowed way now is `{var}`.\n- **breaking:** Remove the deprecated `Host`, `Scheme` and `OptionalPath`\n  extractors ([#3599])\n  - Also remove `HostRejection` which only had `FailedToResolveHost`\n    previously used in the `Host` extractor ([#3636])\n- **breaking:** Change `routing::RouterExt::route_with_tsr` to only redirect\n  the HTTP methods that the supplied `MethodRouter` handles. This allows the\n  following pattern which lead to a panic before because the two\n  `route_with_tsr` calls would both attempt to register a method-independent\n  redirect ([#3586]):\n\n  ```rust\n  Router::new()\n      .route_with_tsr(\"/path\", get(/* handler */))\n      .route_with_tsr(\"/path\", post(/* handler */))\n  ```\n\n[#3664]: https://github.com/tokio-rs/axum/pull/3664\n[#3599]: https://github.com/tokio-rs/axum/pull/3599\n[#3586]: https://github.com/tokio-rs/axum/pull/3586\n\n# 0.12.5\n\n- **fixed:** `JsonLines` now correctly respects the default body limit ([#3591])\n\n[#3591]: https://github.com/tokio-rs/axum/pull/3591\n\n# 0.12.4\n\n- **changed:** Deprecated the `Host` and `Scheme` extractors ([#3595])\n  - Please comment in [#3442] if you depend on one of them\n\n[#3595]: https://github.com/tokio-rs/axum/pull/3595\n[#3442]: https://github.com/tokio-rs/axum/issues/3442\n\n# 0.12.3\n\n- **changed:** Make the `typed-routing` feature enable the `routing` feature ([#3514])\n- **changed:** Add trailing newline to `ErasedJson::pretty` response bodies ([#3526])\n- **fixed:** Fix integer underflow in `FileStream::try_range_response` for empty files ([#3566])\n\n[#3514]: https://github.com/tokio-rs/axum/pull/3514\n[#3526]: https://github.com/tokio-rs/axum/pull/3526\n[#3566]: https://github.com/tokio-rs/axum/pull/3566\n\n# 0.12.2\n\n- Make it easier to visually scan for default features ([#3550])\n\n[#3550]: https://github.com/tokio-rs/axum/pull/3550\n\n# 0.12.1\n\nThis release contains no changes in code, only a small `Cargo.toml` fix for\n`docs.rs`.\n\n# 0.12.0\n\n- **breaking:** Remove unused `async-stream` feature, which was accidentally\n  introduced as an implicit feature through an optional dependency which was no\n  longer being used ([#3298])\n- **breaking:** `option_layer` now maps the `Response` body type to `axum::body::Body` ([#3469])\n- **breaking:** Some new features are added which need to be opted in ([#3485]).\n  - `Cached` extractor requires `cached` feature.\n  - The handler utilities require `handler` feature.\n  - The middleware utilities require `middleware` feature.\n  - `OptionalPath` extractor requires `optional-path` feature.\n  - The routing utilities require `routing` feature.\n  - `WithRejection` extractor requires `with-rejection` feature.\n- **breaking:** Upgraded `prost` dependency to v0.14. ([#3517])\n\n[#3298]: https://github.com/tokio-rs/axum/pull/3298\n[#3469]: https://github.com/tokio-rs/axum/pull/3469\n[#3485]: https://github.com/tokio-rs/axum/pull/3485\n[#3517]: https://github.com/tokio-rs/axum/pull/3517\n\n# 0.11.0\n\nYanked from crates.io due to unforeseen breaking change, see [#3190] for details.\n\n[#3190]: https://github.com/tokio-rs/axum/pull/3190\n\n# 0.10.3\n\nReleased without changes to fix docs.rs build.\n\n# 0.10.2\n\n- **added:** Implement `OptionalFromRequest` for `Host` ([#3177])\n\n[#3177]: https://github.com/tokio-rs/axum/pull/3177\n\n# 0.10.1\n\n- **fixed:** Fix a broken link in the documentation of `ErasedJson` ([#3186])\n- **added:** Add `vpath!` for compile time path verification on static paths. ([#3288])\n\n[#3186]: https://github.com/tokio-rs/axum/pull/3186\n[#3288]: https://github.com/tokio-rs/axum/pull/3288\n\n# 0.10.0\n\n## since rc.1\n\n<details>\n\n- **breaking:** Remove `OptionalFromRequestParts` impl for `Query` ([#3088])\n- **changed:** Query/Form: Use `serde_path_to_error` to report fields that failed to parse ([#3081])\n\n[#3088]: https://github.com/tokio-rs/axum/pull/3088\n\n</details>\n\n## full changelog\n\n- **breaking:** Update to prost 0.13. Used for the `Protobuf` extractor ([#2829])\n- **changed:** Update minimum rust version to 1.75 ([#2943])\n- **changed:** Deprecated `OptionalPath<T>` ([#2475])\n- **changed:** Query/Form: Use `serde_path_to_error` to report fields that failed to parse ([#3081])\n- **changed:** The `multipart` feature is no longer on by default ([#3058])\n- **fixed:** `Host` extractor includes port number when parsing authority ([#2242])\n- **added:** Add `RouterExt::typed_connect` ([#2961])\n- **added:** Add `json!` for easy construction of JSON responses ([#2962])\n- **added:** Add `InternalServerError` response for logging an internal error\n  and returning HTTP 500 in a convenient way. ([#3010])\n- **added:** Add `FileStream` for easy construction of file stream responses ([#3047])\n- **added:** Add `Scheme` extractor ([#2507])\n\n[#3081]: https://github.com/tokio-rs/axum/pull/3081\n\n## rc.1\n\n- **breaking:** `Option<Query<T>>` no longer swallows all error conditions, instead rejecting the\n  request in many cases; see its documentation for details ([#2475])\n- **changed:** Deprecated `OptionalPath<T>` and `OptionalQuery<T>` ([#2475])\n- **fixed:** `Host` extractor includes port number when parsing authority ([#2242])\n- **changed:** The `multipart` feature is no longer on by default ([#3058])\n- **added:** Add `RouterExt::typed_connect` ([#2961])\n- **added:** Add `json!` for easy construction of JSON responses ([#2962])\n- **added:** Add `InternalServerError` response for logging an internal error\n  and returning HTTP 500 in a convenient way. ([#3010])\n- **added:** Add `FileStream` for easy construction of file stream responses ([#3047])\n- **added:** Add `Scheme` extractor ([#2507])\n\n[#2242]: https://github.com/tokio-rs/axum/pull/2242\n[#2475]: https://github.com/tokio-rs/axum/pull/2475\n[#3058]: https://github.com/tokio-rs/axum/pull/3058\n[#2961]: https://github.com/tokio-rs/axum/pull/2961\n[#2962]: https://github.com/tokio-rs/axum/pull/2962\n[#3010]: https://github.com/tokio-rs/axum/pull/3010\n[#3047]: https://github.com/tokio-rs/axum/pull/3047\n[#2507]: https://github.com/tokio-rs/axum/pull/2507\n\n## alpha.1\n\n- **breaking:** Update to prost 0.13. Used for the `Protobuf` extractor ([#2829])\n- **change:** Update minimum rust version to 1.75 ([#2943])\n\n[#2829]: https://github.com/tokio-rs/axum/pull/2829\n[#2943]: https://github.com/tokio-rs/axum/pull/2943\n\n# 0.9.6\n\n- **docs:** Add links to features table ([#3030])\n\n[#3030]: https://github.com/tokio-rs/axum/pull/3030\n\n# 0.9.5\n\n- **added:** Add `RouterExt::typed_connect` ([#2961])\n- **added:** Add `json!` for easy construction of JSON responses ([#2962])\n\n[#2961]: https://github.com/tokio-rs/axum/pull/2961\n[#2962]: https://github.com/tokio-rs/axum/pull/2962\n\n# 0.9.4\n\n- **added:** The `response::Attachment` type ([#2789])\n\n[#2789]: https://github.com/tokio-rs/axum/pull/2789\n\n# 0.9.3 (24. March, 2024)\n\n- **added:** New `tracing` feature which enables logging rejections from\n  built-in extractor with the `axum::rejection=trace` target ([#2584])\n\n[#2584]: https://github.com/tokio-rs/axum/pull/2584\n\n# 0.9.2 (13. January, 2024)\n\n- **added:** Implement `TypedPath` for `WithRejection<TypedPath, _>`\n- **fixed:** Documentation link to `serde::Deserialize` in `JsonDeserializer` extractor ([#2498])\n- **added:** Add `is_missing` function for `TypedHeaderRejection` and `TypedHeaderRejectionReason` ([#2503])\n\n[#2498]: https://github.com/tokio-rs/axum/pull/2498\n[#2503]: https://github.com/tokio-rs/axum/pull/2503\n\n# 0.9.1 (29. December, 2023)\n\n- **change:** Update version of multer used internally for multipart ([#2433])\n- **added:** `JsonDeserializer` extractor ([#2431])\n\n[#2433]: https://github.com/tokio-rs/axum/pull/2433\n[#2431]: https://github.com/tokio-rs/axum/pull/2431\n\n# 0.9.0 (27. November, 2023)\n\n- **added:** `OptionalQuery` extractor ([#2310])\n- **added:** `TypedHeader` which used to be in `axum` ([#1850])\n- **breaking:** Update to prost 0.12. Used for the `Protobuf` extractor\n- **breaking:** Make `tokio` an optional dependency\n- **breaking:** Upgrade `cookie` dependency to 0.18 ([#2343])\n- **breaking:** Functions and methods that previously accepted a `Cookie`\n  now accept any `T: Into<Cookie>` ([#2348])\n\n[#1850]: https://github.com/tokio-rs/axum/pull/1850\n[#2310]: https://github.com/tokio-rs/axum/pull/2310\n[#2343]: https://github.com/tokio-rs/axum/pull/2343\n[#2348]: https://github.com/tokio-rs/axum/pull/2348\n\n# 0.8.0 (16. September, 2023)\n\n- **breaking:** Update to prost 0.12. Used for the `Protobuf` extractor ([#2224])\n\n[#2224]: https://github.com/tokio-rs/axum/pull/2224\n\n# 0.7.7 (03. August, 2023)\n\n- **added:** `Clone` implementation for `ErasedJson` ([#2142])\n\n[#2142]: https://github.com/tokio-rs/axum/pull/2142\n\n# 0.7.6 (02. August, 2023)\n\n- **fixed:** Remove unused dependency ([#2135])\n\n[#2135]: https://github.com/tokio-rs/axum/pull/2135\n\n# 0.7.5 (17. July, 2023)\n\n- **fixed:** Remove explicit auto deref from `PrivateCookieJar` example ([#2028])\n\n[#2028]: https://github.com/tokio-rs/axum/pull/2028\n\n# 0.7.4 (18. April, 2023)\n\n- **added:** Add `Html` response type ([#1921])\n- **added:** Add `Css` response type ([#1921])\n- **added:** Add `JavaScript` response type ([#1921])\n- **added:** Add `Wasm` response type ([#1921])\n\n[#1921]: https://github.com/tokio-rs/axum/pull/1921\n\n# 0.7.3 (11. April, 2023)\n\n- **added:** Implement `Deref` and `DerefMut` for built-in extractors ([#1922])\n- **added:** Add `OptionalPath` extractor ([#1889])\n\n[#1889]: https://github.com/tokio-rs/axum/pull/1889\n[#1922]: https://github.com/tokio-rs/axum/pull/1922\n\n# 0.7.2 (22. March, 2023)\n\n- **added:** Implement `IntoResponse` for `MultipartError` ([#1861])\n\n[#1861]: https://github.com/tokio-rs/axum/pull/1861\n\n# 0.7.1 (13. March, 2023)\n\n- Updated to latest `axum-macros`\n\n# 0.7.0 (03. March, 2023)\n\n- **breaking:** Remove the `spa` feature which should have been removed in 0.6.0 ([#1802])\n- **added:** Add `Multipart`. This is similar to `axum::extract::Multipart`\n  except that it enforces field exclusivity at runtime instead of compile time,\n  as this improves usability ([#1692])\n- **added:** Implement `Clone` for `CookieJar`, `PrivateCookieJar` and `SignedCookieJar` ([#1808])\n- **fixed:** Add `#[must_use]` attributes to types that do nothing unless used ([#1809])\n\n[#1692]: https://github.com/tokio-rs/axum/pull/1692\n[#1802]: https://github.com/tokio-rs/axum/pull/1802\n[#1808]: https://github.com/tokio-rs/axum/pull/1808\n[#1809]: https://github.com/tokio-rs/axum/pull/1809\n\n# 0.6.0 (24. February, 2022)\n\n- **breaking:**  Change casing of `ProtoBuf` to `Protobuf` ([#1595])\n- **breaking:** `SpaRouter` has been removed. Use `ServeDir` and `ServeFile`\n  from `tower-http` instead:\n\n  ```rust\n  // before\n  Router::new().merge(SpaRouter::new(\"/assets\", \"dist\"));\n\n  // with ServeDir\n  Router::new().nest_service(\"/assets\", ServeDir::new(\"dist\"));\n\n  // before with `index_file`\n  Router::new().merge(SpaRouter::new(\"/assets\", \"dist\").index_file(\"index.html\"));\n\n  // with ServeDir + ServeFile\n  Router::new().nest_service(\n      \"/assets\",\n      ServeDir::new(\"dist\").not_found_service(ServeFile::new(\"dist/index.html\")),\n  );\n  ```\n\n  See the [static-file-server-example] for more examples ([#1784])\n\n[#1595]: https://github.com/tokio-rs/axum/pull/1595\n[#1784]: https://github.com/tokio-rs/axum/pull/1784\n[static-file-server-example]: https://github.com/tokio-rs/axum/blob/main/examples/static-file-server/src/main.rs\n\n# 0.5.0 (12. February, 2022)\n\n- **added:** Add `option_layer` for converting an `Option<Layer>` into a `Layer` ([#1696])\n- **added:** Implement `Layer` and `Service` for `Either` ([#1696])\n- **added:** Add `TypedPath::with_query_params` ([#1744])\n- **breaking:** Update to [`cookie`] 0.17 ([#1747])\n\n[#1696]: https://github.com/tokio-rs/axum/pull/1696\n[#1744]: https://github.com/tokio-rs/axum/pull/1744\n[#1747]: https://github.com/tokio-rs/axum/pull/1747\n[`cookie`]: https://crates.io/crates/cookie\n\n# 0.4.2 (02. December, 2022)\n\n- **fixed:** Bug fixes for `RouterExt:{route_with_tsr, route_service_with_tsr}` ([#1608]):\n  - Redirects to the correct URI if the route contains path parameters\n  - Keeps query parameters when redirecting\n  - Better improved error message if adding route for `/`\n\n[#1608]: https://github.com/tokio-rs/axum/pull/1608\n\n# 0.4.1 (29. November, 2022)\n\n- **fixed:** Fix wrong `From` impl for `Resource` ([#1589])\n\n[#1589]: https://github.com/tokio-rs/axum/pull/1589\n\n# 0.4.0 (25. November, 2022)\n\n- **added:** Add `RouterExt::route_with_tsr` for adding routes with an\n  additional \"trailing slash redirect\" route ([#1119])\n- **added:** Support chaining handlers with `HandlerCallWithExtractors::or` ([#1170])\n- **added:** Add Protocol Buffer extractor and response ([#1239])\n- **added:** Add `Either*` types for combining extractors and responses into a\n  single type ([#1263])\n- **added:** `WithRejection` extractor for customizing other extractors' rejections ([#1262])\n- **added:** Add sync constructors to `CookieJar`, `PrivateCookieJar`, and\n  `SignedCookieJar` so they're easier to use in custom middleware\n- **changed:** For methods that accept some `S: Service`, the bounds have been\n  relaxed so the return type can be any type that implements `IntoResponse` rather than being a\n  literal `Response`\n- **change:** axum-extra's MSRV is now 1.60 ([#1239])\n- **breaking:** `Form` has a new rejection type ([#1496])\n- **breaking:** `Query` has a new rejection type ([#1496])\n- **breaking:** `Resource::nest` and `Resource::nest_collection` have been\n  removed. You can instead convert the `Resource` into a `Router` and\n  add additional routes as necessary ([#1086])\n- **breaking:** `SignedCookieJar` and `PrivateCookieJar` now extracts the keys\n  from the router's state, rather than extensions\n- **breaking:** `Resource` has a new `S` type param which represents the state ([#1155])\n- **breaking:** `RouterExt::route_with_tsr` now only accepts `MethodRouter`s ([#1155])\n- **added:** `RouterExt::route_service_with_tsr` for routing to any `Service` ([#1155])\n\n[#1086]: https://github.com/tokio-rs/axum/pull/1086\n[#1119]: https://github.com/tokio-rs/axum/pull/1119\n[#1155]: https://github.com/tokio-rs/axum/pull/1155\n[#1170]: https://github.com/tokio-rs/axum/pull/1170\n[#1214]: https://github.com/tokio-rs/axum/pull/1214\n[#1239]: https://github.com/tokio-rs/axum/pull/1239\n[#1262]: https://github.com/tokio-rs/axum/pull/1262\n[#1263]: https://github.com/tokio-rs/axum/pull/1263\n[#1496]: https://github.com/tokio-rs/axum/pull/1496\n\n<details>\n<summary>0.4.0 Pre-Releases</summary>\n\n# 0.4.0-rc.3 (19. November, 2022)\n\n- **breaking:** Depend axum 0.6.0-rc.5 and axum-macros 0.3.0-rc.3\n\n# 0.4.0-rc.2 (8. November, 2022)\n\n- **breaking:** `Form` has a new rejection type ([#1496])\n- **breaking:** `Query` has a new rejection type ([#1496])\n\n[#1496]: https://github.com/tokio-rs/axum/pull/1496\n\n# 0.4.0-rc.1 (23. August, 2022)\n\n- **added:** Add `RouterExt::route_with_tsr` for adding routes with an\n  additional \"trailing slash redirect\" route ([#1119])\n- **breaking:** `Resource::nest` and `Resource::nest_collection` has been\n  removed. You can instead convert the `Resource` into a `Router` and\n  add additional routes as necessary ([#1086])\n- **changed:** For methods that accept some `S: Service`, the bounds have been\n  relaxed so the response type must implement `IntoResponse` rather than being a\n  literal `Response`\n- **added:** Support chaining handlers with `HandlerCallWithExtractors::or` ([#1170])\n- **change:** axum-extra's MSRV is now 1.60 ([#1239])\n- **breaking:** `SignedCookieJar` and `PrivateCookieJar` now extracts the keys\n  from the router's state, rather than extensions\n- **added:** Add Protocol Buffer extractor and response ([#1239])\n- **added:** Add `Either*` types for combining extractors and responses into a\n  single type ([#1263])\n- **added:** `WithRejection` extractor for customizing other extractors' rejections ([#1262])\n- **added:** Add sync constructors to `CookieJar`, `PrivateCookieJar`, and\n  `SignedCookieJar` so they're easier to use in custom middleware\n- **breaking:** `Resource` has a new `S` type param which represents the state ([#1155])\n- **breaking:** `RouterExt::route_with_tsr` now only accepts `MethodRouter`s ([#1155])\n- **added:** `RouterExt::route_service_with_tsr` for routing to any `Service` ([#1155])\n\n[#1086]: https://github.com/tokio-rs/axum/pull/1086\n[#1119]: https://github.com/tokio-rs/axum/pull/1119\n[#1155]: https://github.com/tokio-rs/axum/pull/1155\n[#1170]: https://github.com/tokio-rs/axum/pull/1170\n[#1214]: https://github.com/tokio-rs/axum/pull/1214\n[#1239]: https://github.com/tokio-rs/axum/pull/1239\n[#1262]: https://github.com/tokio-rs/axum/pull/1262\n[#1263]: https://github.com/tokio-rs/axum/pull/1263\n\n</details>\n\n# 0.3.7 (09. August, 2022)\n\n- **fixed:** Depend on axum 0.5.15 which contains a fix for an accidental breaking change.\n\n# 0.3.6 (02. July, 2022)\n\n- **fixed:** Fix feature labels missing in generated docs ([#1137])\n\n[#1137]: https://github.com/tokio-rs/axum/pull/1137\n\n# 0.3.5 (27. June, 2022)\n\n- **added:** Add `JsonLines` for streaming newline delimited JSON ([#1093])\n- **change:** axum-extra's MSRV is now 1.56 ([#1098])\n\n[#1093]: https://github.com/tokio-rs/axum/pull/1093\n[#1098]: https://github.com/tokio-rs/axum/pull/1098\n\n# 0.3.4 (08. June, 2022)\n\n- **fixed:** Use `impl IntoResponse` less in docs ([#1049])\n- **added:** Add `AsyncReadBody` for creating a body from a `tokio::io::AsyncRead` ([#1072])\n\n[#1049]: https://github.com/tokio-rs/axum/pull/1049\n[#1072]: https://github.com/tokio-rs/axum/pull/1072\n\n# 0.3.3 (18. May, 2022)\n\n- **added:** Add `extract::Query` which supports multi-value items ([#1041])\n- **added:** Support customizing rejections for `#[derive(TypedPath)]` ([#1012])\n\n[#1041]: https://github.com/tokio-rs/axum/pull/1041\n[#1012]: https://github.com/tokio-rs/axum/pull/1012\n\n# 0.3.2 (15. May, 2022)\n\n- **added:** Add `extract::Form` which supports multi-value items ([#1031])\n\n[#1031]: https://github.com/tokio-rs/axum/pull/1031\n\n# 0.3.1 (10. May, 2022)\n\n- **fixed:** `Option` and `Result` are now supported in typed path route handler parameters ([#1001])\n- **fixed:** Support wildcards in typed paths ([#1003])\n- **added:** Support using a custom rejection type for `#[derive(TypedPath)]`\n  instead of `PathRejection` ([#1012])\n\n[#1001]: https://github.com/tokio-rs/axum/pull/1001\n[#1003]: https://github.com/tokio-rs/axum/pull/1003\n[#1012]: https://github.com/tokio-rs/axum/pull/1012\n\n# 0.3.0 (27. April, 2022)\n\n- **fixed:** Don't depend on axum with default features enabled ([#913])\n- **breaking:** Private and signed cookies now requires enabling the\n  `cookie-private` and `cookie-signed` features respectively ([#949])\n- **changed:** Update to tower-http 0.3 ([#965])\n\n[#913]: https://github.com/tokio-rs/axum/pull/913\n[#949]: https://github.com/tokio-rs/axum/pull/949\n[#965]: https://github.com/tokio-rs/axum/pull/965\n\n# 0.2.1 (03. April, 2022)\n\n- **added:** Re-export `SameSite` and `Expiration` from the `cookie` crate ([#898])\n- **added:** Add `PrivateCookieJar` for managing private cookies ([#900])\n- **added:** Add `SpaRouter` for routing setups commonly used for single page applications ([#904])\n- **fixed:** Fix `SignedCookieJar` when using custom key types ([#899])\n\n[#898]: https://github.com/tokio-rs/axum/pull/898\n[#899]: https://github.com/tokio-rs/axum/pull/899\n[#900]: https://github.com/tokio-rs/axum/pull/900\n[#904]: https://github.com/tokio-rs/axum/pull/904\n\n# 0.2.0 (31. March, 2022)\n\n- **added:** Add `TypedPath::to_uri` for converting the path into a `Uri` ([#790])\n- **added:** Extractors and responses for dealing with cookies. See `extract::cookies` for more\n  details ([#816])\n- **breaking:** `CachedRejection` has been removed ([#699])\n- **breaking:** `<Cached<T> as FromRequest>::Rejection` is now `T::Rejection`. ([#699])\n- **breaking:** `middleware::from_fn` has been remove from axum-extra and moved into the main\n  axum crate ([#719])\n- **breaking:** `HasRoutes` has been removed. `Router::merge` now accepts `Into<Router>` ([#819])\n- **breaking:** `RouterExt::with` method has been removed. Use `Router::merge` instead. It works\n  identically ([#819])\n\n[#699]: https://github.com/tokio-rs/axum/pull/699\n[#719]: https://github.com/tokio-rs/axum/pull/719\n[#790]: https://github.com/tokio-rs/axum/pull/790\n[#816]: https://github.com/tokio-rs/axum/pull/816\n[#819]: https://github.com/tokio-rs/axum/pull/819\n\n# 0.1.5 (1. March, 2022)\n\n- **added:** Add `TypedPath::to_uri` for converting the path into a `Uri` ([#790])\n\n[#790]: https://github.com/tokio-rs/axum/pull/790\n\n# 0.1.4 (22. February, 2022)\n\n- **fix:** Depend on the right versions of axum and axum-macros ([#782])\n\n[#782]: https://github.com/tokio-rs/axum/pull/782\n\n# 0.1.3 (22. February, 2022)\n\n- **added:** Add type safe routing. See `axum_extra::routing::typed` for more details ([#756])\n- **fix:** Depend on tower with `default_features = false` ([#666])\n- **change:** `middleware::from_fn` has been deprecated and moved into the main\n  axum crate ([#719])\n\n[#666]: https://github.com/tokio-rs/axum/pull/666\n[#719]: https://github.com/tokio-rs/axum/pull/719\n[#756]: https://github.com/tokio-rs/axum/pull/756\n\n# 0.1.2 (13. January, 2022)\n\n- **fix:** Depend on tower with `default_features = false` ([#666])\n\n# 0.1.1 (27. December, 2021)\n\n- Add `middleware::from_fn` for creating middleware from async functions ([#656])\n- Add support for returning pretty JSON response in `response::ErasedJson` ([#662])\n\n[#656]: https://github.com/tokio-rs/axum/pull/656\n[#662]: https://github.com/tokio-rs/axum/pull/662\n\n# 0.1.0 (02. December, 2021)\n\n- Initial release.\n\n[Keep a Changelog]: https://keepachangelog.com/en/1.0.0/\n[Semantic Versioning]: https://semver.org/spec/v2.0.0.html\n"
  },
  {
    "path": "axum-extra/Cargo.toml",
    "content": "[package]\ncategories = [\"asynchronous\", \"network-programming\", \"web-programming\"]\ndescription = \"Extra utilities for axum\"\nedition = \"2021\"\nrust-version = { workspace = true }\nhomepage = \"https://github.com/tokio-rs/axum\"\nkeywords = [\"http\", \"web\", \"routing\"]\nlicense = \"MIT\"\nname = \"axum-extra\"\nreadme = \"README.md\"\nrepository = \"https://github.com/tokio-rs/axum\"\nversion = \"0.12.5\"\n\n[package.metadata.docs.rs]\nall-features = true\n\n[package.metadata.cargo_check_external_types]\nallowed_external_types = [\n    \"axum::*\",\n    \"axum_core::*\",\n    \"axum_macros::*\",\n    \"bytes::*\",\n    \"cookie::*\",\n    \"futures_core::*\",\n    \"futures_util::*\",\n    \"headers\",\n    \"headers_core::*\",\n    \"http::*\",\n    \"http_body::*\",\n    \"prost::*\",\n    \"serde_core::*\",\n    \"tokio::*\",\n    \"tower_layer::*\",\n    \"tower_service::*\",\n]\n\n[features]\ndefault = [\"tracing\"]\n\nasync-read-body = [\"dep:tokio-util\", \"tokio-util?/io\", \"dep:tokio\"]\ncached = [\"dep:axum\"]\nfile-stream = [\n    \"dep:tokio-util\",\n    \"tokio-util?/io\",\n    \"dep:tokio\",\n    \"tokio?/fs\",\n    \"tokio?/io-util\",\n]\nattachment = [\"dep:tracing\"]\nerror-response = [\"dep:tracing\", \"tracing/std\"]\ncookie = [\"dep:cookie\"]\ncookie-private = [\"cookie\", \"cookie?/private\"]\ncookie-signed = [\"cookie\", \"cookie?/signed\"]\ncookie-key-expansion = [\"cookie\", \"cookie?/key-expansion\"]\nerased-json = [\"dep:serde_core\", \"dep:serde_json\", \"dep:typed-json\"]\nform = [\n    \"dep:axum\",\n    \"dep:form_urlencoded\",\n    \"dep:serde_core\",\n    \"dep:serde_html_form\",\n    \"dep:serde_path_to_error\",\n]\nhandler = [\"dep:axum\"]\njson-deserializer = [\"dep:serde_core\", \"dep:serde_json\", \"dep:serde_path_to_error\"]\njson-lines = [\n    \"dep:serde_core\",\n    \"dep:serde_json\",\n    \"dep:tokio-util\",\n    \"dep:tokio-stream\",\n    \"tokio-util?/io\",\n    \"tokio-stream?/io-util\",\n    \"dep:tokio\",\n]\nmiddleware = [\"dep:axum\"]\nmultipart = [\"dep:multer\", \"dep:fastrand\"]\nprotobuf = [\"dep:prost\"]\nrouting = [\"axum/original-uri\", \"dep:rustversion\"]\nquery = [\n    \"dep:form_urlencoded\",\n    \"dep:serde_core\",\n    \"dep:serde_html_form\",\n    \"dep:serde_path_to_error\",\n]\ntracing = [\"axum-core/tracing\", \"axum/tracing\", \"dep:tracing\"]\ntyped-header = [\"dep:headers\"]\ntyped-routing = [\n    \"routing\",\n    \"dep:axum-macros\",\n    \"dep:percent-encoding\",\n    \"dep:serde_core\",\n    \"dep:serde_html_form\",\n    \"dep:form_urlencoded\",\n]\nwith-rejection = [\"dep:axum\"]\n\n# Enabled by docs.rs because it uses all-features\n# Enables upstream things linked to in docs\n__private_docs = [\"axum/json\", \"axum/query\", \"dep:serde\", \"dep:tower\"]\n\n[dependencies]\naxum-core = { path = \"../axum-core\", version = \"0.5.6\" }\nbytes = \"1.1.0\"\nfutures-core = \"0.3\"\nfutures-util = { version = \"0.3\", default-features = false, features = [\"alloc\"] }\nhttp = \"1.0.0\"\nhttp-body = \"1.0.0\"\nhttp-body-util = \"0.1.0\"\nmime = \"0.3\"\npin-project-lite = \"0.2\"\ntower-layer = \"0.3\"\ntower-service = \"0.3\"\n\n# optional dependencies\naxum = { path = \"../axum\", version = \"0.8.8\", default-features = false, optional = true }\naxum-macros = { path = \"../axum-macros\", version = \"0.5.0\", optional = true }\ncookie = { package = \"cookie\", version = \"0.18.0\", features = [\"percent-encode\"], optional = true }\nfastrand = { version = \"2.1.0\", optional = true }\nform_urlencoded = { version = \"1.1.0\", optional = true }\nheaders = { version = \"0.4.0\", optional = true }\nmulter = { version = \"3.0.0\", optional = true }\npercent-encoding = { version = \"2.1\", optional = true }\nprost = { version = \"0.14\", optional = true }\nrustversion = { version = \"1.0.9\", optional = true }\nserde_core = { version = \"1.0.221\", optional = true }\n# DO NOT update. axum itself uses serde_html_form 0.3.x which has slightly\n# different behavior in some edge cases. This feature here is kept (deprecated)\n# to let people transition to that easier (fewer breaking changes to deal with\n# at once if they keep using axum_extra's `Query` / `Form` initially when going\n# to axum 0.9).\nserde_html_form = { version = \"0.2.0\", optional = true }\nserde_json = { version = \"1.0.71\", optional = true }\nserde_path_to_error = { version = \"0.1.8\", optional = true }\ntokio = { version = \"1.19\", optional = true }\ntokio-stream = { version = \"0.1.9\", optional = true }\ntokio-util = { version = \"0.7\", optional = true }\ntracing = { version = \"0.1.37\", default-features = false, optional = true }\ntyped-json = { version = \"0.1.1\", optional = true }\n\n# doc dependencies\nserde = { version = \"1.0.221\", optional = true }\ntower = { version = \"0.5.2\", default-features = false, features = [\"util\"], optional = true }\n\n[dev-dependencies]\naxum = { path = \"../axum\", features = [\"macros\", \"__private\"] }\naxum-macros = { path = \"../axum-macros\", features = [\"__private\"] }\nhyper = \"1.0.0\"\nreqwest = { version = \"0.12\", default-features = false, features = [\"json\", \"stream\", \"multipart\"] }\nserde = { version = \"1.0.221\", features = [\"derive\"] }\nserde_json = \"1.0.71\"\ntempfile = \"3.23.0\"\ntokio = { version = \"1.14\", features = [\"full\"] }\ntower = { version = \"0.5.2\", features = [\"util\"] }\ntower-http = { version = \"0.6.0\", features = [\"map-response-body\", \"timeout\"] }\ntracing-subscriber = \"0.3.20\"\n\n[lints]\nworkspace = true\n"
  },
  {
    "path": "axum-extra/README.md",
    "content": "# axum-extra\n\n[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum-extra/actions/workflows/CI.yml)\n[![Crates.io](https://img.shields.io/crates/v/axum-extra)](https://crates.io/crates/axum-extra)\n[![Documentation](https://docs.rs/axum-extra/badge.svg)](https://docs.rs/axum-extra)\n\nExtra utilities for [`axum`].\n\nMore information about this crate can be found in the [crate documentation][docs].\n\n## Safety\n\nThis crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% safe Rust.\n\n## Minimum supported Rust version\n\naxum-extra's MSRV is 1.75.\n\n## Getting Help\n\nYou're also welcome to ask in the [Discord channel][chat] or open an [issue]\nwith your question.\n\n## Contributing\n\n🎈 Thanks for your help improving the project! We are so happy to have\nyou! We have a [contributing guide][contributing] to help you get involved in the\n`axum` project.\n\n## License\n\nThis project is licensed under the [MIT license][license].\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `axum` by you, shall be licensed as MIT, without any\nadditional terms or conditions.\n\n[`axum`]: https://crates.io/crates/axum\n[chat]: https://discord.gg/tokio\n[contributing]: /CONTRIBUTING.md\n[docs]: https://docs.rs/axum-extra\n[license]: /axum-extra/LICENSE\n[issue]: https://github.com/tokio-rs/axum/issues/new\n"
  },
  {
    "path": "axum-extra/src/body/async_read_body.rs",
    "content": "use axum_core::{\n    body::Body,\n    response::{IntoResponse, Response},\n    Error,\n};\nuse bytes::Bytes;\nuse http_body::Body as HttpBody;\nuse pin_project_lite::pin_project;\nuse std::{\n    pin::Pin,\n    task::{Context, Poll},\n};\nuse tokio::io::AsyncRead;\nuse tokio_util::io::ReaderStream;\n\npin_project! {\n    /// An [`HttpBody`] created from an [`AsyncRead`].\n    ///\n    /// # Example\n    ///\n    /// `AsyncReadBody` can be used to stream the contents of a file:\n    ///\n    /// ```rust\n    /// use axum::{\n    ///     Router,\n    ///     routing::get,\n    ///     http::{StatusCode, header::CONTENT_TYPE},\n    ///     response::{Response, IntoResponse},\n    /// };\n    /// use axum_extra::body::AsyncReadBody;\n    /// use tokio::fs::File;\n    ///\n    /// async fn cargo_toml() -> Result<Response, (StatusCode, String)> {\n    ///     let file = File::open(\"Cargo.toml\")\n    ///         .await\n    ///         .map_err(|err| {\n    ///             (StatusCode::NOT_FOUND, format!(\"File not found: {err}\"))\n    ///         })?;\n    ///\n    ///     let headers = [(CONTENT_TYPE, \"text/x-toml\")];\n    ///     let body = AsyncReadBody::new(file);\n    ///     Ok((headers, body).into_response())\n    /// }\n    ///\n    /// let app = Router::new().route(\"/Cargo.toml\", get(cargo_toml));\n    /// # let _: Router = app;\n    /// ```\n    #[cfg(feature = \"async-read-body\")]\n    #[derive(Debug)]\n    #[must_use]\n    pub struct AsyncReadBody {\n        #[pin]\n        body: Body,\n    }\n}\n\nimpl AsyncReadBody {\n    /// Create a new `AsyncReadBody`.\n    pub fn new<R>(read: R) -> Self\n    where\n        R: AsyncRead + Send + 'static,\n    {\n        Self {\n            body: Body::from_stream(ReaderStream::new(read)),\n        }\n    }\n}\n\nimpl HttpBody for AsyncReadBody {\n    type Data = Bytes;\n    type Error = Error;\n\n    #[inline]\n    fn poll_frame(\n        self: Pin<&mut Self>,\n        cx: &mut Context<'_>,\n    ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> {\n        self.project().body.poll_frame(cx)\n    }\n\n    #[inline]\n    fn is_end_stream(&self) -> bool {\n        self.body.is_end_stream()\n    }\n\n    #[inline]\n    fn size_hint(&self) -> http_body::SizeHint {\n        self.body.size_hint()\n    }\n}\n\nimpl IntoResponse for AsyncReadBody {\n    fn into_response(self) -> Response {\n        self.body.into_response()\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/body/mod.rs",
    "content": "//! Additional bodies.\n\n#[cfg(feature = \"async-read-body\")]\nmod async_read_body;\n\n#[cfg(feature = \"async-read-body\")]\npub use self::async_read_body::AsyncReadBody;\n"
  },
  {
    "path": "axum-extra/src/either.rs",
    "content": "//! `Either*` types for combining extractors or responses into a single type.\n//!\n//! # As an extractor\n//!\n//! ```\n//! use axum_extra::either::Either3;\n//! use axum::{\n//!     body::Bytes,\n//!     Router,\n//!     routing::get,\n//!     extract::FromRequestParts,\n//! };\n//!\n//! // extractors for checking permissions\n//! struct AdminPermissions {}\n//!\n//! impl<S> FromRequestParts<S> for AdminPermissions\n//! where\n//!     S: Send + Sync,\n//! {\n//!     // check for admin permissions...\n//!     # type Rejection = ();\n//!     # async fn from_request_parts(parts: &mut axum::http::request::Parts, state: &S) -> Result<Self, Self::Rejection> {\n//!     #     todo!()\n//!     # }\n//! }\n//!\n//! struct User {}\n//!\n//! impl<S> FromRequestParts<S> for User\n//! where\n//!     S: Send + Sync,\n//! {\n//!     // check for a logged in user...\n//!     # type Rejection = ();\n//!     # async fn from_request_parts(parts: &mut axum::http::request::Parts, state: &S) -> Result<Self, Self::Rejection> {\n//!     #     todo!()\n//!     # }\n//! }\n//!\n//! async fn handler(\n//!     body: Either3<AdminPermissions, User, ()>,\n//! ) {\n//!     match body {\n//!         Either3::E1(admin) => { /* ... */ }\n//!         Either3::E2(user) => { /* ... */ }\n//!         Either3::E3(guest) => { /* ... */ }\n//!     }\n//! }\n//! #\n//! # let _: axum::routing::MethodRouter = axum::routing::get(handler);\n//! ```\n//!\n//! Note that if all the inner extractors reject the request, the rejection from the last\n//! extractor will be returned. For the example above that would be [`BytesRejection`].\n//!\n//! # As a response\n//!\n//! ```\n//! use axum_extra::either::Either3;\n//! use axum::{Json, http::StatusCode, response::IntoResponse};\n//! use serde_json::{Value, json};\n//!\n//! async fn handler() -> Either3<Json<Value>, &'static str, StatusCode> {\n//!     if something() {\n//!         Either3::E1(Json(json!({ \"data\": \"...\" })))\n//!     } else if something_else() {\n//!         Either3::E2(\"foobar\")\n//!     } else {\n//!         Either3::E3(StatusCode::NOT_FOUND)\n//!     }\n//! }\n//!\n//! fn something() -> bool {\n//!     // ...\n//!     # false\n//! }\n//!\n//! fn something_else() -> bool {\n//!     // ...\n//!     # false\n//! }\n//! #\n//! # let _: axum::routing::MethodRouter = axum::routing::get(handler);\n//! ```\n//!\n//! The general recommendation is to use [`IntoResponse::into_response`] to return different response\n//! types, but if you need to preserve the exact type then `Either*` works as well.\n//!\n//! [`BytesRejection`]: axum::extract::rejection::BytesRejection\n//! [`IntoResponse::into_response`]: https://docs.rs/axum/0.8/axum/response/index.html#returning-different-response-types\n\nuse std::task::{Context, Poll};\n\nuse axum_core::{\n    extract::FromRequestParts,\n    response::{IntoResponse, Response},\n};\nuse http::request::Parts;\nuse tower_layer::Layer;\nuse tower_service::Service;\n\n/// Combines two extractors or responses into a single type.\n///\n/// See the [module docs](self) for examples.\n#[derive(Debug, Clone)]\n#[must_use]\npub enum Either<E1, E2> {\n    #[allow(missing_docs)]\n    E1(E1),\n    #[allow(missing_docs)]\n    E2(E2),\n}\n\n/// Combines three extractors or responses into a single type.\n///\n/// See the [module docs](self) for examples.\n#[derive(Debug, Clone)]\n#[must_use]\npub enum Either3<E1, E2, E3> {\n    #[allow(missing_docs)]\n    E1(E1),\n    #[allow(missing_docs)]\n    E2(E2),\n    #[allow(missing_docs)]\n    E3(E3),\n}\n\n/// Combines four extractors or responses into a single type.\n///\n/// See the [module docs](self) for examples.\n#[derive(Debug, Clone)]\n#[must_use]\npub enum Either4<E1, E2, E3, E4> {\n    #[allow(missing_docs)]\n    E1(E1),\n    #[allow(missing_docs)]\n    E2(E2),\n    #[allow(missing_docs)]\n    E3(E3),\n    #[allow(missing_docs)]\n    E4(E4),\n}\n\n/// Combines five extractors or responses into a single type.\n///\n/// See the [module docs](self) for examples.\n#[derive(Debug, Clone)]\n#[must_use]\npub enum Either5<E1, E2, E3, E4, E5> {\n    #[allow(missing_docs)]\n    E1(E1),\n    #[allow(missing_docs)]\n    E2(E2),\n    #[allow(missing_docs)]\n    E3(E3),\n    #[allow(missing_docs)]\n    E4(E4),\n    #[allow(missing_docs)]\n    E5(E5),\n}\n\n/// Combines six extractors or responses into a single type.\n///\n/// See the [module docs](self) for examples.\n#[derive(Debug, Clone)]\n#[must_use]\npub enum Either6<E1, E2, E3, E4, E5, E6> {\n    #[allow(missing_docs)]\n    E1(E1),\n    #[allow(missing_docs)]\n    E2(E2),\n    #[allow(missing_docs)]\n    E3(E3),\n    #[allow(missing_docs)]\n    E4(E4),\n    #[allow(missing_docs)]\n    E5(E5),\n    #[allow(missing_docs)]\n    E6(E6),\n}\n\n/// Combines seven extractors or responses into a single type.\n///\n/// See the [module docs](self) for examples.\n#[derive(Debug, Clone)]\n#[must_use]\npub enum Either7<E1, E2, E3, E4, E5, E6, E7> {\n    #[allow(missing_docs)]\n    E1(E1),\n    #[allow(missing_docs)]\n    E2(E2),\n    #[allow(missing_docs)]\n    E3(E3),\n    #[allow(missing_docs)]\n    E4(E4),\n    #[allow(missing_docs)]\n    E5(E5),\n    #[allow(missing_docs)]\n    E6(E6),\n    #[allow(missing_docs)]\n    E7(E7),\n}\n\n/// Combines eight extractors or responses into a single type.\n///\n/// See the [module docs](self) for examples.\n#[derive(Debug, Clone)]\n#[must_use]\npub enum Either8<E1, E2, E3, E4, E5, E6, E7, E8> {\n    #[allow(missing_docs)]\n    E1(E1),\n    #[allow(missing_docs)]\n    E2(E2),\n    #[allow(missing_docs)]\n    E3(E3),\n    #[allow(missing_docs)]\n    E4(E4),\n    #[allow(missing_docs)]\n    E5(E5),\n    #[allow(missing_docs)]\n    E6(E6),\n    #[allow(missing_docs)]\n    E7(E7),\n    #[allow(missing_docs)]\n    E8(E8),\n}\n\nmacro_rules! impl_traits_for_either {\n    (\n        $either:ident =>\n        [$($ident:ident),* $(,)?],\n        $last:ident $(,)?\n    ) => {\n        impl<S, $($ident),*, $last> FromRequestParts<S> for $either<$($ident),*, $last>\n        where\n            $($ident: FromRequestParts<S>),*,\n            $last: FromRequestParts<S>,\n            S: Send + Sync,\n        {\n            type Rejection = $last::Rejection;\n\n            async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n                $(\n                    if let Ok(value) = <$ident as FromRequestParts<S>>::from_request_parts(parts, state).await {\n                        return Ok(Self::$ident(value));\n                    }\n                )*\n\n                <$last as FromRequestParts<S>>::from_request_parts(parts, state).await.map(Self::$last)\n            }\n        }\n\n        impl<$($ident),*, $last> IntoResponse for $either<$($ident),*, $last>\n        where\n            $($ident: IntoResponse),*,\n            $last: IntoResponse,\n        {\n            fn into_response(self) -> Response {\n                match self {\n                    $( Self::$ident(value) => value.into_response(), )*\n                    Self::$last(value) => value.into_response(),\n                }\n            }\n        }\n    };\n}\n\nimpl_traits_for_either!(Either => [E1], E2);\nimpl_traits_for_either!(Either3 => [E1, E2], E3);\nimpl_traits_for_either!(Either4 => [E1, E2, E3], E4);\nimpl_traits_for_either!(Either5 => [E1, E2, E3, E4], E5);\nimpl_traits_for_either!(Either6 => [E1, E2, E3, E4, E5], E6);\nimpl_traits_for_either!(Either7 => [E1, E2, E3, E4, E5, E6], E7);\nimpl_traits_for_either!(Either8 => [E1, E2, E3, E4, E5, E6, E7], E8);\n\nimpl<E1, E2, S> Layer<S> for Either<E1, E2>\nwhere\n    E1: Layer<S>,\n    E2: Layer<S>,\n{\n    type Service = Either<E1::Service, E2::Service>;\n\n    fn layer(&self, inner: S) -> Self::Service {\n        match self {\n            Self::E1(layer) => Either::E1(layer.layer(inner)),\n            Self::E2(layer) => Either::E2(layer.layer(inner)),\n        }\n    }\n}\n\nimpl<R, E1, E2> Service<R> for Either<E1, E2>\nwhere\n    E1: Service<R>,\n    E2: Service<R, Response = E1::Response, Error = E1::Error>,\n{\n    type Response = E1::Response;\n    type Error = E1::Error;\n    type Future = futures_util::future::Either<E1::Future, E2::Future>;\n\n    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        match self {\n            Self::E1(inner) => inner.poll_ready(cx),\n            Self::E2(inner) => inner.poll_ready(cx),\n        }\n    }\n\n    fn call(&mut self, req: R) -> Self::Future {\n        match self {\n            Self::E1(inner) => futures_util::future::Either::Left(inner.call(req)),\n            Self::E2(inner) => futures_util::future::Either::Right(inner.call(req)),\n        }\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/cached.rs",
    "content": "use axum::extract::FromRequestParts;\nuse http::request::Parts;\n\n/// Cache results of other extractors.\n///\n/// `Cached` wraps another extractor and caches its result in [request extensions].\n///\n/// This is useful if you have a tree of extractors that share common sub-extractors that\n/// you only want to run once, perhaps because they're expensive.\n///\n/// The cache purely type based so you can only cache one value of each type. The cache is also\n/// local to the current request and not reused across requests.\n///\n/// # Example\n///\n/// ```rust\n/// use axum_extra::extract::Cached;\n/// use axum::{\n///     extract::FromRequestParts,\n///     response::{IntoResponse, Response},\n///     http::{StatusCode, request::Parts},\n/// };\n///\n/// #[derive(Clone)]\n/// struct Session { /* ... */ }\n///\n/// impl<S> FromRequestParts<S> for Session\n/// where\n///     S: Send + Sync,\n/// {\n///     type Rejection = (StatusCode, String);\n///\n///     async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n///         // load session...\n///         # unimplemented!()\n///     }\n/// }\n///\n/// struct CurrentUser { /* ... */ }\n///\n/// impl<S> FromRequestParts<S> for CurrentUser\n/// where\n///     S: Send + Sync,\n/// {\n///     type Rejection = Response;\n///\n///     async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n///         // loading a `CurrentUser` requires first loading the `Session`\n///         //\n///         // by using `Cached<Session>` we avoid extracting the session more than\n///         // once, in case other extractors for the same request also loads the session\n///         let session: Session = Cached::<Session>::from_request_parts(parts, state)\n///             .await\n///             .map_err(|err| err.into_response())?\n///             .0;\n///\n///         // load user from session...\n///         # unimplemented!()\n///     }\n/// }\n///\n/// // handler that extracts the current user and the session\n/// //\n/// // the session will only be loaded once, even though `CurrentUser`\n/// // also loads it\n/// async fn handler(\n///     current_user: CurrentUser,\n///     // we have to use `Cached<Session>` here otherwise the\n///     // cached session would not be used\n///     Cached(session): Cached<Session>,\n/// ) {\n///     // ...\n/// }\n/// ```\n///\n/// [request extensions]: http::Extensions\n#[derive(Debug, Clone, Default)]\npub struct Cached<T>(pub T);\n\n#[derive(Clone)]\nstruct CachedEntry<T>(T);\n\nimpl<S, T> FromRequestParts<S> for Cached<T>\nwhere\n    S: Send + Sync,\n    T: FromRequestParts<S> + Clone + Send + Sync + 'static,\n{\n    type Rejection = T::Rejection;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        if let Some(value) = parts.extensions.get::<CachedEntry<T>>() {\n            Ok(Self(value.0.clone()))\n        } else {\n            let value = T::from_request_parts(parts, state).await?;\n            parts.extensions.insert(CachedEntry(value.clone()));\n            Ok(Self(value))\n        }\n    }\n}\n\naxum_core::__impl_deref!(Cached);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{http::Request, routing::get, Router};\n    use std::{\n        convert::Infallible,\n        sync::atomic::{AtomicU32, Ordering},\n        time::Instant,\n    };\n\n    #[tokio::test]\n    async fn works() {\n        static COUNTER: AtomicU32 = AtomicU32::new(0);\n\n        #[derive(Clone, Debug, PartialEq, Eq)]\n        struct Extractor(Instant);\n\n        impl<S> FromRequestParts<S> for Extractor\n        where\n            S: Send + Sync,\n        {\n            type Rejection = Infallible;\n\n            async fn from_request_parts(\n                _parts: &mut Parts,\n                _state: &S,\n            ) -> Result<Self, Self::Rejection> {\n                COUNTER.fetch_add(1, Ordering::SeqCst);\n                Ok(Self(Instant::now()))\n            }\n        }\n\n        let (mut parts, _) = Request::new(()).into_parts();\n\n        let first = Cached::<Extractor>::from_request_parts(&mut parts, &())\n            .await\n            .unwrap()\n            .0;\n        assert_eq!(COUNTER.load(Ordering::SeqCst), 1);\n\n        let second = Cached::<Extractor>::from_request_parts(&mut parts, &())\n            .await\n            .unwrap()\n            .0;\n        assert_eq!(COUNTER.load(Ordering::SeqCst), 1);\n\n        assert_eq!(first, second);\n    }\n\n    // Not a #[test], we just want to know this compiles\n    async fn _last_handler_argument() {\n        async fn handler(_: http::Method, _: Cached<http::HeaderMap>) {}\n        let _r: Router = Router::new().route(\"/\", get(handler));\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/cookie/mod.rs",
    "content": "//! Cookie parsing and cookie jar management.\n//!\n//! See [`CookieJar`], [`SignedCookieJar`], and [`PrivateCookieJar`] for more details.\n\nuse axum_core::{\n    extract::FromRequestParts,\n    response::{IntoResponse, IntoResponseParts, Response, ResponseParts},\n};\nuse http::{\n    header::{COOKIE, SET_COOKIE},\n    request::Parts,\n    HeaderMap,\n};\nuse std::convert::Infallible;\n\n#[cfg(feature = \"cookie-private\")]\nmod private;\n#[cfg(feature = \"cookie-signed\")]\nmod signed;\n\n#[cfg(feature = \"cookie-private\")]\npub use self::private::PrivateCookieJar;\n#[cfg(feature = \"cookie-signed\")]\npub use self::signed::SignedCookieJar;\n\npub use cookie::{Cookie, Expiration, SameSite};\n\n#[cfg(any(feature = \"cookie-signed\", feature = \"cookie-private\"))]\npub use cookie::Key;\n\n/// Extractor that grabs cookies from the request and manages the jar.\n///\n/// Note that methods like [`CookieJar::add`], [`CookieJar::remove`], etc updates the [`CookieJar`]\n/// and returns it. This value _must_ be returned from the handler as part of the response for the\n/// changes to be propagated.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     routing::{post, get},\n///     response::{IntoResponse, Redirect},\n///     http::StatusCode,\n/// };\n/// use axum_extra::{\n///     TypedHeader,\n///     headers::authorization::{Authorization, Bearer},\n///     extract::cookie::{CookieJar, Cookie},\n/// };\n///\n/// async fn create_session(\n///     TypedHeader(auth): TypedHeader<Authorization<Bearer>>,\n///     jar: CookieJar,\n/// ) -> Result<(CookieJar, Redirect), StatusCode> {\n///     if let Some(session_id) = authorize_and_create_session(auth.token()).await {\n///         Ok((\n///             // the updated jar must be returned for the changes\n///             // to be included in the response\n///             jar.add(Cookie::new(\"session_id\", session_id)),\n///             Redirect::to(\"/me\"),\n///         ))\n///     } else {\n///         Err(StatusCode::UNAUTHORIZED)\n///     }\n/// }\n///\n/// async fn me(jar: CookieJar) -> Result<(), StatusCode> {\n///     if let Some(session_id) = jar.get(\"session_id\") {\n///         // fetch and render user...\n///         # Ok(())\n///     } else {\n///         Err(StatusCode::UNAUTHORIZED)\n///     }\n/// }\n///\n/// async fn authorize_and_create_session(token: &str) -> Option<String> {\n///     // authorize the user and create a session...\n///     # todo!()\n/// }\n///\n/// let app = Router::new()\n///     .route(\"/sessions\", post(create_session))\n///     .route(\"/me\", get(me));\n/// # let app: Router = app;\n/// ```\n#[must_use = \"`CookieJar` should be returned as part of a `Response`, otherwise it does nothing.\"]\n#[derive(Debug, Default, Clone)]\npub struct CookieJar {\n    jar: cookie::CookieJar,\n}\n\nimpl<S> FromRequestParts<S> for CookieJar\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        Ok(Self::from_headers(&parts.headers))\n    }\n}\n\nfn cookies_from_request(headers: &HeaderMap) -> impl Iterator<Item = Cookie<'static>> + '_ {\n    headers\n        .get_all(COOKIE)\n        .into_iter()\n        .filter_map(|value| value.to_str().ok())\n        .flat_map(|value| value.split(';'))\n        .filter_map(|cookie| Cookie::parse_encoded(cookie.to_owned()).ok())\n}\n\nimpl CookieJar {\n    /// Create a new `CookieJar` from a map of request headers.\n    ///\n    /// The cookies in `headers` will be added to the jar.\n    ///\n    /// This is intended to be used in middleware and other places where it might be difficult to\n    /// run extractors. Normally you should create `CookieJar`s through [`FromRequestParts`].\n    ///\n    /// [`FromRequestParts`]: axum::extract::FromRequestParts\n    pub fn from_headers(headers: &HeaderMap) -> Self {\n        let mut jar = cookie::CookieJar::new();\n        for cookie in cookies_from_request(headers) {\n            jar.add_original(cookie);\n        }\n        Self { jar }\n    }\n\n    /// Create a new empty `CookieJar`.\n    ///\n    /// This is intended to be used in middleware and other places where it might be difficult to\n    /// run extractors. Normally you should create `CookieJar`s through [`FromRequestParts`].\n    ///\n    /// If you need a jar that contains the headers from a request use `impl From<&HeaderMap> for\n    /// CookieJar`.\n    ///\n    /// [`FromRequestParts`]: axum::extract::FromRequestParts\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    /// Get a cookie from the jar.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::CookieJar;\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: CookieJar) {\n    ///     let value: Option<String> = jar\n    ///         .get(\"foo\")\n    ///         .map(|cookie| cookie.value().to_owned());\n    /// }\n    /// ```\n    #[must_use]\n    pub fn get(&self, name: &str) -> Option<&Cookie<'static>> {\n        self.jar.get(name)\n    }\n\n    /// Remove a cookie from the jar.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::{CookieJar, Cookie};\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: CookieJar) -> CookieJar {\n    ///     jar.remove(Cookie::from(\"foo\"))\n    /// }\n    /// ```\n    pub fn remove<C: Into<Cookie<'static>>>(mut self, cookie: C) -> Self {\n        self.jar.remove(cookie);\n        self\n    }\n\n    /// Add a cookie to the jar.\n    ///\n    /// The value will automatically be percent-encoded.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::{CookieJar, Cookie};\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: CookieJar) -> CookieJar {\n    ///     jar.add(Cookie::new(\"foo\", \"bar\"))\n    /// }\n    /// ```\n    #[allow(clippy::should_implement_trait)]\n    pub fn add<C: Into<Cookie<'static>>>(mut self, cookie: C) -> Self {\n        self.jar.add(cookie);\n        self\n    }\n\n    /// Get an iterator over all cookies in the jar.\n    pub fn iter(&self) -> impl Iterator<Item = &'_ Cookie<'static>> {\n        self.jar.iter()\n    }\n}\n\nimpl IntoResponseParts for CookieJar {\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        set_cookies(&self.jar, res.headers_mut());\n        Ok(res)\n    }\n}\n\nimpl IntoResponse for CookieJar {\n    fn into_response(self) -> Response {\n        (self, ()).into_response()\n    }\n}\n\nfn set_cookies(jar: &cookie::CookieJar, headers: &mut HeaderMap) {\n    for cookie in jar.delta() {\n        if let Ok(header_value) = cookie.encoded().to_string().parse() {\n            headers.append(SET_COOKIE, header_value);\n        }\n    }\n\n    // we don't need to call `jar.reset_delta()` because `into_response_parts` consumes the cookie\n    // jar so it cannot be called multiple times.\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{body::Body, extract::FromRef, http::Request, routing::get, Router};\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    macro_rules! cookie_test {\n        ($name:ident, $jar:ty) => {\n            #[tokio::test]\n            async fn $name() {\n                async fn set_cookie(jar: $jar) -> impl IntoResponse {\n                    jar.add(Cookie::new(\"key\", \"value\"))\n                }\n\n                async fn get_cookie(jar: $jar) -> impl IntoResponse {\n                    jar.get(\"key\").unwrap().value().to_owned()\n                }\n\n                async fn remove_cookie(jar: $jar) -> impl IntoResponse {\n                    jar.remove(Cookie::from(\"key\"))\n                }\n\n                let state = AppState {\n                    key: Key::generate(),\n                    custom_key: CustomKey(Key::generate()),\n                };\n\n                let app = Router::new()\n                    .route(\"/set\", get(set_cookie))\n                    .route(\"/get\", get(get_cookie))\n                    .route(\"/remove\", get(remove_cookie))\n                    .with_state(state);\n\n                let res = app\n                    .clone()\n                    .oneshot(Request::builder().uri(\"/set\").body(Body::empty()).unwrap())\n                    .await\n                    .unwrap();\n                let cookie_value = res.headers()[\"set-cookie\"].to_str().unwrap();\n\n                let res = app\n                    .clone()\n                    .oneshot(\n                        Request::builder()\n                            .uri(\"/get\")\n                            .header(\"cookie\", cookie_value)\n                            .body(Body::empty())\n                            .unwrap(),\n                    )\n                    .await\n                    .unwrap();\n                let body = body_text(res).await;\n                assert_eq!(body, \"value\");\n\n                let res = app\n                    .clone()\n                    .oneshot(\n                        Request::builder()\n                            .uri(\"/remove\")\n                            .header(\"cookie\", cookie_value)\n                            .body(Body::empty())\n                            .unwrap(),\n                    )\n                    .await\n                    .unwrap();\n                assert!(res.headers()[\"set-cookie\"]\n                    .to_str()\n                    .unwrap()\n                    .contains(\"key=;\"));\n            }\n        };\n    }\n\n    cookie_test!(plaintext_cookies, CookieJar);\n\n    #[cfg(feature = \"cookie-signed\")]\n    cookie_test!(signed_cookies, SignedCookieJar);\n    #[cfg(feature = \"cookie-signed\")]\n    cookie_test!(signed_cookies_with_custom_key, SignedCookieJar<CustomKey>);\n\n    #[cfg(feature = \"cookie-private\")]\n    cookie_test!(private_cookies, PrivateCookieJar);\n    #[cfg(feature = \"cookie-private\")]\n    cookie_test!(private_cookies_with_custom_key, PrivateCookieJar<CustomKey>);\n\n    #[derive(Clone)]\n    struct AppState {\n        key: Key,\n        custom_key: CustomKey,\n    }\n\n    impl FromRef<AppState> for Key {\n        fn from_ref(state: &AppState) -> Self {\n            state.key.clone()\n        }\n    }\n\n    impl FromRef<AppState> for CustomKey {\n        fn from_ref(state: &AppState) -> Self {\n            state.custom_key.clone()\n        }\n    }\n\n    #[derive(Clone)]\n    struct CustomKey(Key);\n\n    impl From<CustomKey> for Key {\n        fn from(custom: CustomKey) -> Self {\n            custom.0\n        }\n    }\n\n    #[cfg(feature = \"cookie-signed\")]\n    #[tokio::test]\n    async fn signed_cannot_access_invalid_cookies() {\n        async fn get_cookie(jar: SignedCookieJar) -> impl IntoResponse {\n            format!(\"{:?}\", jar.get(\"key\"))\n        }\n\n        let state = AppState {\n            key: Key::generate(),\n            custom_key: CustomKey(Key::generate()),\n        };\n\n        let app = Router::new()\n            .route(\"/get\", get(get_cookie))\n            .with_state(state);\n\n        let res = app\n            .clone()\n            .oneshot(\n                Request::builder()\n                    .uri(\"/get\")\n                    .header(\"cookie\", \"key=value\")\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n        let body = body_text(res).await;\n        assert_eq!(body, \"None\");\n    }\n\n    async fn body_text<B>(body: B) -> String\n    where\n        B: axum::body::HttpBody,\n        B::Error: std::fmt::Debug,\n    {\n        let bytes = body.collect().await.unwrap().to_bytes();\n        String::from_utf8(bytes.to_vec()).unwrap()\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/cookie/private.rs",
    "content": "use super::{cookies_from_request, set_cookies, Cookie, Key};\nuse axum_core::{\n    extract::{FromRef, FromRequestParts},\n    response::{IntoResponse, IntoResponseParts, Response, ResponseParts},\n};\nuse cookie::PrivateJar;\nuse http::{request::Parts, HeaderMap};\nuse std::{convert::Infallible, fmt, marker::PhantomData};\n\n/// Extractor that grabs private cookies from the request and manages the jar.\n///\n/// All cookies will be private and encrypted with a [`Key`]. This makes it suitable for storing\n/// private data.\n///\n/// Note that methods like [`PrivateCookieJar::add`], [`PrivateCookieJar::remove`], etc updates the\n/// [`PrivateCookieJar`] and returns it. This value _must_ be returned from the handler as part of\n/// the response for the changes to be propagated.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     routing::{post, get},\n///     extract::FromRef,\n///     response::{IntoResponse, Redirect},\n///     http::StatusCode,\n/// };\n/// use axum_extra::{\n///     TypedHeader,\n///     headers::authorization::{Authorization, Bearer},\n///     extract::cookie::{PrivateCookieJar, Cookie, Key},\n/// };\n///\n/// async fn set_secret(\n///     jar: PrivateCookieJar,\n/// ) -> (PrivateCookieJar, Redirect) {\n///     let updated_jar = jar.add(Cookie::new(\"secret\", \"secret-data\"));\n///     (updated_jar, Redirect::to(\"/get\"))\n/// }\n///\n/// async fn get_secret(jar: PrivateCookieJar) {\n///     if let Some(data) = jar.get(\"secret\") {\n///         // ...\n///     }\n/// }\n///\n/// // our application state\n/// #[derive(Clone)]\n/// struct AppState {\n///     // that holds the key used to encrypt cookies\n///     key: Key,\n/// }\n///\n/// // this impl tells `PrivateCookieJar` how to access the key from our state\n/// impl FromRef<AppState> for Key {\n///     fn from_ref(state: &AppState) -> Self {\n///         state.key.clone()\n///     }\n/// }\n///\n/// let state = AppState {\n///     // Generate a secure key\n///     //\n///     // You probably don't wanna generate a new one each time the app starts though\n///     key: Key::generate(),\n/// };\n///\n/// let app = Router::new()\n///     .route(\"/set\", post(set_secret))\n///     .route(\"/get\", get(get_secret))\n///     .with_state(state);\n/// # let _: axum::Router = app;\n/// ```\n///\n/// If you have been using `Arc<AppState>` you cannot implement `FromRef<Arc<AppState>> for Key`.\n/// You can use a new type instead:\n///\n/// ```rust\n/// # use axum::extract::FromRef;\n/// # use axum_extra::extract::cookie::{PrivateCookieJar, Cookie, Key};\n/// use std::sync::Arc;\n/// use std::ops::Deref;\n///\n/// #[derive(Clone)]\n/// struct AppState(Arc<InnerState>);\n///\n/// // deref so you can still access the inner fields easily\n/// impl Deref for AppState {\n///     type Target = InnerState;\n///\n///     fn deref(&self) -> &Self::Target {\n///         &self.0\n///     }\n/// }\n///\n/// struct InnerState {\n///     key: Key\n/// }\n///\n/// impl FromRef<AppState> for Key {\n///     fn from_ref(state: &AppState) -> Self {\n///         state.0.key.clone()\n///     }\n/// }\n/// ```\n#[must_use = \"`PrivateCookieJar` should be returned as part of a `Response`, otherwise it does nothing.\"]\npub struct PrivateCookieJar<K = Key> {\n    jar: cookie::CookieJar,\n    key: Key,\n    // The key used to extract the key. Allows users to use multiple keys for different\n    // jars. Maybe a library wants its own key.\n    _marker: PhantomData<K>,\n}\n\nimpl<K> fmt::Debug for PrivateCookieJar<K> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"PrivateCookieJar\")\n            .field(\"jar\", &self.jar)\n            .field(\"key\", &\"REDACTED\")\n            .finish()\n    }\n}\n\nimpl<S, K> FromRequestParts<S> for PrivateCookieJar<K>\nwhere\n    S: Send + Sync,\n    K: FromRef<S> + Into<Key>,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let k = K::from_ref(state);\n        let key = k.into();\n        let PrivateCookieJar {\n            jar,\n            key,\n            _marker: _,\n        } = PrivateCookieJar::from_headers(&parts.headers, key);\n        Ok(Self {\n            jar,\n            key,\n            _marker: PhantomData,\n        })\n    }\n}\n\nimpl PrivateCookieJar {\n    /// Create a new `PrivateCookieJar` from a map of request headers.\n    ///\n    /// The valid cookies in `headers` will be added to the jar.\n    ///\n    /// This is intended to be used in middleware and other where places it might be difficult to\n    /// run extractors. Normally you should create `PrivateCookieJar`s through [`FromRequestParts`].\n    ///\n    /// [`FromRequestParts`]: axum::extract::FromRequestParts\n    pub fn from_headers(headers: &HeaderMap, key: Key) -> Self {\n        let mut jar = cookie::CookieJar::new();\n        let mut private_jar = jar.private_mut(&key);\n        for cookie in cookies_from_request(headers) {\n            if let Some(cookie) = private_jar.decrypt(cookie) {\n                private_jar.add_original(cookie);\n            }\n        }\n\n        Self {\n            jar,\n            key,\n            _marker: PhantomData,\n        }\n    }\n\n    /// Create a new empty `PrivateCookieJarIter`.\n    ///\n    /// This is intended to be used in middleware and other places where it might be difficult to\n    /// run extractors. Normally you should create `PrivateCookieJar`s through [`FromRequestParts`].\n    ///\n    /// [`FromRequestParts`]: axum::extract::FromRequestParts\n    pub fn new(key: Key) -> Self {\n        Self {\n            jar: Default::default(),\n            key,\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl<K> PrivateCookieJar<K> {\n    /// Get a cookie from the jar.\n    ///\n    /// If the cookie exists and can be decrypted then it is returned in plaintext.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::PrivateCookieJar;\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: PrivateCookieJar) {\n    ///     let value: Option<String> = jar\n    ///         .get(\"foo\")\n    ///         .map(|cookie| cookie.value().to_owned());\n    /// }\n    /// ```\n    #[must_use]\n    pub fn get(&self, name: &str) -> Option<Cookie<'static>> {\n        self.private_jar().get(name)\n    }\n\n    /// Remove a cookie from the jar.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::{PrivateCookieJar, Cookie};\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: PrivateCookieJar) -> PrivateCookieJar {\n    ///     jar.remove(Cookie::from(\"foo\"))\n    /// }\n    /// ```\n    pub fn remove<C: Into<Cookie<'static>>>(mut self, cookie: C) -> Self {\n        self.private_jar_mut().remove(cookie);\n        self\n    }\n\n    /// Add a cookie to the jar.\n    ///\n    /// The value will automatically be percent-encoded.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::{PrivateCookieJar, Cookie};\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: PrivateCookieJar) -> PrivateCookieJar {\n    ///     jar.add(Cookie::new(\"foo\", \"bar\"))\n    /// }\n    /// ```\n    #[allow(clippy::should_implement_trait)]\n    pub fn add<C: Into<Cookie<'static>>>(mut self, cookie: C) -> Self {\n        self.private_jar_mut().add(cookie);\n        self\n    }\n\n    /// Authenticates and decrypts `cookie`, returning the plaintext version if decryption succeeds\n    /// or `None` otherwise.\n    #[must_use]\n    pub fn decrypt(&self, cookie: Cookie<'static>) -> Option<Cookie<'static>> {\n        self.private_jar().decrypt(cookie)\n    }\n\n    /// Get an iterator over all cookies in the jar.\n    ///\n    /// Only cookies with valid authenticity and integrity are yielded by the iterator.\n    pub fn iter(&self) -> impl Iterator<Item = Cookie<'static>> + '_ {\n        PrivateCookieJarIter {\n            jar: self,\n            iter: self.jar.iter(),\n        }\n    }\n\n    fn private_jar(&self) -> PrivateJar<&'_ cookie::CookieJar> {\n        self.jar.private(&self.key)\n    }\n\n    fn private_jar_mut(&mut self) -> PrivateJar<&'_ mut cookie::CookieJar> {\n        self.jar.private_mut(&self.key)\n    }\n}\n\nimpl<K> IntoResponseParts for PrivateCookieJar<K> {\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        set_cookies(&self.jar, res.headers_mut());\n        Ok(res)\n    }\n}\n\nimpl<K> IntoResponse for PrivateCookieJar<K> {\n    fn into_response(self) -> Response {\n        (self, ()).into_response()\n    }\n}\n\n#[must_use = \"iterators are lazy and do nothing unless consumed\"]\nstruct PrivateCookieJarIter<'a, K> {\n    jar: &'a PrivateCookieJar<K>,\n    iter: cookie::Iter<'a>,\n}\n\nimpl<K> Iterator for PrivateCookieJarIter<'_, K> {\n    type Item = Cookie<'static>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        loop {\n            let cookie = self.iter.next()?;\n\n            if let Some(cookie) = self.jar.get(cookie.name()) {\n                return Some(cookie);\n            }\n        }\n    }\n}\n\nimpl<K> Clone for PrivateCookieJar<K> {\n    fn clone(&self) -> Self {\n        Self {\n            jar: self.jar.clone(),\n            key: self.key.clone(),\n            _marker: self._marker,\n        }\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/cookie/signed.rs",
    "content": "use super::{cookies_from_request, set_cookies};\nuse axum_core::{\n    extract::{FromRef, FromRequestParts},\n    response::{IntoResponse, IntoResponseParts, Response, ResponseParts},\n};\nuse cookie::SignedJar;\nuse cookie::{Cookie, Key};\nuse http::{request::Parts, HeaderMap};\nuse std::{convert::Infallible, fmt, marker::PhantomData};\n\n/// Extractor that grabs signed cookies from the request and manages the jar.\n///\n/// All cookies will be signed and verified with a [`Key`]. Do not use this to store private data\n/// as the values are still transmitted in plaintext.\n///\n/// Note that methods like [`SignedCookieJar::add`], [`SignedCookieJar::remove`], etc updates the\n/// [`SignedCookieJar`] and returns it. This value _must_ be returned from the handler as part of\n/// the response for the changes to be propagated.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{\n///     Router,\n///     routing::{post, get},\n///     extract::FromRef,\n///     response::{IntoResponse, Redirect},\n///     http::StatusCode,\n/// };\n/// use axum_extra::{\n///     TypedHeader,\n///     headers::authorization::{Authorization, Bearer},\n///     extract::cookie::{SignedCookieJar, Cookie, Key},\n/// };\n///\n/// async fn create_session(\n///     TypedHeader(auth): TypedHeader<Authorization<Bearer>>,\n///     jar: SignedCookieJar,\n/// ) -> Result<(SignedCookieJar, Redirect), StatusCode> {\n///     if let Some(session_id) = authorize_and_create_session(auth.token()).await {\n///         Ok((\n///             // the updated jar must be returned for the changes\n///             // to be included in the response\n///             jar.add(Cookie::new(\"session_id\", session_id)),\n///             Redirect::to(\"/me\"),\n///         ))\n///     } else {\n///         Err(StatusCode::UNAUTHORIZED)\n///     }\n/// }\n///\n/// async fn me(jar: SignedCookieJar) -> Result<(), StatusCode> {\n///     if let Some(session_id) = jar.get(\"session_id\") {\n///         // fetch and render user...\n///         # Ok(())\n///     } else {\n///         Err(StatusCode::UNAUTHORIZED)\n///     }\n/// }\n///\n/// async fn authorize_and_create_session(token: &str) -> Option<String> {\n///     // authorize the user and create a session...\n///     # todo!()\n/// }\n///\n/// // our application state\n/// #[derive(Clone)]\n/// struct AppState {\n///     // that holds the key used to sign cookies\n///     key: Key,\n/// }\n///\n/// // this impl tells `SignedCookieJar` how to access the key from our state\n/// impl FromRef<AppState> for Key {\n///     fn from_ref(state: &AppState) -> Self {\n///         state.key.clone()\n///     }\n/// }\n///\n/// let state = AppState {\n///     // Generate a secure key\n///     //\n///     // You probably don't wanna generate a new one each time the app starts though\n///     key: Key::generate(),\n/// };\n///\n/// let app = Router::new()\n///     .route(\"/sessions\", post(create_session))\n///     .route(\"/me\", get(me))\n///     .with_state(state);\n/// # let _: axum::Router = app;\n/// ```\n/// If you have been using `Arc<AppState>` you cannot implement `FromRef<Arc<AppState>> for Key`.\n/// You can use a new type instead:\n///\n/// ```rust\n/// # use axum::extract::FromRef;\n/// # use axum_extra::extract::cookie::{PrivateCookieJar, Cookie, Key};\n/// use std::sync::Arc;\n/// use std::ops::Deref;\n///\n/// #[derive(Clone)]\n/// struct AppState(Arc<InnerState>);\n///\n/// // deref so you can still access the inner fields easily\n/// impl Deref for AppState {\n///     type Target = InnerState;\n///\n///     fn deref(&self) -> &Self::Target {\n///         &*self.0\n///     }\n/// }\n///\n/// struct InnerState {\n///     key: Key\n/// }\n///\n/// impl FromRef<AppState> for Key {\n///     fn from_ref(state: &AppState) -> Self {\n///         state.0.key.clone()\n///     }\n/// }\n/// ```\n#[must_use = \"`SignedCookieJar` should be returned as part of a `Response`, otherwise it does nothing.\"]\npub struct SignedCookieJar<K = Key> {\n    jar: cookie::CookieJar,\n    key: Key,\n    // The key used to extract the key. Allows users to use multiple keys for different\n    // jars. Maybe a library wants its own key.\n    _marker: PhantomData<K>,\n}\n\nimpl<K> fmt::Debug for SignedCookieJar<K> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"SignedCookieJar\")\n            .field(\"jar\", &self.jar)\n            .field(\"key\", &\"REDACTED\")\n            .finish()\n    }\n}\n\nimpl<S, K> FromRequestParts<S> for SignedCookieJar<K>\nwhere\n    S: Send + Sync,\n    K: FromRef<S> + Into<Key>,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let k = K::from_ref(state);\n        let key = k.into();\n        let SignedCookieJar {\n            jar,\n            key,\n            _marker: _,\n        } = SignedCookieJar::from_headers(&parts.headers, key);\n        Ok(Self {\n            jar,\n            key,\n            _marker: PhantomData,\n        })\n    }\n}\n\nimpl SignedCookieJar {\n    /// Create a new `SignedCookieJar` from a map of request headers.\n    ///\n    /// The valid cookies in `headers` will be added to the jar.\n    ///\n    /// This is intended to be used in middleware and other places where it might be difficult to\n    /// run extractors. Normally you should create `SignedCookieJar`s through [`FromRequestParts`].\n    ///\n    /// [`FromRequestParts`]: axum::extract::FromRequestParts\n    pub fn from_headers(headers: &HeaderMap, key: Key) -> Self {\n        let mut jar = cookie::CookieJar::new();\n        let mut signed_jar = jar.signed_mut(&key);\n        for cookie in cookies_from_request(headers) {\n            if let Some(cookie) = signed_jar.verify(cookie) {\n                signed_jar.add_original(cookie);\n            }\n        }\n\n        Self {\n            jar,\n            key,\n            _marker: PhantomData,\n        }\n    }\n\n    /// Create a new empty `SignedCookieJar`.\n    ///\n    /// This is intended to be used in middleware and other places where it might be difficult to\n    /// run extractors. Normally you should create `SignedCookieJar`s through [`FromRequestParts`].\n    ///\n    /// [`FromRequestParts`]: axum::extract::FromRequestParts\n    pub fn new(key: Key) -> Self {\n        Self {\n            jar: Default::default(),\n            key,\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl<K> SignedCookieJar<K> {\n    /// Get a cookie from the jar.\n    ///\n    /// If the cookie exists and its authenticity and integrity can be verified then it is returned\n    /// in plaintext.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::SignedCookieJar;\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: SignedCookieJar) {\n    ///     let value: Option<String> = jar\n    ///         .get(\"foo\")\n    ///         .map(|cookie| cookie.value().to_owned());\n    /// }\n    /// ```\n    #[must_use]\n    pub fn get(&self, name: &str) -> Option<Cookie<'static>> {\n        self.signed_jar().get(name)\n    }\n\n    /// Remove a cookie from the jar.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::{SignedCookieJar, Cookie};\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: SignedCookieJar) -> SignedCookieJar {\n    ///     jar.remove(Cookie::from(\"foo\"))\n    /// }\n    /// ```\n    pub fn remove<C: Into<Cookie<'static>>>(mut self, cookie: C) -> Self {\n        self.signed_jar_mut().remove(cookie);\n        self\n    }\n\n    /// Add a cookie to the jar.\n    ///\n    /// The value will automatically be percent-encoded.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// use axum_extra::extract::cookie::{SignedCookieJar, Cookie};\n    /// use axum::response::IntoResponse;\n    ///\n    /// async fn handle(jar: SignedCookieJar) -> SignedCookieJar {\n    ///     jar.add(Cookie::new(\"foo\", \"bar\"))\n    /// }\n    /// ```\n    #[allow(clippy::should_implement_trait)]\n    pub fn add<C: Into<Cookie<'static>>>(mut self, cookie: C) -> Self {\n        self.signed_jar_mut().add(cookie);\n        self\n    }\n\n    /// Verifies the authenticity and integrity of `cookie`, returning the plaintext version if\n    /// verification succeeds or `None` otherwise.\n    #[must_use]\n    pub fn verify(&self, cookie: Cookie<'static>) -> Option<Cookie<'static>> {\n        self.signed_jar().verify(cookie)\n    }\n\n    /// Get an iterator over all cookies in the jar.\n    ///\n    /// Only cookies with valid authenticity and integrity are yielded by the iterator.\n    pub fn iter(&self) -> impl Iterator<Item = Cookie<'static>> + '_ {\n        SignedCookieJarIter {\n            jar: self,\n            iter: self.jar.iter(),\n        }\n    }\n\n    fn signed_jar(&self) -> SignedJar<&'_ cookie::CookieJar> {\n        self.jar.signed(&self.key)\n    }\n\n    fn signed_jar_mut(&mut self) -> SignedJar<&'_ mut cookie::CookieJar> {\n        self.jar.signed_mut(&self.key)\n    }\n}\n\nimpl<K> IntoResponseParts for SignedCookieJar<K> {\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        set_cookies(&self.jar, res.headers_mut());\n        Ok(res)\n    }\n}\n\nimpl<K> IntoResponse for SignedCookieJar<K> {\n    fn into_response(self) -> Response {\n        (self, ()).into_response()\n    }\n}\n\n#[must_use = \"iterators are lazy and do nothing unless consumed\"]\nstruct SignedCookieJarIter<'a, K> {\n    jar: &'a SignedCookieJar<K>,\n    iter: cookie::Iter<'a>,\n}\n\nimpl<K> Iterator for SignedCookieJarIter<'_, K> {\n    type Item = Cookie<'static>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        loop {\n            let cookie = self.iter.next()?;\n\n            if let Some(cookie) = self.jar.get(cookie.name()) {\n                return Some(cookie);\n            }\n        }\n    }\n}\n\nimpl<K> Clone for SignedCookieJar<K> {\n    fn clone(&self) -> Self {\n        Self {\n            jar: self.jar.clone(),\n            key: self.key.clone(),\n            _marker: self._marker,\n        }\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/form.rs",
    "content": "#![allow(deprecated)]\n\nuse axum::extract::rejection::RawFormRejection;\nuse axum::{\n    extract::{FromRequest, RawForm, Request},\n    RequestExt,\n};\nuse axum_core::__composite_rejection as composite_rejection;\nuse axum_core::__define_rejection as define_rejection;\nuse serde_core::de::DeserializeOwned;\n\n/// Extractor that deserializes `application/x-www-form-urlencoded` requests\n/// into some type.\n///\n/// `T` is expected to implement [`serde::Deserialize`].\n///\n/// # Deprecated\n///\n/// This extractor used to use a different deserializer under-the-hood but that\n/// is no longer the case. Now it only uses an older version of the same\n/// deserializer, purely for ease of transition to the latest version.\n/// Before switching to `axum::extract::Form`, it is recommended to read the\n/// [changelog for `serde_html_form v0.3.0`][changelog].\n///\n/// [changelog]: https://github.com/jplatte/serde_html_form/blob/main/CHANGELOG.md#030\n#[deprecated = \"see documentation\"]\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg(feature = \"form\")]\npub struct Form<T>(pub T);\n\naxum_core::__impl_deref!(Form);\n\nimpl<T, S> FromRequest<S> for Form<T>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = FormRejection;\n\n    async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        let is_get_or_head =\n            req.method() == http::Method::GET || req.method() == http::Method::HEAD;\n\n        let RawForm(bytes) = req.extract().await?;\n\n        let deserializer = serde_html_form::Deserializer::new(form_urlencoded::parse(&bytes));\n\n        serde_path_to_error::deserialize::<_, T>(deserializer)\n            .map(Self)\n            .map_err(|err| {\n                if is_get_or_head {\n                    FailedToDeserializeForm::from_err(err).into()\n                } else {\n                    FailedToDeserializeFormBody::from_err(err).into()\n                }\n            })\n    }\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Failed to deserialize form\"]\n    /// Rejection type used if the [`Form`](Form) extractor is unable to\n    /// deserialize the form into the target type.\n    pub struct FailedToDeserializeForm(Error);\n}\n\ndefine_rejection! {\n    #[status = UNPROCESSABLE_ENTITY]\n    #[body = \"Failed to deserialize form body\"]\n    /// Rejection type used if the [`Form`](Form) extractor is unable to\n    /// deserialize the form body into the target type.\n    pub struct FailedToDeserializeFormBody(Error);\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Form`].\n    ///\n    /// Contains one variant for each way the [`Form`] extractor can fail.\n    #[deprecated = \"because Form is deprecated\"]\n    pub enum FormRejection {\n        RawFormRejection,\n        FailedToDeserializeForm,\n        FailedToDeserializeFormBody,\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::routing::{on, post, MethodFilter};\n    use axum::Router;\n    use http::header::CONTENT_TYPE;\n    use http::StatusCode;\n    use mime::APPLICATION_WWW_FORM_URLENCODED;\n    use serde::Deserialize;\n\n    #[tokio::test]\n    async fn supports_multiple_values() {\n        #[derive(Deserialize)]\n        struct Data {\n            #[serde(rename = \"value\")]\n            values: Vec<String>,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            post(|Form(data): Form<Data>| async move { data.values.join(\",\") }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client\n            .post(\"/\")\n            .header(CONTENT_TYPE, \"application/x-www-form-urlencoded\")\n            .body(\"value=one&value=two\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"one,two\");\n    }\n\n    #[tokio::test]\n    async fn deserialize_error_status_codes() {\n        #[allow(dead_code)]\n        #[derive(Deserialize)]\n        struct Payload {\n            a: i32,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            on(\n                MethodFilter::GET.or(MethodFilter::POST),\n                |_: Form<Payload>| async {},\n            ),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/?a=false\").await;\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n        assert_eq!(\n            res.text().await,\n            \"Failed to deserialize form: a: invalid digit found in string\"\n        );\n\n        let res = client\n            .post(\"/\")\n            .header(CONTENT_TYPE, APPLICATION_WWW_FORM_URLENCODED.as_ref())\n            .body(\"a=false\")\n            .await;\n        assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);\n        assert_eq!(\n            res.text().await,\n            \"Failed to deserialize form body: a: invalid digit found in string\"\n        );\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/json_deserializer.rs",
    "content": "use axum_core::__composite_rejection as composite_rejection;\nuse axum_core::__define_rejection as define_rejection;\nuse axum_core::extract::rejection::BytesRejection;\nuse axum_core::extract::{FromRequest, Request};\nuse bytes::Bytes;\nuse http::{header, HeaderMap};\nuse serde_core::Deserialize;\nuse std::marker::PhantomData;\n\n/// JSON Extractor for zero-copy deserialization.\n///\n/// Deserialize request bodies into some type that implements [`serde::Deserialize<'de>`][serde::Deserialize].\n/// Parsing JSON is delayed until [`deserialize`](JsonDeserializer::deserialize) is called.\n/// If the type implements [`serde::de::DeserializeOwned`], the [`Json`](axum::Json) extractor should\n/// be preferred.\n///\n/// The request will be rejected (and a [`JsonDeserializerRejection`] will be returned) if:\n///\n/// - The request doesn't have a `Content-Type: application/json` (or similar) header.\n/// - Buffering the request body fails.\n///\n/// Additionally, a `JsonRejection` error will be returned, when calling `deserialize` if:\n///\n/// - The body doesn't contain syntactically valid JSON.\n/// - The body contains syntactically valid JSON, but it couldn't be deserialized into the target type.\n/// - Attempting to deserialize escaped JSON into a type that must be borrowed (e.g. `&'a str`).\n///\n/// ⚠️ `serde` will implicitly try to borrow for `&str` and `&[u8]` types, but will error if the\n/// input contains escaped characters. Use `Cow<'a, str>` or `Cow<'a, [u8]>`, with the\n/// `#[serde(borrow)]` attribute, to allow serde to fall back to an owned type when encountering\n/// escaped characters.\n///\n/// ⚠️ Since parsing JSON requires consuming the request body, the `Json` extractor must be\n/// *last* if there are multiple extractors in a handler.\n/// See [\"the order of extractors\"][order-of-extractors]\n///\n/// [order-of-extractors]: axum::extract#the-order-of-extractors\n///\n/// See [`JsonDeserializerRejection`] for more details.\n///\n/// # Example\n///\n/// ```rust,no_run\n/// use axum::{\n///     routing::post,\n///     Router,\n///     response::{IntoResponse, Response}\n/// };\n/// use axum_extra::extract::JsonDeserializer;\n/// use serde::Deserialize;\n/// use std::borrow::Cow;\n/// use http::StatusCode;\n///\n/// #[derive(Deserialize)]\n/// struct Data<'a> {\n///     #[serde(borrow)]\n///     borrow_text: Cow<'a, str>,\n///     #[serde(borrow)]\n///     borrow_bytes: Cow<'a, [u8]>,\n///     borrow_dangerous: &'a str,\n///     not_borrowed: String,\n/// }\n///\n/// async fn upload(deserializer: JsonDeserializer<Data<'_>>) -> Response {\n///     let data = match deserializer.deserialize() {\n///         Ok(data) => data,\n///         Err(e) => return e.into_response(),\n///     };\n///\n///     // payload is a `Data` with borrowed data from `deserializer`,\n///     // which owns the request body (`Bytes`).\n///\n///     StatusCode::OK.into_response()\n/// }\n///\n/// let app = Router::new().route(\"/upload\", post(upload));\n/// # let _: Router = app;\n/// ```\n#[derive(Debug, Clone, Default)]\n#[cfg_attr(docsrs, doc(cfg(feature = \"json-deserializer\")))]\npub struct JsonDeserializer<T> {\n    bytes: Bytes,\n    _marker: PhantomData<T>,\n}\n\nimpl<T, S> FromRequest<S> for JsonDeserializer<T>\nwhere\n    T: Deserialize<'static>,\n    S: Send + Sync,\n{\n    type Rejection = JsonDeserializerRejection;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        if json_content_type(req.headers()) {\n            let bytes = Bytes::from_request(req, state).await?;\n            Ok(Self {\n                bytes,\n                _marker: PhantomData,\n            })\n        } else {\n            Err(MissingJsonContentType.into())\n        }\n    }\n}\n\nimpl<'de, 'a: 'de, T> JsonDeserializer<T>\nwhere\n    T: Deserialize<'de>,\n{\n    /// Deserialize the request body into the target type.\n    /// See [`JsonDeserializer`] for more details.\n    pub fn deserialize(&'a self) -> Result<T, JsonDeserializerRejection> {\n        let deserializer = &mut serde_json::Deserializer::from_slice(&self.bytes);\n\n        let value = match serde_path_to_error::deserialize(deserializer) {\n            Ok(value) => value,\n            Err(err) => {\n                let rejection = match err.inner().classify() {\n                    serde_json::error::Category::Data => JsonDataError::from_err(err).into(),\n                    serde_json::error::Category::Syntax | serde_json::error::Category::Eof => {\n                        JsonSyntaxError::from_err(err).into()\n                    }\n                    serde_json::error::Category::Io => {\n                        if cfg!(debug_assertions) {\n                            // we don't use `serde_json::from_reader` and instead always buffer\n                            // bodies first, so we shouldn't encounter any IO errors\n                            unreachable!()\n                        } else {\n                            JsonSyntaxError::from_err(err).into()\n                        }\n                    }\n                };\n                return Err(rejection);\n            }\n        };\n\n        Ok(value)\n    }\n}\n\ndefine_rejection! {\n    #[status = UNPROCESSABLE_ENTITY]\n    #[body = \"Failed to deserialize the JSON body into the target type\"]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json-deserializer\")))]\n    /// Rejection type for [`JsonDeserializer`].\n    ///\n    /// This rejection is used if the request body is syntactically valid JSON but couldn't be\n    /// deserialized into the target type.\n    pub struct JsonDataError(Error);\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Failed to parse the request body as JSON\"]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json-deserializer\")))]\n    /// Rejection type for [`JsonDeserializer`].\n    ///\n    /// This rejection is used if the request body didn't contain syntactically valid JSON.\n    pub struct JsonSyntaxError(Error);\n}\n\ndefine_rejection! {\n    #[status = UNSUPPORTED_MEDIA_TYPE]\n    #[body = \"Expected request with `Content-Type: application/json`\"]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json-deserializer\")))]\n    /// Rejection type for [`JsonDeserializer`] used if the `Content-Type`\n    /// header is missing.\n    pub struct MissingJsonContentType;\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`JsonDeserializer`].\n    ///\n    /// Contains one variant for each way the [`JsonDeserializer`] extractor\n    /// can fail.\n    #[cfg_attr(docsrs, doc(cfg(feature = \"json-deserializer\")))]\n    pub enum JsonDeserializerRejection {\n        JsonDataError,\n        JsonSyntaxError,\n        MissingJsonContentType,\n        BytesRejection,\n    }\n}\n\nfn json_content_type(headers: &HeaderMap) -> bool {\n    let Some(content_type) = headers.get(header::CONTENT_TYPE) else {\n        return false;\n    };\n\n    let Ok(content_type) = content_type.to_str() else {\n        return false;\n    };\n\n    let Ok(mime) = content_type.parse::<mime::Mime>() else {\n        return false;\n    };\n\n    let is_json_content_type = mime.type_() == \"application\"\n        && (mime.subtype() == \"json\" || mime.suffix().is_some_and(|name| name == \"json\"));\n\n    is_json_content_type\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::{\n        response::{IntoResponse, Response},\n        routing::post,\n        Router,\n    };\n    use http::StatusCode;\n    use serde::Deserialize;\n    use serde_json::{json, Value};\n    use std::borrow::Cow;\n\n    #[tokio::test]\n    async fn deserialize_body() {\n        #[derive(Debug, Deserialize)]\n        struct Input<'a> {\n            #[serde(borrow)]\n            foo: Cow<'a, str>,\n        }\n\n        async fn handler(deserializer: JsonDeserializer<Input<'_>>) -> Response {\n            match deserializer.deserialize() {\n                Ok(input) => {\n                    assert!(matches!(input.foo, Cow::Borrowed(_)));\n                    input.foo.into_owned().into_response()\n                }\n                Err(e) => e.into_response(),\n            }\n        }\n\n        let app = Router::new().route(\"/\", post(handler));\n\n        let client = TestClient::new(app);\n        let res = client.post(\"/\").json(&json!({ \"foo\": \"bar\" })).await;\n        let body = res.text().await;\n\n        assert_eq!(body, \"bar\");\n    }\n\n    #[tokio::test]\n    async fn deserialize_body_escaped_to_cow() {\n        #[derive(Debug, Deserialize)]\n        struct Input<'a> {\n            #[serde(borrow)]\n            foo: Cow<'a, str>,\n        }\n\n        async fn handler(deserializer: JsonDeserializer<Input<'_>>) -> Response {\n            match deserializer.deserialize() {\n                Ok(Input { foo }) => {\n                    let Cow::Owned(foo) = foo else {\n                        panic!(\"Deserializer is expected to fallback to Cow::Owned when encountering escaped characters\")\n                    };\n\n                    foo.into_response()\n                }\n                Err(e) => e.into_response(),\n            }\n        }\n\n        let app = Router::new().route(\"/\", post(handler));\n\n        let client = TestClient::new(app);\n\n        // The escaped characters prevent serde_json from borrowing.\n        let res = client.post(\"/\").json(&json!({ \"foo\": \"\\\"bar\\\"\" })).await;\n\n        let body = res.text().await;\n\n        assert_eq!(body, r#\"\"bar\"\"#);\n    }\n\n    #[tokio::test]\n    async fn deserialize_body_escaped_to_str() {\n        #[derive(Debug, Deserialize)]\n        struct Input<'a> {\n            // Explicit `#[serde(borrow)]` attribute is not required for `&str` or &[u8].\n            // See: https://serde.rs/lifetimes.html#borrowing-data-in-a-derived-impl\n            foo: &'a str,\n        }\n\n        async fn handler(deserializer: JsonDeserializer<Input<'_>>) -> Response {\n            match deserializer.deserialize() {\n                Ok(Input { foo }) => foo.to_owned().into_response(),\n                Err(e) => e.into_response(),\n            }\n        }\n\n        let app = Router::new().route(\"/\", post(handler));\n\n        let client = TestClient::new(app);\n\n        let res = client.post(\"/\").json(&json!({ \"foo\": \"good\" })).await;\n        let body = res.text().await;\n        assert_eq!(body, \"good\");\n\n        let res = client.post(\"/\").json(&json!({ \"foo\": \"\\\"bad\\\"\" })).await;\n        assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);\n        let body_text = res.text().await;\n        assert_eq!(\n            body_text,\n            \"Failed to deserialize the JSON body into the target type: foo: invalid type: string \\\"\\\\\\\"bad\\\\\\\"\\\", expected a borrowed string at line 1 column 16\"\n        );\n    }\n\n    #[tokio::test]\n    async fn consume_body_to_json_requires_json_content_type() {\n        #[derive(Debug, Deserialize)]\n        struct Input<'a> {\n            #[allow(dead_code)]\n            foo: Cow<'a, str>,\n        }\n\n        async fn handler(_deserializer: JsonDeserializer<Input<'_>>) -> Response {\n            panic!(\"This handler should not be called\")\n        }\n\n        let app = Router::new().route(\"/\", post(handler));\n\n        let client = TestClient::new(app);\n        let res = client.post(\"/\").body(r#\"{ \"foo\": \"bar\" }\"#).await;\n\n        let status = res.status();\n\n        assert_eq!(status, StatusCode::UNSUPPORTED_MEDIA_TYPE);\n    }\n\n    #[tokio::test]\n    async fn json_content_types() {\n        async fn valid_json_content_type(content_type: &str) -> bool {\n            println!(\"testing {content_type:?}\");\n\n            async fn handler(_deserializer: JsonDeserializer<Value>) -> Response {\n                StatusCode::OK.into_response()\n            }\n\n            let app = Router::new().route(\"/\", post(handler));\n\n            let res = TestClient::new(app)\n                .post(\"/\")\n                .header(\"content-type\", content_type)\n                .body(\"{}\")\n                .await;\n\n            res.status() == StatusCode::OK\n        }\n\n        assert!(valid_json_content_type(\"application/json\").await);\n        assert!(valid_json_content_type(\"application/json; charset=utf-8\").await);\n        assert!(valid_json_content_type(\"application/json;charset=utf-8\").await);\n        assert!(valid_json_content_type(\"application/cloudevents+json\").await);\n        assert!(!valid_json_content_type(\"text/json\").await);\n    }\n\n    #[tokio::test]\n    async fn invalid_json_syntax() {\n        async fn handler(deserializer: JsonDeserializer<Value>) -> Response {\n            match deserializer.deserialize() {\n                Ok(_) => panic!(\"Should have matched `Err`\"),\n                Err(e) => e.into_response(),\n            }\n        }\n\n        let app = Router::new().route(\"/\", post(handler));\n\n        let client = TestClient::new(app);\n        let res = client\n            .post(\"/\")\n            .body(\"{\")\n            .header(\"content-type\", \"application/json\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n    }\n\n    #[derive(Deserialize)]\n    struct Foo {\n        #[allow(dead_code)]\n        a: i32,\n        #[allow(dead_code)]\n        b: Vec<Bar>,\n    }\n\n    #[derive(Deserialize)]\n    struct Bar {\n        #[allow(dead_code)]\n        x: i32,\n        #[allow(dead_code)]\n        y: i32,\n    }\n\n    #[tokio::test]\n    async fn invalid_json_data() {\n        async fn handler(deserializer: JsonDeserializer<Foo>) -> Response {\n            match deserializer.deserialize() {\n                Ok(_) => panic!(\"Should have matched `Err`\"),\n                Err(e) => e.into_response(),\n            }\n        }\n\n        let app = Router::new().route(\"/\", post(handler));\n\n        let client = TestClient::new(app);\n        let res = client\n            .post(\"/\")\n            .body(\"{\\\"a\\\": 1, \\\"b\\\": [{\\\"x\\\": 2}]}\")\n            .header(\"content-type\", \"application/json\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);\n        let body_text = res.text().await;\n        assert_eq!(\n            body_text,\n            \"Failed to deserialize the JSON body into the target type: b[0]: missing field `y` at line 1 column 23\"\n        );\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/mod.rs",
    "content": "//! Additional extractors.\n\n#[cfg(feature = \"cached\")]\nmod cached;\n\n#[cfg(feature = \"with-rejection\")]\nmod with_rejection;\n\n#[cfg(feature = \"form\")]\nmod form;\n\n#[cfg(feature = \"cookie\")]\npub mod cookie;\n\n#[cfg(feature = \"json-deserializer\")]\nmod json_deserializer;\n\n#[cfg(feature = \"query\")]\nmod query;\n\n#[cfg(feature = \"multipart\")]\npub mod multipart;\n\n#[cfg(feature = \"cached\")]\npub use self::cached::Cached;\n\n#[cfg(feature = \"with-rejection\")]\npub use self::with_rejection::WithRejection;\n\n#[cfg(feature = \"cookie\")]\npub use self::cookie::CookieJar;\n\n#[cfg(feature = \"cookie-private\")]\npub use self::cookie::PrivateCookieJar;\n\n#[cfg(feature = \"cookie-signed\")]\npub use self::cookie::SignedCookieJar;\n\n#[cfg(feature = \"form\")]\n#[allow(deprecated)]\npub use self::form::{Form, FormRejection};\n\n#[cfg(feature = \"query\")]\npub use self::query::OptionalQuery;\n#[cfg(feature = \"query\")]\n#[allow(deprecated)]\npub use self::query::{OptionalQueryRejection, Query, QueryRejection};\n\n#[cfg(feature = \"multipart\")]\npub use self::multipart::Multipart;\n\n#[cfg(feature = \"json-deserializer\")]\npub use self::json_deserializer::{\n    JsonDataError, JsonDeserializer, JsonDeserializerRejection, JsonSyntaxError,\n    MissingJsonContentType,\n};\n\n#[cfg(feature = \"json-lines\")]\n#[doc(no_inline)]\npub use crate::json_lines::JsonLines;\n\n#[cfg(feature = \"typed-header\")]\n#[doc(no_inline)]\npub use crate::typed_header::TypedHeader;\n"
  },
  {
    "path": "axum-extra/src/extract/multipart.rs",
    "content": "//! Extractor that parses `multipart/form-data` requests commonly used with file uploads.\n//!\n//! See [`Multipart`] for more details.\n\nuse axum_core::{\n    __composite_rejection as composite_rejection, __define_rejection as define_rejection,\n    body::Body,\n    extract::FromRequest,\n    response::{IntoResponse, Response},\n    RequestExt,\n};\nuse bytes::Bytes;\nuse futures_core::stream::Stream;\nuse http::{\n    header::{HeaderMap, CONTENT_TYPE},\n    Request, StatusCode,\n};\nuse std::{\n    error::Error,\n    fmt,\n    pin::Pin,\n    task::{Context, Poll},\n};\n\n/// Extractor that parses `multipart/form-data` requests (commonly used with file uploads).\n///\n/// ⚠️ Since extracting multipart form data from the request requires consuming the body, the\n/// `Multipart` extractor must be *last* if there are multiple extractors in a handler.\n/// See [\"the order of extractors\"][order-of-extractors]\n///\n/// [order-of-extractors]: crate::extract#the-order-of-extractors\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     routing::post,\n///     Router,\n/// };\n/// use axum_extra::extract::Multipart;\n///\n/// async fn upload(mut multipart: Multipart) {\n///     while let Some(mut field) = multipart.next_field().await.unwrap() {\n///         let name = field.name().unwrap().to_string();\n///         let data = field.bytes().await.unwrap();\n///\n///         println!(\"Length of `{}` is {} bytes\", name, data.len());\n///     }\n/// }\n///\n/// let app = Router::new().route(\"/upload\", post(upload));\n/// # let _: Router = app;\n/// ```\n///\n/// # Field Exclusivity\n///\n/// A [`Field`] represents a raw, self-decoding stream into multipart data. As such, only one\n/// [`Field`] from a given Multipart instance may be live at once. That is, a [`Field`] emitted by\n/// [`next_field()`] must be dropped before calling [`next_field()`] again. Failure to do so will\n/// result in an error.\n///\n/// ```\n/// use axum_extra::extract::Multipart;\n///\n/// async fn handler(mut multipart: Multipart) {\n///     let field_1 = multipart.next_field().await;\n///\n///     // We cannot get the next field while `field_1` is still alive. Have to drop `field_1`\n///     // first.\n///     let field_2 = multipart.next_field().await;\n///     assert!(field_2.is_err());\n/// }\n/// ```\n///\n/// In general you should consume `Multipart` by looping over the fields in order and make sure not\n/// to keep `Field`s around from previous loop iterations. That will minimize the risk of runtime\n/// errors.\n///\n/// # Differences between this and `axum::extract::Multipart`\n///\n/// `axum::extract::Multipart` uses lifetimes to enforce field exclusivity at compile time, however\n/// that leads to significant usability issues such as `Field` not being `'static`.\n///\n/// `axum_extra::extract::Multipart` instead enforces field exclusivity at runtime which makes\n/// things easier to use at the cost of possible runtime errors.\n///\n/// [`next_field()`]: Multipart::next_field\n#[cfg_attr(docsrs, doc(cfg(feature = \"multipart\")))]\n#[derive(Debug)]\npub struct Multipart {\n    inner: multer::Multipart<'static>,\n}\n\nimpl<S> FromRequest<S> for Multipart\nwhere\n    S: Send + Sync,\n{\n    type Rejection = MultipartRejection;\n\n    async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {\n        let boundary = parse_boundary(req.headers()).ok_or(InvalidBoundary)?;\n        let stream = req.with_limited_body().into_body();\n        let multipart = multer::Multipart::new(stream.into_data_stream(), boundary);\n        Ok(Self { inner: multipart })\n    }\n}\n\nimpl Multipart {\n    /// Yields the next [`Field`] if available.\n    pub async fn next_field(&mut self) -> Result<Option<Field>, MultipartError> {\n        let field = self\n            .inner\n            .next_field()\n            .await\n            .map_err(MultipartError::from_multer)?;\n\n        if let Some(field) = field {\n            Ok(Some(Field { inner: field }))\n        } else {\n            Ok(None)\n        }\n    }\n\n    /// Convert the `Multipart` into a stream of its fields.\n    pub fn into_stream(self) -> impl Stream<Item = Result<Field, MultipartError>> + Send + 'static {\n        futures_util::stream::try_unfold(self, |mut multipart| async move {\n            let field = multipart.next_field().await?;\n            Ok(field.map(|field| (field, multipart)))\n        })\n    }\n}\n\n/// A single field in a multipart stream.\n#[derive(Debug)]\npub struct Field {\n    inner: multer::Field<'static>,\n}\n\nimpl Stream for Field {\n    type Item = Result<Bytes, MultipartError>;\n\n    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {\n        Pin::new(&mut self.inner)\n            .poll_next(cx)\n            .map_err(MultipartError::from_multer)\n    }\n}\n\nimpl Field {\n    /// The field name found in the\n    /// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)\n    /// header.\n    #[must_use]\n    pub fn name(&self) -> Option<&str> {\n        self.inner.name()\n    }\n\n    /// The file name found in the\n    /// [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)\n    /// header.\n    #[must_use]\n    pub fn file_name(&self) -> Option<&str> {\n        self.inner.file_name()\n    }\n\n    /// Get the [content type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) of the field.\n    #[must_use]\n    pub fn content_type(&self) -> Option<&str> {\n        self.inner.content_type().map(|m| m.as_ref())\n    }\n\n    /// Get a map of headers as [`HeaderMap`].\n    #[must_use]\n    pub fn headers(&self) -> &HeaderMap {\n        self.inner.headers()\n    }\n\n    /// Get the full data of the field as [`Bytes`].\n    pub async fn bytes(self) -> Result<Bytes, MultipartError> {\n        self.inner\n            .bytes()\n            .await\n            .map_err(MultipartError::from_multer)\n    }\n\n    /// Get the full field data as text.\n    pub async fn text(self) -> Result<String, MultipartError> {\n        self.inner.text().await.map_err(MultipartError::from_multer)\n    }\n\n    /// Stream a chunk of the field data.\n    ///\n    /// When the field data has been exhausted, this will return [`None`].\n    ///\n    /// Note this does the same thing as `Field`'s [`Stream`] implementation.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{\n    ///    routing::post,\n    ///    response::IntoResponse,\n    ///    http::StatusCode,\n    ///    Router,\n    /// };\n    /// use axum_extra::extract::Multipart;\n    ///\n    /// async fn upload(mut multipart: Multipart) -> Result<(), (StatusCode, String)> {\n    ///     while let Some(mut field) = multipart\n    ///         .next_field()\n    ///         .await\n    ///         .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))?\n    ///     {\n    ///         while let Some(chunk) = field\n    ///             .chunk()\n    ///             .await\n    ///             .map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))?\n    ///         {\n    ///             println!(\"received {} bytes\", chunk.len());\n    ///         }\n    ///     }\n    ///\n    ///     Ok(())\n    /// }\n    ///\n    /// let app = Router::new().route(\"/upload\", post(upload));\n    /// # let _: Router = app;\n    /// ```\n    pub async fn chunk(&mut self) -> Result<Option<Bytes>, MultipartError> {\n        self.inner\n            .chunk()\n            .await\n            .map_err(MultipartError::from_multer)\n    }\n}\n\n/// Errors associated with parsing `multipart/form-data` requests.\n#[derive(Debug)]\npub struct MultipartError {\n    source: multer::Error,\n}\n\nimpl MultipartError {\n    fn from_multer(multer: multer::Error) -> Self {\n        Self { source: multer }\n    }\n\n    /// Get the response body text used for this rejection.\n    pub fn body_text(&self) -> String {\n        let body = if is_body_limit_error(&self.source) {\n            \"Request payload is too large\".to_owned()\n        } else {\n            self.source.to_string()\n        };\n        axum_core::__log_rejection!(\n            rejection_type = Self,\n            body_text = body,\n            status = self.status(),\n        );\n        body\n    }\n\n    /// Get the status code used for this rejection.\n    #[must_use]\n    pub fn status(&self) -> http::StatusCode {\n        status_code_from_multer_error(&self.source)\n    }\n}\n\nfn status_code_from_multer_error(err: &multer::Error) -> StatusCode {\n    match err {\n        multer::Error::UnknownField { .. }\n        | multer::Error::IncompleteFieldData { .. }\n        | multer::Error::IncompleteHeaders\n        | multer::Error::ReadHeaderFailed(..)\n        | multer::Error::DecodeHeaderName { .. }\n        | multer::Error::DecodeContentType(..)\n        | multer::Error::NoBoundary\n        | multer::Error::DecodeHeaderValue { .. }\n        | multer::Error::NoMultipart\n        | multer::Error::IncompleteStream => StatusCode::BAD_REQUEST,\n        multer::Error::FieldSizeExceeded { .. } | multer::Error::StreamSizeExceeded { .. } => {\n            StatusCode::PAYLOAD_TOO_LARGE\n        }\n        multer::Error::StreamReadFailed(err) => {\n            if let Some(err) = err.downcast_ref::<multer::Error>() {\n                return status_code_from_multer_error(err);\n            }\n\n            if err\n                .downcast_ref::<axum_core::Error>()\n                .and_then(|err| err.source())\n                .and_then(|err| err.downcast_ref::<http_body_util::LengthLimitError>())\n                .is_some()\n            {\n                return StatusCode::PAYLOAD_TOO_LARGE;\n            }\n\n            StatusCode::INTERNAL_SERVER_ERROR\n        }\n        _ => StatusCode::INTERNAL_SERVER_ERROR,\n    }\n}\n\nfn is_body_limit_error(err: &multer::Error) -> bool {\n    match err {\n        multer::Error::FieldSizeExceeded { .. } | multer::Error::StreamSizeExceeded { .. } => true,\n        multer::Error::StreamReadFailed(err) => {\n            if let Some(err) = err.downcast_ref::<multer::Error>() {\n                return is_body_limit_error(err);\n            }\n            err.downcast_ref::<axum_core::Error>()\n                .and_then(|err| err.source())\n                .and_then(|err| err.downcast_ref::<http_body_util::LengthLimitError>())\n                .is_some()\n        }\n        _ => false,\n    }\n}\n\nimpl IntoResponse for MultipartError {\n    fn into_response(self) -> Response {\n        (self.status(), self.body_text()).into_response()\n    }\n}\n\nimpl fmt::Display for MultipartError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"Error parsing `multipart/form-data` request\")\n    }\n}\n\nimpl std::error::Error for MultipartError {\n    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n        Some(&self.source)\n    }\n}\n\nfn parse_boundary(headers: &HeaderMap) -> Option<String> {\n    let content_type = headers.get(CONTENT_TYPE)?.to_str().ok()?;\n    multer::parse_boundary(content_type).ok()\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Multipart`].\n    ///\n    /// Contains one variant for each way the [`Multipart`] extractor can fail.\n    pub enum MultipartRejection {\n        InvalidBoundary,\n    }\n}\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Invalid `boundary` for `multipart/form-data` request\"]\n    /// Rejection type used if the `boundary` in a `multipart/form-data` is\n    /// missing or invalid.\n    pub struct InvalidBoundary;\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::{extract::DefaultBodyLimit, routing::post, Router};\n\n    #[tokio::test]\n    async fn content_type_with_encoding() {\n        const BYTES: &[u8] = \"<!doctype html><title>🦀</title>\".as_bytes();\n        const FILE_NAME: &str = \"index.html\";\n        const CONTENT_TYPE: &str = \"text/html; charset=utf-8\";\n\n        async fn handle(mut multipart: Multipart) -> impl IntoResponse {\n            let field = multipart.next_field().await.unwrap().unwrap();\n\n            assert_eq!(field.file_name().unwrap(), FILE_NAME);\n            assert_eq!(field.content_type().unwrap(), CONTENT_TYPE);\n            assert_eq!(field.bytes().await.unwrap(), BYTES);\n\n            assert!(multipart.next_field().await.unwrap().is_none());\n        }\n\n        let app = Router::new().route(\"/\", post(handle));\n\n        let client = TestClient::new(app);\n\n        let form = reqwest::multipart::Form::new().part(\n            \"file\",\n            reqwest::multipart::Part::bytes(BYTES)\n                .file_name(FILE_NAME)\n                .mime_str(CONTENT_TYPE)\n                .unwrap(),\n        );\n\n        client.post(\"/\").multipart(form).await;\n    }\n\n    // No need for this to be a #[test], we just want to make sure it compiles\n    fn _multipart_from_request_limited() {\n        async fn handler(_: Multipart) {}\n        let _app: Router<()> = Router::new().route(\"/\", post(handler));\n    }\n\n    #[tokio::test]\n    async fn body_too_large() {\n        const BYTES: &[u8] = \"<!doctype html><title>🦀</title>\".as_bytes();\n\n        async fn handle(mut multipart: Multipart) -> Result<(), MultipartError> {\n            while let Some(field) = multipart.next_field().await? {\n                field.bytes().await?;\n            }\n            Ok(())\n        }\n\n        let app = Router::new()\n            .route(\"/\", post(handle))\n            .layer(DefaultBodyLimit::max(BYTES.len() - 1));\n\n        let client = TestClient::new(app);\n\n        let form =\n            reqwest::multipart::Form::new().part(\"file\", reqwest::multipart::Part::bytes(BYTES));\n\n        let res = client.post(\"/\").multipart(form).await;\n        assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n        assert_eq!(res.text().await, \"Request payload is too large\");\n    }\n\n    #[tokio::test]\n    #[cfg(feature = \"tracing\")]\n    async fn body_too_large_with_tracing() {\n        const BYTES: &[u8] = \"<!doctype html><title>🦀</title>\".as_bytes();\n\n        async fn handle(mut multipart: Multipart) -> impl IntoResponse {\n            let result: Result<(), MultipartError> = async {\n                while let Some(field) = multipart.next_field().await? {\n                    field.bytes().await?;\n                }\n                Ok(())\n            }\n            .await;\n\n            let subscriber = tracing_subscriber::FmtSubscriber::builder()\n                .with_max_level(tracing::level_filters::LevelFilter::TRACE)\n                .with_writer(std::io::sink)\n                .finish();\n\n            let guard = tracing::subscriber::set_default(subscriber);\n            let response = result.into_response();\n            drop(guard);\n\n            response\n        }\n\n        let app = Router::new()\n            .route(\"/\", post(handle))\n            .layer(DefaultBodyLimit::max(BYTES.len() - 1));\n\n        let client = TestClient::new(app);\n\n        let form =\n            reqwest::multipart::Form::new().part(\"file\", reqwest::multipart::Part::bytes(BYTES));\n\n        let res = client.post(\"/\").multipart(form).await;\n        assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/query.rs",
    "content": "#![allow(deprecated)]\n\nuse axum_core::__composite_rejection as composite_rejection;\nuse axum_core::__define_rejection as define_rejection;\nuse axum_core::extract::FromRequestParts;\nuse http::{request::Parts, Uri};\nuse serde_core::de::DeserializeOwned;\n\n/// Extractor that deserializes query strings into some type.\n///\n/// `T` is expected to implement [`serde::Deserialize`].\n///\n/// # Deprecated\n///\n/// This extractor used to use a different deserializer under-the-hood but that\n/// is no longer the case. Now it only uses an older version of the same\n/// deserializer, purely for ease of transition to the latest version.\n/// Before switching to `axum::extract::Form`, it is recommended to read the\n/// [changelog for `serde_html_form v0.3.0`][changelog].\n///\n/// [changelog]: https://github.com/jplatte/serde_html_form/blob/main/CHANGELOG.md#030\n#[deprecated = \"see documentation\"]\n#[cfg_attr(docsrs, doc(cfg(feature = \"query\")))]\n#[derive(Debug, Clone, Copy, Default)]\npub struct Query<T>(pub T);\n\nimpl<T, S> FromRequestParts<S> for Query<T>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = QueryRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        let query = parts.uri.query().unwrap_or_default();\n        let deserializer =\n            serde_html_form::Deserializer::new(form_urlencoded::parse(query.as_bytes()));\n        let value = serde_path_to_error::deserialize(deserializer)\n            .map_err(FailedToDeserializeQueryString::from_err)?;\n        Ok(Self(value))\n    }\n}\n\nimpl<T> Query<T>\nwhere\n    T: DeserializeOwned,\n{\n    /// Attempts to construct a [`Query`] from a reference to a [`Uri`].\n    ///\n    /// # Example\n    /// ```\n    /// use axum_extra::extract::Query;\n    /// use http::Uri;\n    /// use serde::Deserialize;\n    ///\n    /// #[derive(Deserialize)]\n    /// struct ExampleParams {\n    ///     foo: String,\n    ///     bar: u32,\n    /// }\n    ///\n    /// let uri: Uri = \"http://example.com/path?foo=hello&bar=42\".parse().unwrap();\n    /// let result: Query<ExampleParams> = Query::try_from_uri(&uri).unwrap();\n    /// assert_eq!(result.foo, String::from(\"hello\"));\n    /// assert_eq!(result.bar, 42);\n    /// ```\n    pub fn try_from_uri(value: &Uri) -> Result<Self, QueryRejection> {\n        let query = value.query().unwrap_or_default();\n        let params =\n            serde_html_form::from_str(query).map_err(FailedToDeserializeQueryString::from_err)?;\n        Ok(Self(params))\n    }\n}\n\naxum_core::__impl_deref!(Query);\n\ndefine_rejection! {\n    #[status = BAD_REQUEST]\n    #[body = \"Failed to deserialize query string\"]\n    /// Rejection type used if the [`Query`] extractor is unable to\n    /// deserialize the query string into the target type.\n    pub struct FailedToDeserializeQueryString(Error);\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Query`].\n    ///\n    /// Contains one variant for each way the [`Query`] extractor can fail.\n    #[deprecated = \"because Query is deprecated\"]\n    pub enum QueryRejection {\n        FailedToDeserializeQueryString,\n    }\n}\n\n/// Extractor that deserializes query strings into `None` if no query parameters are present.\n///\n/// Otherwise behaviour is identical to [`Query`][axum::extract::Query].\n/// `T` is expected to implement [`serde::Deserialize`].\n///\n/// # Example\n///\n/// ```rust,no_run\n/// use axum::{routing::get, Router};\n/// use axum_extra::extract::OptionalQuery;\n/// use serde::Deserialize;\n///\n/// #[derive(Deserialize)]\n/// struct Pagination {\n///     page: usize,\n///     per_page: usize,\n/// }\n///\n/// // This will parse query strings like `?page=2&per_page=30` into `Some(Pagination)` and\n/// // empty query string into `None`\n/// async fn list_things(OptionalQuery(pagination): OptionalQuery<Pagination>) {\n///     match pagination {\n///         Some(Pagination{ page, per_page }) => { /* return specified page */ },\n///         None => { /* return fist page */ }\n///     }\n///     // ...\n/// }\n///\n/// let app = Router::new().route(\"/list_things\", get(list_things));\n/// # let _: Router = app;\n/// ```\n///\n/// If the query string cannot be parsed it will reject the request with a `400\n/// Bad Request` response.\n#[cfg_attr(docsrs, doc(cfg(feature = \"query\")))]\n#[derive(Debug, Clone, Copy, Default)]\npub struct OptionalQuery<T>(pub Option<T>);\n\nimpl<T, S> FromRequestParts<S> for OptionalQuery<T>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = OptionalQueryRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        if let Some(query) = parts.uri.query() {\n            let deserializer =\n                serde_html_form::Deserializer::new(form_urlencoded::parse(query.as_bytes()));\n            let value = serde_path_to_error::deserialize(deserializer)\n                .map_err(FailedToDeserializeQueryString::from_err)?;\n            Ok(Self(Some(value)))\n        } else {\n            Ok(Self(None))\n        }\n    }\n}\n\nimpl<T> std::ops::Deref for OptionalQuery<T> {\n    type Target = Option<T>;\n\n    #[inline]\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<T> std::ops::DerefMut for OptionalQuery<T> {\n    #[inline]\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`OptionalQuery`].\n    ///\n    /// Contains one variant for each way the [`OptionalQuery`] extractor can fail.\n    pub enum OptionalQueryRejection {\n        FailedToDeserializeQueryString,\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::routing::{get, post};\n    use axum::Router;\n    use http::header::CONTENT_TYPE;\n    use http::StatusCode;\n    use serde::Deserialize;\n\n    #[tokio::test]\n    async fn query_supports_multiple_values() {\n        #[derive(Deserialize)]\n        struct Data {\n            #[serde(rename = \"value\")]\n            values: Vec<String>,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            post(|Query(data): Query<Data>| async move { data.values.join(\",\") }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client\n            .post(\"/?value=one&value=two\")\n            .header(CONTENT_TYPE, \"application/x-www-form-urlencoded\")\n            .body(\"\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"one,two\");\n    }\n\n    #[tokio::test]\n    async fn correct_rejection_status_code() {\n        #[derive(Deserialize)]\n        #[allow(dead_code)]\n        struct Params {\n            n: i32,\n        }\n\n        async fn handler(_: Query<Params>) {}\n\n        let app = Router::new().route(\"/\", get(handler));\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/?n=hi\").await;\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n        assert_eq!(\n            res.text().await,\n            \"Failed to deserialize query string: n: invalid digit found in string\"\n        );\n    }\n\n    #[tokio::test]\n    async fn optional_query_supports_multiple_values() {\n        #[derive(Deserialize)]\n        struct Data {\n            #[serde(rename = \"value\")]\n            values: Vec<String>,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            post(|OptionalQuery(data): OptionalQuery<Data>| async move {\n                data.map(|Data { values }| values.join(\",\"))\n                    .unwrap_or(\"None\".to_owned())\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client\n            .post(\"/?value=one&value=two\")\n            .header(CONTENT_TYPE, \"application/x-www-form-urlencoded\")\n            .body(\"\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"one,two\");\n    }\n\n    #[tokio::test]\n    async fn optional_query_deserializes_no_parameters_into_none() {\n        #[derive(Deserialize)]\n        struct Data {\n            value: String,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            post(|OptionalQuery(data): OptionalQuery<Data>| async move {\n                match data {\n                    None => \"None\".into(),\n                    Some(data) => data.value,\n                }\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.post(\"/\").body(\"\").await;\n\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"None\");\n    }\n\n    #[tokio::test]\n    async fn optional_query_preserves_parsing_errors() {\n        #[derive(Deserialize)]\n        struct Data {\n            value: String,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            post(|OptionalQuery(data): OptionalQuery<Data>| async move {\n                match data {\n                    None => \"None\".into(),\n                    Some(data) => data.value,\n                }\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client\n            .post(\"/?other=something\")\n            .header(CONTENT_TYPE, \"application/x-www-form-urlencoded\")\n            .body(\"\")\n            .await;\n\n        assert_eq!(res.status(), StatusCode::BAD_REQUEST);\n    }\n\n    #[test]\n    fn test_try_from_uri() {\n        #[derive(Deserialize)]\n        struct TestQueryParams {\n            foo: Vec<String>,\n            bar: u32,\n        }\n        let uri: Uri = \"http://example.com/path?foo=hello&bar=42&foo=goodbye\"\n            .parse()\n            .unwrap();\n        let result: Query<TestQueryParams> = Query::try_from_uri(&uri).unwrap();\n        assert_eq!(result.foo, [String::from(\"hello\"), String::from(\"goodbye\")]);\n        assert_eq!(result.bar, 42);\n    }\n\n    #[test]\n    fn test_try_from_uri_with_invalid_query() {\n        #[derive(Deserialize)]\n        struct TestQueryParams {\n            _foo: String,\n            _bar: u32,\n        }\n        let uri: Uri = \"http://example.com/path?foo=hello&bar=invalid\"\n            .parse()\n            .unwrap();\n        let result: Result<Query<TestQueryParams>, _> = Query::try_from_uri(&uri);\n\n        assert!(result.is_err());\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/extract/with_rejection.rs",
    "content": "use axum::extract::{FromRequest, FromRequestParts, Request};\nuse axum::response::IntoResponse;\nuse http::request::Parts;\nuse std::fmt::{Debug, Display};\nuse std::marker::PhantomData;\nuse std::ops::{Deref, DerefMut};\n\n#[cfg(feature = \"typed-routing\")]\nuse crate::routing::TypedPath;\n\n/// Extractor for customizing extractor rejections\n///\n/// `WithRejection` wraps another extractor and gives you the result. If the\n/// extraction fails, the `Rejection` is transformed into `R` and returned as a\n/// response\n///\n/// `E` is expected to implement [`FromRequest`]\n///\n/// `R` is expected to implement [`IntoResponse`] and [`From<E::Rejection>`]\n///\n///\n/// # Example\n///\n/// ```rust\n/// use axum::extract::rejection::JsonRejection;\n/// use axum::response::{Response, IntoResponse};\n/// use axum::Json;\n/// use axum_extra::extract::WithRejection;\n/// use serde::Deserialize;\n///\n/// struct MyRejection { /* ... */ }\n///\n/// impl From<JsonRejection> for MyRejection {\n///     fn from(rejection: JsonRejection) -> MyRejection {\n///         // ...\n///         # todo!()\n///     }\n/// }\n///\n/// impl IntoResponse for MyRejection {\n///     fn into_response(self) -> Response {\n///         // ...\n///         # todo!()\n///     }\n/// }\n/// #[derive(Debug, Deserialize)]\n/// struct Person { /* ... */ }\n///\n/// async fn handler(\n///     // If the `Json` extractor ever fails, `MyRejection` will be sent to the\n///     // client using the `IntoResponse` impl\n///     WithRejection(Json(Person), _): WithRejection<Json<Person>, MyRejection>\n/// ) { /* ... */ }\n/// # let _: axum::Router = axum::Router::new().route(\"/\", axum::routing::get(handler));\n/// ```\n///\n/// [`FromRequest`]: axum::extract::FromRequest\n/// [`IntoResponse`]: axum::response::IntoResponse\n/// [`From<E::Rejection>`]: std::convert::From\npub struct WithRejection<E, R>(pub E, pub PhantomData<R>);\n\nimpl<E, R> WithRejection<E, R> {\n    /// Returns the wrapped extractor\n    pub fn into_inner(self) -> E {\n        self.0\n    }\n}\n\nimpl<E, R> Debug for WithRejection<E, R>\nwhere\n    E: Debug,\n{\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.debug_tuple(\"WithRejection\")\n            .field(&self.0)\n            .field(&self.1)\n            .finish()\n    }\n}\n\nimpl<E, R> Clone for WithRejection<E, R>\nwhere\n    E: Clone,\n{\n    fn clone(&self) -> Self {\n        Self(self.0.clone(), self.1)\n    }\n}\n\nimpl<E, R> Copy for WithRejection<E, R> where E: Copy {}\n\nimpl<E: Default, R> Default for WithRejection<E, R> {\n    fn default() -> Self {\n        Self(Default::default(), Default::default())\n    }\n}\n\nimpl<E, R> Deref for WithRejection<E, R> {\n    type Target = E;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<E, R> DerefMut for WithRejection<E, R> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nimpl<E, R, S> FromRequest<S> for WithRejection<E, R>\nwhere\n    S: Send + Sync,\n    E: FromRequest<S>,\n    R: From<E::Rejection> + IntoResponse,\n{\n    type Rejection = R;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        let extractor = E::from_request(req, state).await?;\n        Ok(Self(extractor, PhantomData))\n    }\n}\n\nimpl<E, R, S> FromRequestParts<S> for WithRejection<E, R>\nwhere\n    S: Send + Sync,\n    E: FromRequestParts<S>,\n    R: From<E::Rejection> + IntoResponse,\n{\n    type Rejection = R;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let extractor = E::from_request_parts(parts, state).await?;\n        Ok(Self(extractor, PhantomData))\n    }\n}\n\n#[cfg(feature = \"typed-routing\")]\nimpl<E, R> TypedPath for WithRejection<E, R>\nwhere\n    E: TypedPath,\n{\n    const PATH: &'static str = E::PATH;\n}\n\nimpl<E, R> Display for WithRejection<E, R>\nwhere\n    E: Display,\n{\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.0)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::body::Body;\n    use axum::http::Request;\n    use axum::response::Response;\n\n    #[tokio::test]\n    async fn extractor_rejection_is_transformed() {\n        struct TestExtractor;\n        struct TestRejection;\n\n        impl<S> FromRequestParts<S> for TestExtractor\n        where\n            S: Send + Sync,\n        {\n            type Rejection = ();\n\n            async fn from_request_parts(\n                _parts: &mut Parts,\n                _state: &S,\n            ) -> Result<Self, Self::Rejection> {\n                Err(())\n            }\n        }\n\n        impl IntoResponse for TestRejection {\n            fn into_response(self) -> Response {\n                ().into_response()\n            }\n        }\n\n        impl From<()> for TestRejection {\n            fn from(_: ()) -> Self {\n                Self\n            }\n        }\n\n        let req = Request::new(Body::empty());\n        let result = WithRejection::<TestExtractor, TestRejection>::from_request(req, &()).await;\n        assert!(matches!(result, Err(TestRejection)));\n\n        let (mut parts, _) = Request::new(()).into_parts();\n        let result =\n            WithRejection::<TestExtractor, TestRejection>::from_request_parts(&mut parts, &())\n                .await;\n        assert!(matches!(result, Err(TestRejection)));\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/handler/mod.rs",
    "content": "//! Additional handler utilities.\n\nuse axum::body::Body;\nuse axum::extract::Request;\nuse axum::{\n    extract::FromRequest,\n    handler::Handler,\n    response::{IntoResponse, Response},\n};\nuse futures_core::future::BoxFuture;\nuse futures_util::future::{FutureExt, Map};\nuse std::{future::Future, marker::PhantomData};\n\nmod or;\n\npub use self::or::Or;\n\n/// Trait for async functions that can be used to handle requests.\n///\n/// This trait is similar to [`Handler`] but rather than taking the request it takes the extracted\n/// inputs.\n///\n/// The drawbacks of this trait is that you cannot apply middleware to individual handlers like you\n/// can with [`Handler::layer`].\npub trait HandlerCallWithExtractors<T, S>: Sized {\n    /// The type of future calling this handler returns.\n    type Future: Future<Output = Response> + Send + 'static;\n\n    /// Call the handler with the extracted inputs.\n    fn call(self, extractors: T, state: S) -> <Self as HandlerCallWithExtractors<T, S>>::Future;\n\n    /// Convert this `HandlerCallWithExtractors` into [`Handler`].\n    fn into_handler(self) -> IntoHandler<Self, T, S> {\n        IntoHandler {\n            handler: self,\n            _marker: PhantomData,\n        }\n    }\n\n    /// Chain two handlers together, running the second one if the first one rejects.\n    ///\n    /// Note that this only moves to the next handler if an extractor fails. The response from\n    /// handlers are not considered.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum_extra::handler::HandlerCallWithExtractors;\n    /// use axum::{\n    ///     Router,\n    ///     routing::get,\n    ///     extract::FromRequestParts,\n    /// };\n    ///\n    /// // handlers for varying levels of access\n    /// async fn admin(admin: AdminPermissions) {\n    ///     // request came from an admin\n    /// }\n    ///\n    /// async fn user(user: User) {\n    ///     // we have a `User`\n    /// }\n    ///\n    /// async fn guest() {\n    ///     // `AdminPermissions` and `User` failed, so we're just a guest\n    /// }\n    ///\n    /// // extractors for checking permissions\n    /// struct AdminPermissions {}\n    ///\n    /// impl<S> FromRequestParts<S> for AdminPermissions\n    /// where\n    ///     S: Send + Sync,\n    /// {\n    ///     // check for admin permissions...\n    ///     # type Rejection = ();\n    ///     # async fn from_request_parts(parts: &mut http::request::Parts, state: &S) -> Result<Self, Self::Rejection> {\n    ///     #     todo!()\n    ///     # }\n    /// }\n    ///\n    /// struct User {}\n    ///\n    /// impl<S> FromRequestParts<S> for User\n    /// where\n    ///     S: Send + Sync,\n    /// {\n    ///     // check for a logged in user...\n    ///     # type Rejection = ();\n    ///     # async fn from_request_parts(parts: &mut http::request::Parts, state: &S) -> Result<Self, Self::Rejection> {\n    ///     #     todo!()\n    ///     # }\n    /// }\n    ///\n    /// let app = Router::new().route(\n    ///     \"/users/{id}\",\n    ///     get(\n    ///         // first try `admin`, if that rejects run `user`, finally falling back\n    ///         // to `guest`\n    ///         admin.or(user).or(guest)\n    ///     )\n    /// );\n    /// # let _: Router = app;\n    /// ```\n    fn or<R, Rt>(self, rhs: R) -> Or<Self, R, T, Rt, S>\n    where\n        R: HandlerCallWithExtractors<Rt, S>,\n    {\n        Or {\n            lhs: self,\n            rhs,\n            _marker: PhantomData,\n        }\n    }\n}\n\nmacro_rules! impl_handler_call_with {\n     ( $($ty:ident),* $(,)? ) => {\n         #[allow(non_snake_case)]\n         impl<F, Fut, S, $($ty,)*> HandlerCallWithExtractors<($($ty,)*), S> for F\n         where\n             F: FnOnce($($ty,)*) -> Fut,\n             Fut: Future + Send + 'static,\n             Fut::Output: IntoResponse,\n         {\n             // this puts `futures_util` in our public API but that's fine in axum-extra\n             type Future = Map<Fut, fn(Fut::Output) -> Response>;\n\n             fn call(\n                 self,\n                 ($($ty,)*): ($($ty,)*),\n                 _state: S,\n             ) -> <Self as HandlerCallWithExtractors<($($ty,)*), S>>::Future {\n                 self($($ty,)*).map(IntoResponse::into_response)\n             }\n         }\n     };\n }\n\nimpl_handler_call_with!();\nimpl_handler_call_with!(T1);\nimpl_handler_call_with!(T1, T2);\nimpl_handler_call_with!(T1, T2, T3);\nimpl_handler_call_with!(T1, T2, T3, T4);\nimpl_handler_call_with!(T1, T2, T3, T4, T5);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);\nimpl_handler_call_with!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);\n\n/// A [`Handler`] created from a [`HandlerCallWithExtractors`].\n///\n/// Created with [`HandlerCallWithExtractors::into_handler`].\n#[allow(missing_debug_implementations)]\npub struct IntoHandler<H, T, S> {\n    handler: H,\n    _marker: PhantomData<fn() -> (T, S)>,\n}\n\nimpl<H, T, S> Handler<T, S> for IntoHandler<H, T, S>\nwhere\n    H: HandlerCallWithExtractors<T, S> + Clone + Send + Sync + 'static,\n    T: FromRequest<S> + Send + 'static,\n    T::Rejection: Send,\n    S: Send + Sync + 'static,\n{\n    type Future = BoxFuture<'static, Response>;\n\n    fn call(self, req: Request, state: S) -> Self::Future {\n        let req = req.map(Body::new);\n        Box::pin(async move {\n            match T::from_request(req, &state).await {\n                Ok(t) => self.handler.call(t, state).await,\n                Err(rejection) => rejection.into_response(),\n            }\n        })\n    }\n}\n\nimpl<H, T, S> Copy for IntoHandler<H, T, S> where H: Copy {}\n\nimpl<H, T, S> Clone for IntoHandler<H, T, S>\nwhere\n    H: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            handler: self.handler.clone(),\n            _marker: self._marker,\n        }\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/handler/or.rs",
    "content": "use super::HandlerCallWithExtractors;\nuse crate::either::Either;\nuse axum::{\n    extract::{FromRequest, FromRequestParts, Request},\n    handler::Handler,\n    response::{IntoResponse, Response},\n};\nuse futures_core::future::BoxFuture;\nuse futures_util::future::{Either as EitherFuture, FutureExt, Map};\nuse std::{future::Future, marker::PhantomData};\n\n/// [`Handler`] that runs one [`Handler`] and if that rejects it'll fallback to another\n/// [`Handler`].\n///\n/// Created with [`HandlerCallWithExtractors::or`](super::HandlerCallWithExtractors::or).\n#[allow(missing_debug_implementations)]\npub struct Or<L, R, Lt, Rt, S> {\n    pub(super) lhs: L,\n    pub(super) rhs: R,\n    pub(super) _marker: PhantomData<fn() -> (Lt, Rt, S)>,\n}\n\nimpl<S, L, R, Lt, Rt> HandlerCallWithExtractors<Either<Lt, Rt>, S> for Or<L, R, Lt, Rt, S>\nwhere\n    L: HandlerCallWithExtractors<Lt, S> + Send + 'static,\n    R: HandlerCallWithExtractors<Rt, S> + Send + 'static,\n    Rt: Send + 'static,\n    Lt: Send + 'static,\n{\n    // this puts `futures_util` in our public API but that's fine in axum-extra\n    type Future = EitherFuture<\n        Map<L::Future, fn(<L::Future as Future>::Output) -> Response>,\n        Map<R::Future, fn(<R::Future as Future>::Output) -> Response>,\n    >;\n\n    fn call(\n        self,\n        extractors: Either<Lt, Rt>,\n        state: S,\n    ) -> <Self as HandlerCallWithExtractors<Either<Lt, Rt>, S>>::Future {\n        match extractors {\n            Either::E1(lt) => self\n                .lhs\n                .call(lt, state)\n                .map(IntoResponse::into_response as _)\n                .left_future(),\n            Either::E2(rt) => self\n                .rhs\n                .call(rt, state)\n                .map(IntoResponse::into_response as _)\n                .right_future(),\n        }\n    }\n}\n\nimpl<S, L, R, Lt, Rt, M> Handler<(M, Lt, Rt), S> for Or<L, R, Lt, Rt, S>\nwhere\n    L: HandlerCallWithExtractors<Lt, S> + Clone + Send + Sync + 'static,\n    R: HandlerCallWithExtractors<Rt, S> + Clone + Send + Sync + 'static,\n    Lt: FromRequestParts<S> + Send + 'static,\n    Rt: FromRequest<S, M> + Send + 'static,\n    Lt::Rejection: Send,\n    Rt::Rejection: Send,\n    S: Send + Sync + 'static,\n{\n    // this puts `futures_util` in our public API but that's fine in axum-extra\n    type Future = BoxFuture<'static, Response>;\n\n    fn call(self, req: Request, state: S) -> Self::Future {\n        let (mut parts, body) = req.into_parts();\n\n        Box::pin(async move {\n            if let Ok(lt) = Lt::from_request_parts(&mut parts, &state).await {\n                return self.lhs.call(lt, state).await;\n            }\n\n            let req = Request::from_parts(parts, body);\n\n            match Rt::from_request(req, &state).await {\n                Ok(rt) => self.rhs.call(rt, state).await,\n                Err(rejection) => rejection.into_response(),\n            }\n        })\n    }\n}\n\nimpl<L, R, Lt, Rt, S> Copy for Or<L, R, Lt, Rt, S>\nwhere\n    L: Copy,\n    R: Copy,\n{\n}\n\nimpl<L, R, Lt, Rt, S> Clone for Or<L, R, Lt, Rt, S>\nwhere\n    L: Clone,\n    R: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            lhs: self.lhs.clone(),\n            rhs: self.rhs.clone(),\n            _marker: self._marker,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::{\n        extract::{Path, Query},\n        routing::get,\n        Router,\n    };\n    use serde::Deserialize;\n\n    #[tokio::test]\n    async fn works() {\n        #[derive(Deserialize)]\n        struct Params {\n            a: String,\n        }\n\n        async fn one(Path(id): Path<u32>) -> String {\n            id.to_string()\n        }\n\n        async fn two(Query(params): Query<Params>) -> String {\n            params.a\n        }\n\n        async fn three() -> &'static str {\n            \"fallback\"\n        }\n\n        let app = Router::new().route(\"/{id}\", get(one.or(two).or(three)));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/123\").await;\n        assert_eq!(res.text().await, \"123\");\n\n        let res = client.get(\"/foo?a=bar\").await;\n        assert_eq!(res.text().await, \"bar\");\n\n        let res = client.get(\"/foo\").await;\n        assert_eq!(res.text().await, \"fallback\");\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/json_lines.rs",
    "content": "//! Newline delimited JSON extractor and response.\n\nuse axum_core::{\n    body::Body,\n    extract::{FromRequest, Request},\n    response::{IntoResponse, Response},\n    BoxError, RequestExt,\n};\nuse bytes::{BufMut, BytesMut};\nuse futures_core::{stream::BoxStream, Stream, TryStream};\nuse futures_util::stream::TryStreamExt;\nuse pin_project_lite::pin_project;\nuse serde_core::{de::DeserializeOwned, Serialize};\nuse std::{\n    convert::Infallible,\n    io::{self, Write},\n    marker::PhantomData,\n    pin::Pin,\n    task::{Context, Poll},\n};\nuse tokio::io::AsyncBufReadExt;\nuse tokio_stream::wrappers::LinesStream;\nuse tokio_util::io::StreamReader;\n\npin_project! {\n    /// A stream of newline delimited JSON.\n    ///\n    /// This can be used both as an extractor and as a response.\n    ///\n    /// # As extractor\n    ///\n    /// ```rust\n    /// use axum_extra::json_lines::JsonLines;\n    /// use futures_util::stream::StreamExt;\n    ///\n    /// async fn handler(mut stream: JsonLines<serde_json::Value>) {\n    ///     while let Some(value) = stream.next().await {\n    ///         // ...\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// # As response\n    ///\n    /// ```rust\n    /// use axum::{BoxError, response::{IntoResponse, Response}};\n    /// use axum_extra::json_lines::JsonLines;\n    /// use futures_core::stream::Stream;\n    ///\n    /// fn stream_of_values() -> impl Stream<Item = Result<serde_json::Value, BoxError>> {\n    ///     # futures_util::stream::empty()\n    /// }\n    ///\n    /// async fn handler() -> Response {\n    ///     JsonLines::new(stream_of_values()).into_response()\n    /// }\n    /// ```\n    // we use `AsExtractor` as the default because you're more likely to name this type if it's used\n    // as an extractor\n    #[must_use]\n    pub struct JsonLines<S, T = AsExtractor> {\n        #[pin]\n        inner: Inner<S>,\n        _marker: PhantomData<T>,\n    }\n}\n\npin_project! {\n    #[project = InnerProj]\n    enum Inner<S> {\n        Response {\n            #[pin]\n            stream: S,\n        },\n        Extractor {\n            #[pin]\n            stream: BoxStream<'static, Result<S, axum_core::Error>>,\n        },\n    }\n}\n\n/// Marker type used to prove that an `JsonLines` was constructed via `FromRequest`.\n#[derive(Debug)]\n#[non_exhaustive]\npub struct AsExtractor;\n\n/// Marker type used to prove that an `JsonLines` was constructed via `JsonLines::new`.\n#[derive(Debug)]\n#[non_exhaustive]\npub struct AsResponse;\n\nimpl<S> JsonLines<S, AsResponse> {\n    /// Create a new `JsonLines` from a stream of items.\n    pub fn new(stream: S) -> Self {\n        Self {\n            inner: Inner::Response { stream },\n            _marker: PhantomData,\n        }\n    }\n}\n\nimpl<S, T> FromRequest<S> for JsonLines<T, AsExtractor>\nwhere\n    T: DeserializeOwned,\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        // `Stream::lines` isn't a thing so we have to convert it into an `AsyncRead`\n        // so we can call `AsyncRead::lines` and then convert it back to a `Stream`\n        let body = req.into_limited_body();\n        let stream = body.into_data_stream();\n        let stream = stream.map_err(io::Error::other);\n        let read = StreamReader::new(stream);\n        let lines_stream = LinesStream::new(read.lines());\n\n        let deserialized_stream =\n            lines_stream\n                .map_err(axum_core::Error::new)\n                .and_then(|value| async move {\n                    serde_json::from_str::<T>(&value).map_err(axum_core::Error::new)\n                });\n\n        Ok(Self {\n            inner: Inner::Extractor {\n                stream: Box::pin(deserialized_stream),\n            },\n            _marker: PhantomData,\n        })\n    }\n}\n\nimpl<T> Stream for JsonLines<T, AsExtractor> {\n    type Item = Result<T, axum_core::Error>;\n\n    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {\n        match self.project().inner.project() {\n            InnerProj::Extractor { stream } => stream.poll_next(cx),\n            // `JsonLines<_, AsExtractor>` can only be constructed via `FromRequest`\n            // which doesn't use this variant\n            InnerProj::Response { .. } => unreachable!(),\n        }\n    }\n}\n\nimpl<S> IntoResponse for JsonLines<S, AsResponse>\nwhere\n    S: TryStream + Send + 'static,\n    S::Ok: Serialize + Send,\n    S::Error: Into<BoxError>,\n{\n    fn into_response(self) -> Response {\n        let inner = match self.inner {\n            Inner::Response { stream } => stream,\n            // `JsonLines<_, AsResponse>` can only be constructed via `JsonLines::new`\n            // which doesn't use this variant\n            Inner::Extractor { .. } => unreachable!(),\n        };\n\n        let stream = inner.map_err(Into::into).and_then(|value| async move {\n            let mut buf = BytesMut::new().writer();\n            serde_json::to_writer(&mut buf, &value)?;\n            buf.write_all(b\"\\n\")?;\n            Ok::<_, BoxError>(buf.into_inner().freeze())\n        });\n        let stream = Body::from_stream(stream);\n\n        // there is no consensus around mime type yet\n        // https://github.com/wardi/jsonlines/issues/36\n        stream.into_response()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::JsonLines;\n    use crate::test_helpers::*;\n    use axum::{\n        routing::{get, post},\n        Router,\n    };\n    use futures_util::StreamExt;\n    use http::StatusCode;\n    use serde::{Deserialize, Serialize};\n    use std::{convert::Infallible, error::Error};\n\n    #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]\n    struct User {\n        id: i32,\n    }\n\n    #[tokio::test]\n    async fn extractor() {\n        let app = Router::new().route(\n            \"/\",\n            post(|mut stream: JsonLines<User>| async move {\n                assert_eq!(stream.next().await.unwrap().unwrap(), User { id: 1 });\n                assert_eq!(stream.next().await.unwrap().unwrap(), User { id: 2 });\n                assert_eq!(stream.next().await.unwrap().unwrap(), User { id: 3 });\n\n                // sources are downcastable to `serde_json::Error`\n                let err = stream.next().await.unwrap().unwrap_err();\n                let _: &serde_json::Error = err\n                    .source()\n                    .unwrap()\n                    .downcast_ref::<serde_json::Error>()\n                    .unwrap();\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client\n            .post(\"/\")\n            .body(\n                [\n                    \"{\\\"id\\\":1}\",\n                    \"{\\\"id\\\":2}\",\n                    \"{\\\"id\\\":3}\",\n                    // to trigger an error for source downcasting\n                    \"{\\\"id\\\":false}\",\n                ]\n                .join(\"\\n\"),\n            )\n            .await;\n        assert_eq!(res.status(), StatusCode::OK);\n    }\n\n    #[tokio::test]\n    async fn response() {\n        let app = Router::new().route(\n            \"/\",\n            get(|| async {\n                let values = futures_util::stream::iter(vec![\n                    Ok::<_, Infallible>(User { id: 1 }),\n                    Ok::<_, Infallible>(User { id: 2 }),\n                    Ok::<_, Infallible>(User { id: 3 }),\n                ]);\n                JsonLines::new(values)\n            }),\n        );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/\").await;\n\n        let values = res\n            .text()\n            .await\n            .lines()\n            .map(|line| serde_json::from_str::<User>(line).unwrap())\n            .collect::<Vec<_>>();\n\n        assert_eq!(\n            values,\n            vec![User { id: 1 }, User { id: 2 }, User { id: 3 },]\n        );\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/lib.rs",
    "content": "//! Extra utilities for [`axum`].\n//!\n//! # Feature flags\n//!\n//! axum-extra uses a set of [feature flags] to reduce the amount of compiled and\n//! optional dependencies.\n//!\n//! The following optional features are available:\n//!\n//! Name | Description | Default?\n//! ---|---|---\n//! `async-read-body` | Enables the [`AsyncReadBody`](crate::body::AsyncReadBody) body |\n//! `attachment` | Enables the [`Attachment`](crate::response::Attachment) response |\n//! `cached` | Enables the [`Cached`](crate::extract::Cached) extractor |\n//! `cookie` | Enables the [`CookieJar`](crate::extract::CookieJar) extractor |\n//! `cookie-private` | Enables the [`PrivateCookieJar`](crate::extract::PrivateCookieJar) extractor |\n//! `cookie-signed` | Enables the [`SignedCookieJar`](crate::extract::SignedCookieJar) extractor |\n//! `cookie-key-expansion` | Enables the [`Key::derive_from`](crate::extract::cookie::Key::derive_from) method |\n//! `erased-json` | Enables the [`ErasedJson`](crate::response::ErasedJson) response |\n//! `error-response` | Enables the [`InternalServerError`](crate::response::InternalServerError) response |\n//! `form` (deprecated) | Enables the [`Form`](crate::extract::Form) extractor |\n//! `handler` | Enables the [handler] utilities |\n//! `json-deserializer` | Enables the [`JsonDeserializer`](crate::extract::JsonDeserializer) extractor |\n//! `json-lines` | Enables the [`JsonLines`](crate::extract::JsonLines) extractor and response |\n//! `middleware` | Enables the [middleware] utilities |\n//! `multipart` | Enables the [`Multipart`](crate::extract::Multipart) extractor |\n//! `protobuf` | Enables the [`Protobuf`](crate::protobuf::Protobuf) extractor and response |\n//! `query` (deprecated) | Enables the [`Query`](crate::extract::Query) extractor |\n//! `routing` | Enables the [routing] utilities |\n//! `tracing` | Log rejections from built-in extractors | <span role=\"img\" aria-label=\"Default feature\">✔</span>\n//! `typed-routing` | Enables the [`TypedPath`](crate::routing::TypedPath) routing utilities and the `routing` feature. |\n//! `typed-header` | Enables the [`TypedHeader`] extractor and response |\n//! `file-stream` | Enables the [`FileStream`](crate::response::FileStream) response |\n//! `with-rejection` | Enables the [`WithRejection`](crate::extract::WithRejection) extractor |\n//!\n//! [`axum`]: https://crates.io/crates/axum\n\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(test, allow(clippy::float_cmp))]\n#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]\n\n#[allow(unused_extern_crates)]\nextern crate self as axum_extra;\n\npub mod body;\npub mod either;\npub mod extract;\npub mod response;\n\n#[cfg(feature = \"routing\")]\npub mod routing;\n\n#[cfg(feature = \"middleware\")]\npub mod middleware;\n\n#[cfg(feature = \"handler\")]\npub mod handler;\n\n#[cfg(feature = \"json-lines\")]\npub mod json_lines;\n\n#[cfg(feature = \"typed-header\")]\npub mod typed_header;\n\n#[cfg(feature = \"typed-header\")]\n#[doc(no_inline)]\npub use headers;\n\n#[cfg(feature = \"typed-header\")]\n#[doc(inline)]\npub use typed_header::TypedHeader;\n\n#[cfg(feature = \"protobuf\")]\npub mod protobuf;\n\n/// _not_ public API\n#[cfg(feature = \"typed-routing\")]\n#[doc(hidden)]\npub mod __private {\n    use percent_encoding::{AsciiSet, CONTROLS};\n\n    pub use percent_encoding::utf8_percent_encode;\n\n    // from https://github.com/servo/rust-url/blob/master/url/src/parser.rs\n    const FRAGMENT: &AsciiSet = &CONTROLS.add(b' ').add(b'\"').add(b'<').add(b'>').add(b'`');\n    const PATH: &AsciiSet = &FRAGMENT.add(b'#').add(b'?').add(b'{').add(b'}');\n    pub const PATH_SEGMENT: &AsciiSet = &PATH.add(b'/').add(b'%');\n}\n\n#[cfg(test)]\npub(crate) use axum::test_helpers;\n"
  },
  {
    "path": "axum-extra/src/middleware.rs",
    "content": "//! Additional middleware utilities.\n\nuse crate::either::Either;\nuse axum::middleware::ResponseAxumBodyLayer;\nuse tower_layer::Identity;\n\n/// Convert an `Option<Layer>` into a [`Layer`].\n///\n/// If the layer is a `Some` it'll be applied, otherwise not.\n///\n/// # Example\n///\n/// ```\n/// use axum_extra::middleware::option_layer;\n/// use axum::{Router, routing::get};\n/// use std::time::Duration;\n/// use tower_http::timeout::TimeoutLayer;\n///\n/// # let option_timeout = Some(Duration::new(10, 0));\n/// let timeout_layer = option_timeout.map(TimeoutLayer::new);\n///\n/// let app = Router::new()\n///     .route(\"/\", get(|| async {}))\n///     .layer(option_layer(timeout_layer));\n/// # let _: Router = app;\n/// ```\n///\n/// # Difference between this and [`tower::util::option_layer`]\n///\n/// `axum_extra::middleware::option_layer` makes sure that the output `Body` is [`axum::body::Body`].\n///\n/// [`Layer`]: tower_layer::Layer\npub fn option_layer<L>(layer: Option<L>) -> Either<(ResponseAxumBodyLayer, L), Identity> {\n    layer\n        .map(|layer| Either::E1((ResponseAxumBodyLayer, layer)))\n        .unwrap_or_else(|| Either::E2(Identity::new()))\n}\n\n#[cfg(test)]\nmod tests {\n    use std::{\n        convert::Infallible,\n        pin::Pin,\n        task::{Context, Poll},\n    };\n\n    use axum::{body::Body as AxumBody, Router};\n    use bytes::Bytes;\n    use http_body::Body as HttpBody;\n    use tower_http::map_response_body::MapResponseBodyLayer;\n\n    use super::option_layer;\n\n    #[test]\n    fn remap_response_body() {\n        struct BodyWrapper;\n\n        impl BodyWrapper {\n            fn new(_: AxumBody) -> Self {\n                Self\n            }\n        }\n\n        impl HttpBody for BodyWrapper {\n            type Data = Bytes;\n            type Error = Infallible;\n            fn poll_frame(\n                self: Pin<&mut Self>,\n                _cx: &mut Context<'_>,\n            ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> {\n                unimplemented!()\n            }\n            fn is_end_stream(&self) -> bool {\n                unimplemented!()\n            }\n            fn size_hint(&self) -> http_body::SizeHint {\n                unimplemented!()\n            }\n        }\n        let _app: Router = Router::new().layer(option_layer(Some(MapResponseBodyLayer::new(\n            BodyWrapper::new,\n        ))));\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/protobuf.rs",
    "content": "//! Protocol Buffer extractor and response.\n\nuse axum_core::__composite_rejection as composite_rejection;\nuse axum_core::__define_rejection as define_rejection;\nuse axum_core::{\n    extract::{rejection::BytesRejection, FromRequest, Request},\n    response::{IntoResponse, IntoResponseFailed, Response},\n    RequestExt,\n};\nuse bytes::BytesMut;\nuse http::StatusCode;\nuse http_body_util::BodyExt;\nuse prost::Message;\n\n/// A Protocol Buffer message extractor and response.\n///\n/// This can be used both as an extractor and as a response.\n///\n/// # As extractor\n///\n/// When used as an extractor, it can decode request bodies into some type that\n/// implements [`prost::Message`]. The request will be rejected (and a [`ProtobufRejection`] will\n/// be returned) if:\n///\n/// - The body couldn't be decoded into the target Protocol Buffer message type.\n/// - Buffering the request body fails.\n///\n/// See [`ProtobufRejection`] for more details.\n///\n/// The extractor does not expect a `Content-Type` header to be present in the request.\n///\n/// # Extractor example\n///\n/// ```rust,no_run\n/// use axum::{routing::post, Router};\n/// use axum_extra::protobuf::Protobuf;\n///\n/// #[derive(prost::Message)]\n/// struct CreateUser {\n///     #[prost(string, tag=\"1\")]\n///     email: String,\n///     #[prost(string, tag=\"2\")]\n///     password: String,\n/// }\n///\n/// async fn create_user(Protobuf(payload): Protobuf<CreateUser>) {\n///     // payload is `CreateUser`\n/// }\n///\n/// let app = Router::new().route(\"/users\", post(create_user));\n/// # let _: Router = app;\n/// ```\n///\n/// # As response\n///\n/// When used as a response, it can encode any type that implements [`prost::Message`] to\n/// a newly allocated buffer.\n///\n/// If no `Content-Type` header is set, the `Content-Type: application/octet-stream` header\n/// will be used automatically.\n///\n/// # Response example\n///\n/// ```\n/// use axum::{\n///     extract::Path,\n///     routing::get,\n///     Router,\n/// };\n/// use axum_extra::protobuf::Protobuf;\n///\n/// #[derive(prost::Message)]\n/// struct User {\n///     #[prost(string, tag=\"1\")]\n///     username: String,\n/// }\n///\n/// async fn get_user(Path(user_id) : Path<String>) -> Protobuf<User> {\n///     let user = find_user(user_id).await;\n///     Protobuf(user)\n/// }\n///\n/// async fn find_user(user_id: String) -> User {\n///     // ...\n///     # unimplemented!()\n/// }\n///\n/// let app = Router::new().route(\"/users/{id}\", get(get_user));\n/// # let _: Router = app;\n/// ```\n#[derive(Debug, Clone, Copy, Default)]\n#[cfg_attr(docsrs, doc(cfg(feature = \"protobuf\")))]\n#[must_use]\npub struct Protobuf<T>(pub T);\n\nimpl<T, S> FromRequest<S> for Protobuf<T>\nwhere\n    T: Message + Default,\n    S: Send + Sync,\n{\n    type Rejection = ProtobufRejection;\n\n    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {\n        let mut buf = req\n            .into_limited_body()\n            .collect()\n            .await\n            .map_err(ProtobufDecodeError)?\n            .aggregate();\n\n        match T::decode(&mut buf) {\n            Ok(value) => Ok(Self(value)),\n            Err(err) => Err(ProtobufDecodeError::from_err(err).into()),\n        }\n    }\n}\n\naxum_core::__impl_deref!(Protobuf);\n\nimpl<T> From<T> for Protobuf<T> {\n    fn from(inner: T) -> Self {\n        Self(inner)\n    }\n}\n\nimpl<T> IntoResponse for Protobuf<T>\nwhere\n    T: Message + Default,\n{\n    fn into_response(self) -> Response {\n        let mut buf = BytesMut::with_capacity(self.0.encoded_len());\n        match &self.0.encode(&mut buf) {\n            Ok(()) => buf.into_response(),\n            Err(err) => (\n                StatusCode::INTERNAL_SERVER_ERROR,\n                IntoResponseFailed,\n                err.to_string(),\n            )\n                .into_response(),\n        }\n    }\n}\n\ndefine_rejection! {\n    #[status = UNPROCESSABLE_ENTITY]\n    #[body = \"Failed to decode the body\"]\n    /// Rejection type for [`Protobuf`].\n    ///\n    /// This rejection is used if the request body couldn't be decoded into the target type.\n    pub struct ProtobufDecodeError(Error);\n}\n\ncomposite_rejection! {\n    /// Rejection used for [`Protobuf`].\n    ///\n    /// Contains one variant for each way the [`Protobuf`] extractor\n    /// can fail.\n    pub enum ProtobufRejection {\n        ProtobufDecodeError,\n        BytesRejection,\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::{routing::post, Router};\n    use http::header::CONTENT_TYPE;\n    use http::StatusCode;\n\n    #[tokio::test]\n    async fn decode_body() {\n        #[derive(prost::Message)]\n        struct Input {\n            #[prost(string, tag = \"1\")]\n            foo: String,\n        }\n\n        let app = Router::new().route(\n            \"/\",\n            post(|Protobuf(input): Protobuf<Input>| async move { input.foo }),\n        );\n\n        let input = Input {\n            foo: \"bar\".to_owned(),\n        };\n\n        let client = TestClient::new(app);\n        let res = client.post(\"/\").body(input.encode_to_vec()).await;\n\n        let status = res.status();\n        let body = res.text().await;\n\n        assert_eq!(status, StatusCode::OK);\n        assert_eq!(body, input.foo);\n    }\n\n    #[tokio::test]\n    async fn prost_decode_error() {\n        #[derive(prost::Message)]\n        struct Input {\n            #[prost(string, tag = \"1\")]\n            foo: String,\n        }\n\n        #[derive(prost::Message)]\n        struct Expected {\n            #[prost(int32, tag = \"1\")]\n            test: i32,\n        }\n\n        let app = Router::new().route(\"/\", post(|_: Protobuf<Expected>| async {}));\n\n        let input = Input {\n            foo: \"bar\".to_owned(),\n        };\n\n        let client = TestClient::new(app);\n        let res = client.post(\"/\").body(input.encode_to_vec()).await;\n\n        assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);\n        assert!(res.text().await.starts_with(\"Failed to decode the body\"));\n    }\n\n    #[tokio::test]\n    async fn encode_body() {\n        #[derive(prost::Message)]\n        struct Input {\n            #[prost(string, tag = \"1\")]\n            foo: String,\n        }\n\n        #[derive(prost::Message)]\n        struct Output {\n            #[prost(string, tag = \"1\")]\n            result: String,\n        }\n\n        #[axum::debug_handler]\n        async fn handler(Protobuf(input): Protobuf<Input>) -> Protobuf<Output> {\n            let output = Output { result: input.foo };\n\n            Protobuf(output)\n        }\n\n        let app = Router::new().route(\"/\", post(handler));\n\n        let input = Input {\n            foo: \"bar\".to_owned(),\n        };\n\n        let client = TestClient::new(app);\n        let res = client.post(\"/\").body(input.encode_to_vec()).await;\n\n        let content_type_header_value = res\n            .headers()\n            .get(CONTENT_TYPE)\n            .expect(\"missing expected header\");\n\n        assert_eq!(\n            content_type_header_value,\n            mime::APPLICATION_OCTET_STREAM.as_ref()\n        );\n\n        let body = res.bytes().await;\n\n        let output = Output::decode(body).unwrap();\n\n        assert_eq!(output.result, input.foo);\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/response/attachment.rs",
    "content": "use super::content_disposition::EscapedFilename;\nuse axum_core::response::IntoResponse;\nuse http::{header, HeaderMap, HeaderValue};\nuse tracing::error;\n\n/// A file attachment response.\n///\n/// This type will set the `Content-Disposition` header to `attachment`. In response a webbrowser\n/// will offer to download the file instead of displaying it directly.\n///\n/// Use the `filename` and `content_type` methods to set the filename or content-type of the\n/// attachment. If these values are not set they will not be sent.\n///\n///\n/// # Example\n///\n/// ```rust\n///  use axum::{http::StatusCode, routing::get, Router};\n///  use axum_extra::response::Attachment;\n///\n///  async fn cargo_toml() -> Result<Attachment<String>, (StatusCode, String)> {\n///      let file_contents = tokio::fs::read_to_string(\"Cargo.toml\")\n///          .await\n///          .map_err(|err| (StatusCode::NOT_FOUND, format!(\"File not found: {err}\")))?;\n///      Ok(Attachment::new(file_contents)\n///          .filename(\"Cargo.toml\")\n///          .content_type(\"text/x-toml\"))\n///  }\n///\n///  let app = Router::new().route(\"/Cargo.toml\", get(cargo_toml));\n///  let _: Router = app;\n/// ```\n///\n/// # Note\n///\n/// If you use axum with hyper, hyper will set the `Content-Length` if it is known.\n#[derive(Debug)]\n#[must_use]\npub struct Attachment<T> {\n    inner: T,\n    filename: Option<HeaderValue>,\n    content_type: Option<HeaderValue>,\n}\n\nimpl<T: IntoResponse> Attachment<T> {\n    /// Creates a new [`Attachment`].\n    pub fn new(inner: T) -> Self {\n        Self {\n            inner,\n            filename: None,\n            content_type: None,\n        }\n    }\n\n    /// Sets the filename of the [`Attachment`].\n    ///\n    /// This updates the `Content-Disposition` header to add a filename.\n    pub fn filename<H: TryInto<HeaderValue>>(mut self, value: H) -> Self {\n        self.filename = if let Ok(filename) = value.try_into() {\n            Some(filename)\n        } else {\n            error!(\"Attachment filename contains invalid characters\");\n            None\n        };\n        self\n    }\n\n    /// Sets the content-type of the [`Attachment`]\n    pub fn content_type<H: TryInto<HeaderValue>>(mut self, value: H) -> Self {\n        if let Ok(content_type) = value.try_into() {\n            self.content_type = Some(content_type);\n        } else {\n            error!(\"Attachment content-type contains invalid characters\");\n        }\n        self\n    }\n}\n\nimpl<T> IntoResponse for Attachment<T>\nwhere\n    T: IntoResponse,\n{\n    fn into_response(self) -> axum_core::response::Response {\n        let mut headers = HeaderMap::new();\n\n        if let Some(content_type) = self.content_type {\n            headers.append(header::CONTENT_TYPE, content_type);\n        }\n\n        let content_disposition = if let Some(filename) = self.filename {\n            let filename_str = filename\n                .to_str()\n                .expect(\"This was a HeaderValue so this can not fail\");\n            let value = format!(\"attachment; filename=\\\"{}\\\"\", EscapedFilename(filename_str));\n            HeaderValue::try_from(value).expect(\"This was a HeaderValue so this can not fail\")\n        } else {\n            HeaderValue::from_static(\"attachment\")\n        };\n\n        headers.append(header::CONTENT_DISPOSITION, content_disposition);\n\n        (headers, self.inner).into_response()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum_core::response::IntoResponse;\n    use http::header::CONTENT_DISPOSITION;\n\n    #[test]\n    fn attachment_without_filename() {\n        let attachment = Attachment::new(\"data\").into_response();\n        let value = attachment.headers().get(CONTENT_DISPOSITION).unwrap();\n        assert_eq!(value, \"attachment\");\n    }\n\n    #[test]\n    fn attachment_with_normal_filename() {\n        let attachment = Attachment::new(\"data\")\n            .filename(\"report.pdf\")\n            .into_response();\n        let value = attachment.headers().get(CONTENT_DISPOSITION).unwrap();\n        assert_eq!(value, \"attachment; filename=\\\"report.pdf\\\"\");\n    }\n\n    #[test]\n    fn attachment_filename_escapes_quotes() {\n        // A filename containing a double quote should be escaped to prevent\n        // Content-Disposition parameter injection (see CVE-2023-29401)\n        let attachment = Attachment::new(\"data\")\n            .filename(\"evil\\\"; filename*=UTF-8''pwned.txt; x=\\\"\")\n            .into_response();\n        let value = attachment.headers().get(CONTENT_DISPOSITION).unwrap();\n        assert_eq!(\n            value,\n            \"attachment; filename=\\\"evil\\\\\\\"; filename*=UTF-8''pwned.txt; x=\\\\\\\"\\\"\"\n        );\n    }\n\n    #[test]\n    fn attachment_filename_escapes_backslashes() {\n        let attachment = Attachment::new(\"data\")\n            .filename(\"file\\\\name.txt\")\n            .into_response();\n        let value = attachment.headers().get(CONTENT_DISPOSITION).unwrap();\n        assert_eq!(value, \"attachment; filename=\\\"file\\\\\\\\name.txt\\\"\");\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/response/content_disposition.rs",
    "content": "use std::fmt::{self, Write};\n\n/// A wrapper type that escapes backslashes and double quotes when formatted,\n/// for safe inclusion in Content-Disposition header quoted-strings.\n///\n/// This prevents Content-Disposition header parameter injection\n/// (similar to CVE-2023-29401).\npub(crate) struct EscapedFilename<'a>(pub &'a str);\n\nimpl fmt::Display for EscapedFilename<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        for c in self.0.chars() {\n            if c == '\\\\' || c == '\"' {\n                f.write_char('\\\\')?;\n            }\n            f.write_char(c)?;\n        }\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn no_special_characters() {\n        assert_eq!(EscapedFilename(\"report.pdf\").to_string(), \"report.pdf\");\n    }\n\n    #[test]\n    fn escapes_double_quotes() {\n        assert_eq!(\n            EscapedFilename(\"evil\\\"; filename*=UTF-8''pwned.txt; x=\\\"\").to_string(),\n            \"evil\\\\\\\"; filename*=UTF-8''pwned.txt; x=\\\\\\\"\",\n        );\n    }\n\n    #[test]\n    fn escapes_backslashes() {\n        assert_eq!(\n            EscapedFilename(\"file\\\\name.txt\").to_string(),\n            \"file\\\\\\\\name.txt\",\n        );\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/response/erased_json.rs",
    "content": "use std::sync::Arc;\n\nuse axum_core::response::{IntoResponse, IntoResponseFailed, Response};\nuse bytes::{BufMut, Bytes, BytesMut};\nuse http::{header, HeaderValue, StatusCode};\nuse serde_core::Serialize;\n\n/// A response type that holds a JSON in serialized form.\n///\n/// This allows returning a borrowing type from a handler, or returning different response\n/// types as JSON from different branches inside a handler.\n///\n/// Like [`axum::Json`],\n/// if the [`Serialize`] implementation fails\n/// or if a map with non-string keys is used,\n/// a 500 response will be issued\n/// whose body is the error message in UTF-8.\n///\n/// This can be constructed using [`new`](ErasedJson::new)\n/// or the [`json!`](crate::json) macro.\n///\n/// # Example\n///\n/// ```rust\n/// # use axum::{response::IntoResponse};\n/// # use axum_extra::response::ErasedJson;\n/// async fn handler() -> ErasedJson {\n///     # let condition = true;\n///     # let foo = ();\n///     # let bar = vec![()];\n///     // ...\n///\n///     if condition {\n///         ErasedJson::new(&foo)\n///     } else {\n///         ErasedJson::new(&bar)\n///     }\n/// }\n/// ```\n#[cfg_attr(docsrs, doc(cfg(feature = \"erased-json\")))]\n#[derive(Clone, Debug)]\n#[must_use]\npub struct ErasedJson(Result<Bytes, Arc<serde_json::Error>>);\n\nimpl ErasedJson {\n    /// Create an `ErasedJson` by serializing a value with the compact formatter.\n    pub fn new<T: Serialize>(val: T) -> Self {\n        let mut bytes = BytesMut::with_capacity(128);\n        let result = match serde_json::to_writer((&mut bytes).writer(), &val) {\n            Ok(()) => Ok(bytes.freeze()),\n            Err(e) => Err(Arc::new(e)),\n        };\n        Self(result)\n    }\n\n    /// Create an `ErasedJson` by serializing a value with the pretty formatter.\n    pub fn pretty<T: Serialize>(val: T) -> Self {\n        let mut bytes = BytesMut::with_capacity(128);\n        let result = match serde_json::to_writer_pretty((&mut bytes).writer(), &val) {\n            Ok(()) => {\n                bytes.put_u8(b'\\n');\n                Ok(bytes.freeze())\n            }\n            Err(e) => Err(Arc::new(e)),\n        };\n        Self(result)\n    }\n}\n\nimpl IntoResponse for ErasedJson {\n    fn into_response(self) -> Response {\n        match self.0 {\n            Ok(bytes) => (\n                [(\n                    header::CONTENT_TYPE,\n                    HeaderValue::from_static(mime::APPLICATION_JSON.as_ref()),\n                )],\n                bytes,\n            )\n                .into_response(),\n            Err(err) => (\n                StatusCode::INTERNAL_SERVER_ERROR,\n                IntoResponseFailed,\n                err.to_string(),\n            )\n                .into_response(),\n        }\n    }\n}\n\n/// Construct an [`ErasedJson`] response from a JSON literal.\n///\n/// A `Content-Type: application/json` header is automatically added.\n/// Any variable or expression implementing [`Serialize`]\n/// can be interpolated as a value in the literal.\n/// If the [`Serialize`] implementation fails,\n/// or if a map with non-string keys is used,\n/// a 500 response will be issued\n/// whose body is the error message in UTF-8.\n///\n/// Internally,\n/// this function uses the [`typed_json::json!`] macro,\n/// allowing it to perform far fewer allocations\n/// than a dynamic macro like [`serde_json::json!`] would –\n/// it's equivalent to if you had just written\n/// `derive(Serialize)` on a struct.\n///\n/// # Examples\n///\n/// ```\n/// use axum::{\n///     Router,\n///     extract::Path,\n///     response::Response,\n///     routing::get,\n/// };\n/// use axum_extra::response::ErasedJson;\n///\n/// async fn get_user(Path(user_id) : Path<u64>) -> ErasedJson {\n///     let user_name = find_user_name(user_id).await;\n///     axum_extra::json!({ \"name\": user_name })\n/// }\n///\n/// async fn find_user_name(user_id: u64) -> String {\n///     // ...\n///     # unimplemented!()\n/// }\n///\n/// let app = Router::new().route(\"/users/{id}\", get(get_user));\n/// # let _: Router = app;\n/// ```\n///\n/// Trailing commas are allowed in both arrays and objects.\n///\n/// ```\n/// let response = axum_extra::json!([\"trailing\",]);\n/// ```\n#[cfg_attr(docsrs, doc(cfg(feature = \"erased-json\")))]\n#[macro_export]\nmacro_rules! json {\n    ($($t:tt)*) => {\n        $crate::response::ErasedJson::new(\n            $crate::response::__private_erased_json::typed_json::json!($($t)*)\n        )\n    }\n}\n\n/// Not public API. Re-exported as `crate::response::__private_erased_json`.\n#[doc(hidden)]\npub mod private {\n    pub use typed_json;\n}\n"
  },
  {
    "path": "axum-extra/src/response/error_response.rs",
    "content": "use axum_core::response::{IntoResponse, Response};\nuse http::StatusCode;\nuse std::error::Error;\nuse tracing::error;\n\n/// Convenience response to create an error response from a non-[`IntoResponse`] error\n///\n/// This provides a method to quickly respond with an error that does not implement\n/// the `IntoResponse` trait itself. Error details are logged using [`tracing::error!`]\n/// and a generic `500 Internal Server Error` response is returned to the client without\n/// exposing error details.\n///\n/// ```rust\n/// use axum_extra::response::InternalServerError;\n/// use axum_core::response::IntoResponse;\n/// # use std::io::{Error, ErrorKind};\n/// # fn try_thing() -> Result<(), Error> {\n/// #   Err(Error::new(ErrorKind::Other, \"error\"))\n/// # }\n///\n/// async fn maybe_error() -> Result<String, InternalServerError<Error>> {\n///     try_thing().map_err(InternalServerError)?;\n///     // do something on success\n///     # Ok(String::from(\"ok\"))\n/// }\n/// ```\n#[derive(Debug)]\npub struct InternalServerError<T>(pub T);\n\nimpl<T: Error + 'static> IntoResponse for InternalServerError<T> {\n    fn into_response(self) -> Response {\n        error!(error = &self.0 as &dyn Error);\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            \"An error occurred while processing your request.\",\n        )\n            .into_response()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use std::io::Error;\n\n    #[test]\n    fn internal_server_error() {\n        let response = InternalServerError(Error::other(\"Test\")).into_response();\n        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/response/file_stream.rs",
    "content": "use axum_core::{\n    body,\n    response::{IntoResponse, Response},\n    BoxError,\n};\nuse bytes::Bytes;\nuse futures_core::TryStream;\nuse http::{header, StatusCode};\nuse std::{io, path::Path};\nuse tokio::{\n    fs::File,\n    io::{AsyncReadExt, AsyncSeekExt},\n};\nuse tokio_util::io::ReaderStream;\n\n/// Encapsulate the file stream.\n///\n/// The encapsulated file stream construct requires passing in a stream.\n///\n/// # Examples\n///\n/// ```\n/// use axum::{\n///     http::StatusCode,\n///     response::{IntoResponse, Response},\n///     routing::get,\n///     Router,\n/// };\n/// use axum_extra::response::file_stream::FileStream;\n/// use tokio::fs::File;\n/// use tokio_util::io::ReaderStream;\n///\n/// async fn file_stream() -> Result<Response, (StatusCode, String)> {\n///     let file = File::open(\"test.txt\")\n///         .await\n///         .map_err(|e| (StatusCode::NOT_FOUND, format!(\"File not found: {e}\")))?;\n///\n///     let stream = ReaderStream::new(file);\n///     let file_stream_resp = FileStream::new(stream).file_name(\"test.txt\");\n///\n///     Ok(file_stream_resp.into_response())\n/// }\n///\n/// let app = Router::new().route(\"/file-stream\", get(file_stream));\n/// # let _: Router = app;\n/// ```\n#[must_use]\n#[derive(Debug)]\npub struct FileStream<S> {\n    /// stream.\n    pub stream: S,\n    /// The file name of the file.\n    pub file_name: Option<String>,\n    /// The size of the file.\n    pub content_size: Option<u64>,\n}\n\nimpl<S> FileStream<S>\nwhere\n    S: TryStream + Send + 'static,\n    S::Ok: Into<Bytes>,\n    S::Error: Into<BoxError>,\n{\n    /// Create a new [`FileStream`]\n    pub fn new(stream: S) -> Self {\n        Self {\n            stream,\n            file_name: None,\n            content_size: None,\n        }\n    }\n\n    /// Set the file name of the [`FileStream`].\n    ///\n    /// This adds the attachment `Content-Disposition` header with the given `file_name`.\n    pub fn file_name(mut self, file_name: impl Into<String>) -> Self {\n        self.file_name = Some(file_name.into());\n        self\n    }\n\n    /// Set the size of the file.\n    pub fn content_size(mut self, len: u64) -> Self {\n        self.content_size = Some(len);\n        self\n    }\n\n    /// Return a range response.\n    ///\n    /// range: (start, end, total_size)\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use axum::{\n    ///     http::StatusCode,\n    ///     response::IntoResponse,\n    ///     routing::get,\n    ///     Router,\n    /// };\n    /// use axum_extra::response::file_stream::FileStream;\n    /// use tokio::fs::File;\n    /// use tokio::io::AsyncSeekExt;\n    /// use tokio_util::io::ReaderStream;\n    ///\n    /// async fn range_response() -> Result<impl IntoResponse, (StatusCode, String)> {\n    ///     let mut file = File::open(\"test.txt\")\n    ///         .await\n    ///         .map_err(|e| (StatusCode::NOT_FOUND, format!(\"File not found: {e}\")))?;\n    ///     let mut file_size = file\n    ///         .metadata()\n    ///         .await\n    ///         .map_err(|e| (StatusCode::NOT_FOUND, format!(\"Get file size: {e}\")))?\n    ///         .len();\n    ///\n    ///     file.seek(std::io::SeekFrom::Start(10))\n    ///         .await\n    ///         .map_err(|e| (StatusCode::NOT_FOUND, format!(\"File seek error: {e}\")))?;\n    ///     let stream = ReaderStream::new(file);\n    ///\n    ///     Ok(FileStream::new(stream).into_range_response(10, file_size - 1, file_size))\n    /// }\n    ///\n    /// let app = Router::new().route(\"/file-stream\", get(range_response));\n    /// # let _: Router = app;\n    /// ```\n    pub fn into_range_response(self, start: u64, end: u64, total_size: u64) -> Response {\n        let mut resp = Response::builder().header(header::CONTENT_TYPE, \"application/octet-stream\");\n        resp = resp.status(StatusCode::PARTIAL_CONTENT);\n\n        resp = resp.header(\n            header::CONTENT_RANGE,\n            format!(\"bytes {start}-{end}/{total_size}\"),\n        );\n\n        resp.body(body::Body::from_stream(self.stream))\n            .unwrap_or_else(|e| {\n                (\n                    StatusCode::INTERNAL_SERVER_ERROR,\n                    format!(\"build FileStream response error: {e}\"),\n                )\n                    .into_response()\n            })\n    }\n\n    /// Attempts to return RANGE requests directly from the file path.\n    ///\n    /// # Arguments\n    ///\n    /// * `file_path` - The path of the file to be streamed\n    /// * `start` - The start position of the range\n    /// * `end` - The end position of the range\n    ///\n    /// # Note\n    ///\n    /// * If `end` is 0, then it is used as `file_size - 1`\n    /// * If `start` > `file_size` or `start` > `end`, then `Range Not Satisfiable` is returned\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use axum::{\n    ///     http::StatusCode,\n    ///     response::IntoResponse,\n    ///     Router,\n    ///     routing::get\n    /// };\n    /// use std::path::Path;\n    /// use axum_extra::response::file_stream::FileStream;\n    /// use tokio::fs::File;\n    /// use tokio_util::io::ReaderStream;\n    /// use tokio::io::AsyncSeekExt;\n    ///\n    /// async fn range_stream() -> impl IntoResponse {\n    ///     let range_start = 0;\n    ///     let range_end = 1024;\n    ///\n    ///     FileStream::<ReaderStream<File>>::try_range_response(\"CHANGELOG.md\", range_start, range_end).await\n    ///         .map_err(|e| (StatusCode::NOT_FOUND, format!(\"File not found: {e}\")))\n    /// }\n    ///\n    /// let app = Router::new().route(\"/file-stream\", get(range_stream));\n    /// # let _: Router = app;\n    /// ```\n    pub async fn try_range_response(\n        file_path: impl AsRef<Path>,\n        start: u64,\n        mut end: u64,\n    ) -> io::Result<Response> {\n        let mut file = File::open(file_path).await?;\n\n        let metadata = file.metadata().await?;\n        let total_size = metadata.len();\n\n        if total_size == 0 {\n            return Ok((StatusCode::RANGE_NOT_SATISFIABLE, \"Range Not Satisfiable\").into_response());\n        }\n\n        if end == 0 {\n            end = total_size - 1;\n        }\n\n        if start > total_size {\n            return Ok((StatusCode::RANGE_NOT_SATISFIABLE, \"Range Not Satisfiable\").into_response());\n        }\n        if start > end {\n            return Ok((StatusCode::RANGE_NOT_SATISFIABLE, \"Range Not Satisfiable\").into_response());\n        }\n        if end >= total_size {\n            return Ok((StatusCode::RANGE_NOT_SATISFIABLE, \"Range Not Satisfiable\").into_response());\n        }\n\n        file.seek(std::io::SeekFrom::Start(start)).await?;\n\n        let stream = ReaderStream::new(file.take(end - start + 1));\n\n        Ok(FileStream::new(stream).into_range_response(start, end, total_size))\n    }\n}\n\n// Split because the general impl requires to specify `S` and this one does not.\nimpl FileStream<ReaderStream<File>> {\n    /// Create a [`FileStream`] from a file path.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use axum::{\n    ///     http::StatusCode,\n    ///     response::IntoResponse,\n    ///     Router,\n    ///     routing::get\n    /// };\n    /// use axum_extra::response::file_stream::FileStream;\n    ///\n    /// async fn file_stream() -> impl IntoResponse {\n    ///     FileStream::from_path(\"test.txt\")\n    ///         .await\n    ///         .map_err(|e| (StatusCode::NOT_FOUND, format!(\"File not found: {e}\")))\n    /// }\n    ///\n    /// let app = Router::new().route(\"/file-stream\", get(file_stream));\n    /// # let _: Router = app;\n    /// ```\n    pub async fn from_path(path: impl AsRef<Path>) -> io::Result<Self> {\n        let file = File::open(&path).await?;\n        let mut content_size = None;\n        let mut file_name = None;\n\n        if let Ok(metadata) = file.metadata().await {\n            content_size = Some(metadata.len());\n        }\n\n        if let Some(file_name_os) = path.as_ref().file_name() {\n            if let Some(file_name_str) = file_name_os.to_str() {\n                file_name = Some(file_name_str.to_owned());\n            }\n        }\n\n        Ok(Self {\n            stream: ReaderStream::new(file),\n            file_name,\n            content_size,\n        })\n    }\n}\n\nimpl<S> IntoResponse for FileStream<S>\nwhere\n    S: TryStream + Send + 'static,\n    S::Ok: Into<Bytes>,\n    S::Error: Into<BoxError>,\n{\n    fn into_response(self) -> Response {\n        let mut resp = Response::builder().header(header::CONTENT_TYPE, \"application/octet-stream\");\n\n        if let Some(file_name) = self.file_name {\n            resp = resp.header(\n                header::CONTENT_DISPOSITION,\n                format!(\n                    \"attachment; filename=\\\"{}\\\"\",\n                    super::content_disposition::EscapedFilename(&file_name)\n                ),\n            );\n        }\n\n        if let Some(content_size) = self.content_size {\n            resp = resp.header(header::CONTENT_LENGTH, content_size);\n        }\n\n        resp.body(body::Body::from_stream(self.stream))\n            .unwrap_or_else(|e| {\n                (\n                    StatusCode::INTERNAL_SERVER_ERROR,\n                    format!(\"build FileStream response error: {e}\"),\n                )\n                    .into_response()\n            })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{extract::Request, routing::get, Router};\n    use body::Body;\n    use http::HeaderMap;\n    use http_body_util::BodyExt;\n    use std::io::Cursor;\n    use tokio_util::io::ReaderStream;\n    use tower::ServiceExt;\n\n    #[tokio::test]\n    async fn response() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\n            \"/file\",\n            get(|| async {\n                // Simulating a file stream\n                let file_content = b\"Hello, this is the simulated file content!\".to_vec();\n                let reader = Cursor::new(file_content);\n\n                // Response file stream\n                // Content size and file name are not attached by default\n                let stream = ReaderStream::new(reader);\n                FileStream::new(stream).into_response()\n            }),\n        );\n\n        // Simulating a GET request\n        let response = app\n            .oneshot(Request::builder().uri(\"/file\").body(Body::empty())?)\n            .await?;\n\n        // Validate Response Status Code\n        assert_eq!(response.status(), StatusCode::OK);\n\n        // Validate Response Headers\n        assert_eq!(\n            response.headers().get(\"content-type\").unwrap(),\n            \"application/octet-stream\"\n        );\n\n        // Validate Response Body\n        let body: &[u8] = &response.into_body().collect().await?.to_bytes();\n        assert_eq!(\n            std::str::from_utf8(body)?,\n            \"Hello, this is the simulated file content!\"\n        );\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn response_not_set_filename() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\n            \"/file\",\n            get(|| async {\n                // Simulating a file stream\n                let file_content = b\"Hello, this is the simulated file content!\".to_vec();\n                let size = file_content.len() as u64;\n                let reader = Cursor::new(file_content);\n\n                // Response file stream\n                let stream = ReaderStream::new(reader);\n                FileStream::new(stream).content_size(size).into_response()\n            }),\n        );\n\n        // Simulating a GET request\n        let response = app\n            .oneshot(Request::builder().uri(\"/file\").body(Body::empty())?)\n            .await?;\n\n        // Validate Response Status Code\n        assert_eq!(response.status(), StatusCode::OK);\n\n        // Validate Response Headers\n        assert_eq!(\n            response.headers().get(\"content-type\").unwrap(),\n            \"application/octet-stream\"\n        );\n        assert_eq!(response.headers().get(\"content-length\").unwrap(), \"42\");\n\n        // Validate Response Body\n        let body: &[u8] = &response.into_body().collect().await?.to_bytes();\n        assert_eq!(\n            std::str::from_utf8(body)?,\n            \"Hello, this is the simulated file content!\"\n        );\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn response_not_set_content_size() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\n            \"/file\",\n            get(|| async {\n                // Simulating a file stream\n                let file_content = b\"Hello, this is the simulated file content!\".to_vec();\n                let reader = Cursor::new(file_content);\n\n                // Response file stream\n                let stream = ReaderStream::new(reader);\n                FileStream::new(stream).file_name(\"test\").into_response()\n            }),\n        );\n\n        // Simulating a GET request\n        let response = app\n            .oneshot(Request::builder().uri(\"/file\").body(Body::empty())?)\n            .await?;\n\n        // Validate Response Status Code\n        assert_eq!(response.status(), StatusCode::OK);\n\n        // Validate Response Headers\n        assert_eq!(\n            response.headers().get(\"content-type\").unwrap(),\n            \"application/octet-stream\"\n        );\n        assert_eq!(\n            response.headers().get(\"content-disposition\").unwrap(),\n            \"attachment; filename=\\\"test\\\"\"\n        );\n\n        // Validate Response Body\n        let body: &[u8] = &response.into_body().collect().await?.to_bytes();\n        assert_eq!(\n            std::str::from_utf8(body)?,\n            \"Hello, this is the simulated file content!\"\n        );\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn response_with_content_size_and_filename() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\n            \"/file\",\n            get(|| async {\n                // Simulating a file stream\n                let file_content = b\"Hello, this is the simulated file content!\".to_vec();\n                let size = file_content.len() as u64;\n                let reader = Cursor::new(file_content);\n\n                // Response file stream\n                let stream = ReaderStream::new(reader);\n                FileStream::new(stream)\n                    .file_name(\"test\")\n                    .content_size(size)\n                    .into_response()\n            }),\n        );\n\n        // Simulating a GET request\n        let response = app\n            .oneshot(Request::builder().uri(\"/file\").body(Body::empty())?)\n            .await?;\n\n        // Validate Response Status Code\n        assert_eq!(response.status(), StatusCode::OK);\n\n        // Validate Response Headers\n        assert_eq!(\n            response.headers().get(\"content-type\").unwrap(),\n            \"application/octet-stream\"\n        );\n        assert_eq!(\n            response.headers().get(\"content-disposition\").unwrap(),\n            \"attachment; filename=\\\"test\\\"\"\n        );\n        assert_eq!(response.headers().get(\"content-length\").unwrap(), \"42\");\n\n        // Validate Response Body\n        let body: &[u8] = &response.into_body().collect().await?.to_bytes();\n        assert_eq!(\n            std::str::from_utf8(body)?,\n            \"Hello, this is the simulated file content!\"\n        );\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn response_from_path() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\n            \"/from_path\",\n            get(move || async move {\n                FileStream::from_path(Path::new(\"CHANGELOG.md\"))\n                    .await\n                    .unwrap()\n                    .into_response()\n            }),\n        );\n\n        // Simulating a GET request\n        let response = app\n            .oneshot(\n                Request::builder()\n                    .uri(\"/from_path\")\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        // Validate Response Status Code\n        assert_eq!(response.status(), StatusCode::OK);\n\n        // Validate Response Headers\n        assert_eq!(\n            response.headers().get(\"content-type\").unwrap(),\n            \"application/octet-stream\"\n        );\n        assert_eq!(\n            response.headers().get(\"content-disposition\").unwrap(),\n            \"attachment; filename=\\\"CHANGELOG.md\\\"\"\n        );\n\n        let file = File::open(\"CHANGELOG.md\").await.unwrap();\n        // get file size\n        let content_length = file.metadata().await.unwrap().len();\n\n        assert_eq!(\n            response\n                .headers()\n                .get(\"content-length\")\n                .unwrap()\n                .to_str()\n                .unwrap(),\n            content_length.to_string()\n        );\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn response_range_file() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\"/range_response\", get(range_stream));\n\n        // Simulating a GET request\n        let response = app\n            .oneshot(\n                Request::builder()\n                    .uri(\"/range_response\")\n                    .header(header::RANGE, \"bytes=20-1000\")\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        // Validate Response Status Code\n        assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT);\n\n        // Validate Response Headers\n        assert_eq!(\n            response.headers().get(\"content-type\").unwrap(),\n            \"application/octet-stream\"\n        );\n\n        let file = File::open(\"CHANGELOG.md\").await.unwrap();\n        // get file size\n        let content_length = file.metadata().await.unwrap().len();\n\n        assert_eq!(\n            response\n                .headers()\n                .get(\"content-range\")\n                .unwrap()\n                .to_str()\n                .unwrap(),\n            format!(\"bytes 20-1000/{content_length}\")\n        );\n        Ok(())\n    }\n\n    async fn range_stream(headers: HeaderMap) -> Response {\n        let range_header = headers\n            .get(header::RANGE)\n            .and_then(|value| value.to_str().ok());\n\n        let (start, end) = if let Some(range) = range_header {\n            if let Some(range) = parse_range_header(range) {\n                range\n            } else {\n                return (StatusCode::RANGE_NOT_SATISFIABLE, \"Invalid Range\").into_response();\n            }\n        } else {\n            (0, 0) // default range end = 0, if end = 0 end == file size - 1\n        };\n\n        FileStream::<ReaderStream<File>>::try_range_response(Path::new(\"CHANGELOG.md\"), start, end)\n            .await\n            .unwrap()\n    }\n\n    fn parse_range_header(range: &str) -> Option<(u64, u64)> {\n        let range = range.strip_prefix(\"bytes=\")?;\n        let mut parts = range.split('-');\n        let start = parts.next()?.parse::<u64>().ok()?;\n        let end = parts\n            .next()\n            .and_then(|s| s.parse::<u64>().ok())\n            .unwrap_or(0);\n        if start > end {\n            return None;\n        }\n        Some((start, end))\n    }\n\n    #[tokio::test]\n    async fn filename_escapes_quotes() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\n            \"/file\",\n            get(|| async {\n                let file_content = b\"data\".to_vec();\n                let reader = Cursor::new(file_content);\n                let stream = ReaderStream::new(reader);\n                // Filename containing double quotes that could cause parameter injection\n                FileStream::new(stream)\n                    .file_name(\"evil\\\"; filename*=UTF-8''pwned.txt; x=\\\"\")\n                    .into_response()\n            }),\n        );\n\n        let response = app\n            .oneshot(Request::builder().uri(\"/file\").body(Body::empty())?)\n            .await?;\n\n        assert_eq!(response.status(), StatusCode::OK);\n        assert_eq!(\n            response.headers().get(\"content-disposition\").unwrap(),\n            \"attachment; filename=\\\"evil\\\\\\\"; filename*=UTF-8''pwned.txt; x=\\\\\\\"\\\"\"\n        );\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn filename_escapes_backslashes() -> Result<(), Box<dyn std::error::Error>> {\n        let app = Router::new().route(\n            \"/file\",\n            get(|| async {\n                let file_content = b\"data\".to_vec();\n                let reader = Cursor::new(file_content);\n                let stream = ReaderStream::new(reader);\n                FileStream::new(stream)\n                    .file_name(\"file\\\\name.txt\")\n                    .into_response()\n            }),\n        );\n\n        let response = app\n            .oneshot(Request::builder().uri(\"/file\").body(Body::empty())?)\n            .await?;\n\n        assert_eq!(response.status(), StatusCode::OK);\n        assert_eq!(\n            response.headers().get(\"content-disposition\").unwrap(),\n            \"attachment; filename=\\\"file\\\\\\\\name.txt\\\"\"\n        );\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn response_range_empty_file() -> Result<(), Box<dyn std::error::Error>> {\n        let file = tempfile::NamedTempFile::new()?;\n        file.as_file().set_len(0)?;\n        let path = file.path().to_owned();\n\n        let app = Router::new().route(\n            \"/range_empty\",\n            get(move |headers: HeaderMap| {\n                let path = path.clone();\n                async move {\n                    let range_header = headers\n                        .get(header::RANGE)\n                        .and_then(|value| value.to_str().ok());\n\n                    let (start, end) = if let Some(range) = range_header {\n                        if let Some(range) = parse_range_header(range) {\n                            range\n                        } else {\n                            return (StatusCode::RANGE_NOT_SATISFIABLE, \"Invalid Range\")\n                                .into_response();\n                        }\n                    } else {\n                        (0, 0)\n                    };\n\n                    FileStream::<ReaderStream<File>>::try_range_response(path, start, end)\n                        .await\n                        .unwrap_or_else(|_| StatusCode::INTERNAL_SERVER_ERROR.into_response())\n                }\n            }),\n        );\n\n        let response = app\n            .oneshot(\n                Request::builder()\n                    .uri(\"/range_empty\")\n                    .header(header::RANGE, \"bytes=0-\")\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/response/mod.rs",
    "content": "//! Additional types for generating responses.\n\n#[cfg(any(feature = \"attachment\", feature = \"file-stream\"))]\nmod content_disposition;\n\n#[cfg(feature = \"erased-json\")]\nmod erased_json;\n\n#[cfg(feature = \"attachment\")]\nmod attachment;\n\n#[cfg(feature = \"multipart\")]\npub mod multiple;\n\n#[cfg(feature = \"error-response\")]\nmod error_response;\n\n#[cfg(feature = \"file-stream\")]\n/// Module for handling file streams.\npub mod file_stream;\n\n#[cfg(feature = \"file-stream\")]\npub use file_stream::FileStream;\n\n#[cfg(feature = \"error-response\")]\npub use error_response::InternalServerError;\n\n#[cfg(feature = \"erased-json\")]\npub use erased_json::ErasedJson;\n\n/// _not_ public API\n#[cfg(feature = \"erased-json\")]\n#[doc(hidden)]\npub use erased_json::private as __private_erased_json;\n\n#[cfg(feature = \"json-lines\")]\n#[doc(no_inline)]\npub use crate::json_lines::JsonLines;\n\n#[cfg(feature = \"attachment\")]\npub use attachment::Attachment;\n\nmacro_rules! mime_response {\n    (\n        $(#[$m:meta])*\n        $ident:ident,\n        $mime:ident,\n    ) => {\n        mime_response! {\n            $(#[$m])*\n            $ident,\n            mime::$mime.as_ref(),\n        }\n    };\n\n    (\n        $(#[$m:meta])*\n        $ident:ident,\n        $mime:expr,\n    ) => {\n        $(#[$m])*\n        #[derive(Clone, Copy, Debug)]\n        #[must_use]\n        pub struct $ident<T>(pub T);\n\n        impl<T> axum_core::response::IntoResponse for $ident<T>\n        where\n            T: axum_core::response::IntoResponse,\n        {\n            fn into_response(self) -> axum_core::response::Response {\n                (\n                    [(\n                        http::header::CONTENT_TYPE,\n                        http::HeaderValue::from_static($mime),\n                    )],\n                    self.0,\n                )\n                    .into_response()\n            }\n        }\n\n        impl<T> From<T> for $ident<T> {\n            fn from(inner: T) -> Self {\n                Self(inner)\n            }\n        }\n    };\n}\n\nmime_response! {\n    /// A JavaScript response.\n    ///\n    /// Will automatically get `Content-Type: application/javascript; charset=utf-8`.\n    JavaScript,\n    APPLICATION_JAVASCRIPT_UTF_8,\n}\n\nmime_response! {\n    /// A CSS response.\n    ///\n    /// Will automatically get `Content-Type: text/css; charset=utf-8`.\n    Css,\n    TEXT_CSS_UTF_8,\n}\n\nmime_response! {\n    /// A WASM response.\n    ///\n    /// Will automatically get `Content-Type: application/wasm`.\n    Wasm,\n    \"application/wasm\",\n}\n\n#[cfg(feature = \"typed-header\")]\n#[doc(no_inline)]\npub use crate::typed_header::TypedHeader;\n"
  },
  {
    "path": "axum-extra/src/response/multiple.rs",
    "content": "//! Generate forms to use in responses.\n\nuse axum_core::response::{IntoResponse, Response};\nuse fastrand;\nuse http::{header, HeaderMap, StatusCode};\nuse mime::Mime;\n\n/// Create multipart forms to be used in API responses.\n///\n/// This struct implements [`IntoResponse`], and so it can be returned from a handler.\n#[must_use]\n#[derive(Debug)]\npub struct MultipartForm {\n    parts: Vec<Part>,\n}\n\nimpl MultipartForm {\n    /// Initialize a new multipart form with the provided vector of parts.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use axum_extra::response::multiple::{MultipartForm, Part};\n    ///\n    /// let parts: Vec<Part> = vec![Part::text(\"foo\".to_string(), \"abc\"), Part::text(\"bar\".to_string(), \"def\")];\n    /// let form = MultipartForm::with_parts(parts);\n    /// ```\n    pub fn with_parts(parts: Vec<Part>) -> Self {\n        Self { parts }\n    }\n}\n\nimpl IntoResponse for MultipartForm {\n    fn into_response(self) -> Response {\n        // see RFC5758 for details\n        let boundary = generate_boundary();\n        let mut headers = HeaderMap::new();\n        let mime_type: Mime = match format!(\"multipart/form-data; boundary={boundary}\").parse() {\n            Ok(m) => m,\n            // Realistically this should never happen unless the boundary generation code\n            // is modified, and that will be caught by unit tests\n            Err(_) => {\n                return (\n                    StatusCode::INTERNAL_SERVER_ERROR,\n                    \"Invalid multipart boundary generated\",\n                )\n                    .into_response()\n            }\n        };\n        // The use of unwrap is safe here because mime types are inherently string representable\n        headers.insert(header::CONTENT_TYPE, mime_type.to_string().parse().unwrap());\n        let mut serialized_form: Vec<u8> = Vec::new();\n        for part in self.parts {\n            // for each part, the boundary is preceded by two dashes\n            serialized_form.extend_from_slice(format!(\"--{boundary}\\r\\n\").as_bytes());\n            serialized_form.extend_from_slice(&part.serialize());\n        }\n        serialized_form.extend_from_slice(format!(\"--{boundary}--\").as_bytes());\n        (headers, serialized_form).into_response()\n    }\n}\n\n// Valid settings for that header are: \"base64\", \"quoted-printable\", \"8bit\", \"7bit\", and \"binary\".\n/// A single part of a multipart form as defined by\n/// <https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4>\n/// and RFC5758.\n#[derive(Debug)]\npub struct Part {\n    // Every part is expected to contain:\n    // - a [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition\n    // header, where `Content-Disposition` is set to `form-data`, with a parameter of `name` that is set to\n    // the name of the field in the form. In the below example, the name of the field is `user`:\n    // ```\n    // Content-Disposition: form-data; name=\"user\"\n    // ```\n    // If the field contains a file, then the `filename` parameter may be set to the name of the file.\n    // Handling for non-ascii field names is not done here, support for non-ascii characters may be encoded using\n    // methodology described in RFC 2047.\n    // - (optionally) a `Content-Type` header, which if not set, defaults to `text/plain`.\n    // If the field contains a file, then the file should be identified with that file's MIME type (eg: `image/gif`).\n    // If the `MIME` type is not known or specified, then the MIME type should be set to `application/octet-stream`.\n    /// The name of the part in question\n    name: String,\n    /// If the part should be treated as a file, the filename that should be attached that part\n    filename: Option<String>,\n    /// The `Content-Type` header. While not strictly required, it is always set here\n    mime_type: Mime,\n    /// The content/body of the part\n    contents: Vec<u8>,\n}\n\nimpl Part {\n    /// Create a new part with `Content-Type` of `text/plain` with the supplied name and contents.\n    ///\n    /// This form will not have a defined file name.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use axum_extra::response::multiple::{MultipartForm, Part};\n    ///\n    /// // create a form with a single part that has a field with a name of \"foo\",\n    /// // and a value of \"abc\"\n    /// let parts: Vec<Part> = vec![Part::text(\"foo\".to_string(), \"abc\")];\n    /// let form = MultipartForm::from_iter(parts);\n    /// ```\n    #[must_use]\n    pub fn text(name: String, contents: &str) -> Self {\n        Self {\n            name,\n            filename: None,\n            mime_type: mime::TEXT_PLAIN_UTF_8,\n            contents: contents.as_bytes().to_vec(),\n        }\n    }\n\n    /// Create a new part containing a generic file, with a `Content-Type` of `application/octet-stream`\n    /// using the provided file name, field name, and contents.\n    ///\n    /// If the MIME type of the file is known, consider using `Part::raw_part`.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use axum_extra::response::multiple::{MultipartForm, Part};\n    ///\n    /// // create a form with a single part that has a field with a name of \"foo\",\n    /// // with a file name of \"foo.txt\", and with the specified contents\n    /// let parts: Vec<Part> = vec![Part::file(\"foo\", \"foo.txt\", vec![0x68, 0x68, 0x20, 0x6d, 0x6f, 0x6d])];\n    /// let form = MultipartForm::from_iter(parts);\n    /// ```\n    #[must_use]\n    pub fn file(field_name: &str, file_name: &str, contents: Vec<u8>) -> Self {\n        Self {\n            name: field_name.to_owned(),\n            filename: Some(file_name.to_owned()),\n            // If the `MIME` type is not known or specified, then the MIME type should be set to `application/octet-stream`.\n            // See RFC2388 section 3 for specifics.\n            mime_type: mime::APPLICATION_OCTET_STREAM,\n            contents,\n        }\n    }\n\n    /// Create a new part with more fine-grained control over the semantics of that part.\n    ///\n    /// The caller is assumed to have set a valid MIME type.\n    ///\n    /// This function will return an error if the provided MIME type is not valid.\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// use axum_extra::response::multiple::{MultipartForm, Part};\n    ///\n    /// // create a form with a single part that has a field with a name of \"part_name\",\n    /// // with a MIME type of \"application/json\", and the supplied contents.\n    /// let parts: Vec<Part> = vec![Part::raw_part(\"part_name\", \"application/json\", vec![0x68, 0x68, 0x20, 0x6d, 0x6f, 0x6d], None).expect(\"MIME type must be valid\")];\n    /// let form = MultipartForm::from_iter(parts);\n    /// ```\n    pub fn raw_part(\n        name: &str,\n        mime_type: &str,\n        contents: Vec<u8>,\n        filename: Option<&str>,\n    ) -> Result<Self, &'static str> {\n        let mime_type = mime_type.parse().map_err(|_| \"Invalid MIME type\")?;\n        Ok(Self {\n            name: name.to_owned(),\n            filename: filename.map(|f| f.to_owned()),\n            mime_type,\n            contents,\n        })\n    }\n\n    /// Serialize this part into a chunk that can be easily inserted into a larger form\n    pub(super) fn serialize(&self) -> Vec<u8> {\n        // A part is serialized in this general format:\n        // // the filename is optional\n        // Content-Disposition: form-data; name=\"FIELD_NAME\"; filename=\"FILENAME\"\\r\\n\n        // // the mime type (not strictly required by the spec, but always sent here)\n        // Content-Type: mime/type\\r\\n\n        // // a blank line, then the contents of the file start\n        // \\r\\n\n        // CONTENTS\\r\\n\n\n        // Format what we can as a string, then handle the rest at a byte level\n        let mut serialized_part = format!(\"Content-Disposition: form-data; name=\\\"{}\\\"\", self.name);\n        // specify a filename if one was set\n        if let Some(filename) = &self.filename {\n            serialized_part += &format!(\"; filename=\\\"{filename}\\\"\");\n        }\n        serialized_part += \"\\r\\n\";\n        // specify the MIME type\n        serialized_part += &format!(\"Content-Type: {}\\r\\n\", self.mime_type);\n        serialized_part += \"\\r\\n\";\n        let mut part_bytes = serialized_part.as_bytes().to_vec();\n        part_bytes.extend_from_slice(&self.contents);\n        part_bytes.extend_from_slice(b\"\\r\\n\");\n\n        part_bytes\n    }\n}\n\nimpl FromIterator<Part> for MultipartForm {\n    fn from_iter<T: IntoIterator<Item = Part>>(iter: T) -> Self {\n        Self {\n            parts: iter.into_iter().collect(),\n        }\n    }\n}\n\n/// A boundary is defined as a user defined (arbitrary) value that does not occur in any of the data.\n///\n/// Because the specification does not clearly define a methodology for generating boundaries, this implementation\n/// follow's Reqwest's, and generates a boundary in the format of `XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX` where `XXXXXXXX`\n/// is a hexadecimal representation of a pseudo randomly generated u64.\nfn generate_boundary() -> String {\n    let a = fastrand::u64(0..u64::MAX);\n    let b = fastrand::u64(0..u64::MAX);\n    let c = fastrand::u64(0..u64::MAX);\n    let d = fastrand::u64(0..u64::MAX);\n    format!(\"{a:016x}-{b:016x}-{c:016x}-{d:016x}\")\n}\n\n#[cfg(test)]\nmod tests {\n    use super::{generate_boundary, MultipartForm, Part};\n    use axum::{body::Body, http};\n    use axum::{routing::get, Router};\n    use http::{Request, Response};\n    use http_body_util::BodyExt;\n    use mime::Mime;\n    use tower::ServiceExt;\n\n    #[tokio::test]\n    async fn process_form() -> Result<(), Box<dyn std::error::Error>> {\n        // create a boilerplate handle that returns a form\n        async fn handle() -> MultipartForm {\n            let parts: Vec<Part> = vec![\n                Part::text(\"part1\".to_owned(), \"basictext\"),\n                Part::file(\n                    \"part2\",\n                    \"file.txt\",\n                    vec![0x68, 0x69, 0x20, 0x6d, 0x6f, 0x6d],\n                ),\n                Part::raw_part(\"part3\", \"text/plain\", b\"rawpart\".to_vec(), None).unwrap(),\n            ];\n            MultipartForm::from_iter(parts)\n        }\n\n        // make a request to that handle\n        let app = Router::new().route(\"/\", get(handle));\n        let response: Response<_> = app\n            .oneshot(Request::builder().uri(\"/\").body(Body::empty())?)\n            .await?;\n        // content_type header\n        let ct_header = response.headers().get(\"content-type\").unwrap().to_str()?;\n        let boundary = ct_header.split(\"boundary=\").nth(1).unwrap().to_owned();\n        let body: &[u8] = &response.into_body().collect().await?.to_bytes();\n        assert_eq!(\n            std::str::from_utf8(body)?,\n            format!(\n                \"--{boundary}\\r\\n\\\n                Content-Disposition: form-data; name=\\\"part1\\\"\\r\\n\\\n                Content-Type: text/plain; charset=utf-8\\r\\n\\\n                \\r\\n\\\n                basictext\\r\\n\\\n                --{boundary}\\r\\n\\\n                Content-Disposition: form-data; name=\\\"part2\\\"; filename=\\\"file.txt\\\"\\r\\n\\\n                Content-Type: application/octet-stream\\r\\n\\\n                \\r\\n\\\n                hi mom\\r\\n\\\n                --{boundary}\\r\\n\\\n                Content-Disposition: form-data; name=\\\"part3\\\"\\r\\n\\\n                Content-Type: text/plain\\r\\n\\\n                \\r\\n\\\n                rawpart\\r\\n\\\n                --{boundary}--\",\n            )\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn valid_boundary_generation() {\n        for _ in 0..256 {\n            let boundary = generate_boundary();\n            let mime_type: Result<Mime, _> =\n                format!(\"multipart/form-data; boundary={boundary}\").parse();\n            assert!(\n                mime_type.is_ok(),\n                \"The generated boundary was unable to be parsed into a valid mime type.\"\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/routing/mod.rs",
    "content": "//! Additional types for defining routes.\n\nuse axum::{\n    extract::{OriginalUri, Request},\n    response::{IntoResponse, Redirect, Response},\n    routing::{any, on, MethodFilter, MethodRouter},\n    Router,\n};\nuse http::{uri::PathAndQuery, StatusCode, Uri};\nuse std::{borrow::Cow, convert::Infallible};\nuse tower_service::Service;\n\nmod resource;\n\n#[cfg(feature = \"typed-routing\")]\nmod typed;\n\npub use self::resource::Resource;\n\n#[cfg(feature = \"typed-routing\")]\npub use self::typed::WithQueryParams;\n#[cfg(feature = \"typed-routing\")]\npub use axum_macros::TypedPath;\n\n#[cfg(feature = \"typed-routing\")]\npub use self::typed::{SecondElementIs, TypedPath};\n\n// Validates a path at compile time, used with the vpath macro.\n#[rustversion::since(1.80)]\n#[doc(hidden)]\n#[must_use]\npub const fn __private_validate_static_path(path: &'static str) -> &'static str {\n    if path.is_empty() {\n        panic!(\"Paths must start with a `/`. Use \\\"/\\\" for root routes\")\n    }\n    if path.as_bytes()[0] != b'/' {\n        panic!(\"Paths must start with /\");\n    }\n\n    // Checks if we have a path in 107 format.\n    let size: usize = path.len() - 1;\n    let mut curr: usize = 0;\n    let bytes = path.as_bytes();\n    while curr < size {\n        if bytes[curr] == b'/' && (bytes[curr + 1] == b'*' || bytes[curr + 1] == b':') {\n            panic!(\n                \"You have a path with a deprecated format, move your ':var' or '*var' to '{{var}}'\"\n            );\n        }\n        curr += 1;\n    }\n\n    path\n}\n\n/// This macro aborts compilation if the path is invalid.\n///\n/// This example will fail to compile:\n///\n/// ```compile_fail\n/// use axum::routing::{Router, get};\n/// use axum_extra::vpath;\n///\n/// let router = axum::Router::<()>::new()\n///     .route(vpath!(\"invalid_path\"), get(root))\n///     .to_owned();\n///\n/// async fn root() {}\n/// ```\n///\n/// This one will compile without problems:\n///\n/// ```no_run\n/// use axum::routing::{Router, get};\n/// use axum_extra::vpath;\n///\n/// let router = axum::Router::<()>::new()\n///     .route(vpath!(\"/valid_path/{id}\"), get(root))\n///     .to_owned();\n///\n/// async fn root() {}\n/// ```\n///\n/// It also checks for deprecated usage of variables within the path:\n///\n/// ```compile_fail\n///  use axum::routing::{Router, get};\n///  use axum_extra::vpath;\n///\n/// let router = axum::Router::<()>::new()\n///     .route(vpath!(\"/users/:id\"), get(root))\n///     .to_owned();\n///\n/// async fn root() {}\n/// ```\n///\n/// ```compile_fail\n///  use axum::routing::{Router, get};\n///  use axum_extra::vpath;\n///\n/// let router = axum::Router::<()>::new()\n///     .route(vpath!(\"/users/*id\"), get(root))\n///     .to_owned();\n///\n/// async fn root() {}\n/// ```\n/// This macro is available only on rust versions 1.80 and above.\n#[cfg_attr(docsrs, doc(cfg(feature = \"routing\")))]\n#[rustversion::since(1.80)]\n#[macro_export]\nmacro_rules! vpath {\n    ($e:expr) => {\n        const { $crate::routing::__private_validate_static_path($e) }\n    };\n}\n\n/// Extension trait that adds additional methods to [`Router`].\n#[allow(clippy::return_self_not_must_use)]\npub trait RouterExt<S>: sealed::Sealed {\n    /// Add a typed `GET` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_get<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `DELETE` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_delete<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `HEAD` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_head<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `OPTIONS` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_options<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `PATCH` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_patch<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `POST` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_post<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `PUT` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_put<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `TRACE` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_trace<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add a typed `CONNECT` route to the router.\n    ///\n    /// The path will be inferred from the first argument to the handler function which must\n    /// implement [`TypedPath`].\n    ///\n    /// See [`TypedPath`] for more details and examples.\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_connect<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath;\n\n    /// Add another route to the router with an additional \"trailing slash redirect\" route.\n    ///\n    /// If you add a route _without_ a trailing slash, such as `/foo`, this method will also add a\n    /// route for `/foo/` that redirects to `/foo`.\n    ///\n    /// If you add a route _with_ a trailing slash, such as `/bar/`, this method will also add a\n    /// route for `/bar` that redirects to `/bar/`.\n    ///\n    /// This is similar to what axum 0.5.x did by default, except this explicitly adds another\n    /// route, so trying to add a `/foo/` route after calling `.route_with_tsr(\"/foo\", /* ... */)`\n    /// will result in a panic due to route overlap.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum::{Router, routing::get};\n    /// use axum_extra::routing::RouterExt;\n    ///\n    /// let app = Router::new()\n    ///     // `/foo/` will redirect to `/foo`\n    ///     .route_with_tsr(\"/foo\", get(|| async {}))\n    ///     // `/bar` will redirect to `/bar/`\n    ///     .route_with_tsr(\"/bar/\", get(|| async {}));\n    /// # let _: Router = app;\n    /// ```\n    fn route_with_tsr(self, path: &str, method_router: MethodRouter<S>) -> Self\n    where\n        Self: Sized;\n\n    /// Add another route to the router with an additional \"trailing slash redirect\" route.\n    ///\n    /// This works like [`RouterExt::route_with_tsr`] but accepts any [`Service`].\n    fn route_service_with_tsr<T>(self, path: &str, service: T) -> Self\n    where\n        T: Service<Request, Error = Infallible> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse,\n        T::Future: Send + 'static,\n        Self: Sized;\n}\n\nimpl<S> RouterExt<S> for Router<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_get<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::get(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_delete<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::delete(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_head<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::head(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_options<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::options(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_patch<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::patch(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_post<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::post(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_put<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::put(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_trace<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::trace(handler))\n    }\n\n    #[cfg(feature = \"typed-routing\")]\n    fn typed_connect<H, T, P>(self, handler: H) -> Self\n    where\n        H: axum::handler::Handler<T, S>,\n        T: SecondElementIs<P> + 'static,\n        P: TypedPath,\n    {\n        self.route(P::PATH, axum::routing::connect(handler))\n    }\n\n    #[track_caller]\n    fn route_with_tsr(mut self, path: &str, method_router: MethodRouter<S>) -> Self\n    where\n        Self: Sized,\n    {\n        validate_tsr_path(path);\n        let method_filter = method_router.method_filter();\n        self = self.route(path, method_router);\n        add_tsr_redirect_route(self, path, method_filter)\n    }\n\n    #[track_caller]\n    fn route_service_with_tsr<T>(mut self, path: &str, service: T) -> Self\n    where\n        T: Service<Request, Error = Infallible> + Clone + Send + Sync + 'static,\n        T::Response: IntoResponse,\n        T::Future: Send + 'static,\n        Self: Sized,\n    {\n        validate_tsr_path(path);\n        self = self.route_service(path, service);\n        add_tsr_redirect_route(self, path, None)\n    }\n}\n\n#[track_caller]\nfn validate_tsr_path(path: &str) {\n    if path == \"/\" {\n        panic!(\"Cannot add a trailing slash redirect route for `/`\")\n    }\n}\n\nfn add_tsr_redirect_route<S>(\n    router: Router<S>,\n    path: &str,\n    method_filter: Option<MethodFilter>,\n) -> Router<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    async fn redirect_handler(OriginalUri(uri): OriginalUri) -> Response {\n        let new_uri = map_path(uri, |path| {\n            path.strip_suffix('/')\n                .map(Cow::Borrowed)\n                .unwrap_or_else(|| Cow::Owned(format!(\"{path}/\")))\n        });\n\n        if let Some(new_uri) = new_uri {\n            Redirect::permanent(new_uri.to_string()).into_response()\n        } else {\n            StatusCode::BAD_REQUEST.into_response()\n        }\n    }\n\n    let _slot;\n    let redirect_path = if let Some(without_slash) = path.strip_suffix('/') {\n        without_slash\n    } else {\n        // FIXME: Can return `&format!(...)` directly when MSRV is updated\n        _slot = format!(\"{path}/\");\n        &_slot\n    };\n\n    let method_router = match method_filter {\n        Some(f) => on(f, redirect_handler),\n        None => any(redirect_handler),\n    };\n\n    router.route(redirect_path, method_router)\n}\n\n/// Map the path of a `Uri`.\n///\n/// Returns `None` if the `Uri` cannot be put back together with the new path.\nfn map_path<F>(original_uri: Uri, f: F) -> Option<Uri>\nwhere\n    F: FnOnce(&str) -> Cow<'_, str>,\n{\n    let mut parts = original_uri.into_parts();\n    let path_and_query = parts.path_and_query.as_ref()?;\n\n    let new_path = f(path_and_query.path());\n\n    let new_path_and_query = if let Some(query) = &path_and_query.query() {\n        format!(\"{new_path}?{query}\").parse::<PathAndQuery>().ok()?\n    } else {\n        new_path.parse::<PathAndQuery>().ok()?\n    };\n    parts.path_and_query = Some(new_path_and_query);\n\n    Uri::from_parts(parts).ok()\n}\n\nmod sealed {\n    pub trait Sealed {}\n    impl<S> Sealed for axum::Router<S> {}\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::{\n        extract::Path,\n        routing::{get, post},\n    };\n\n    #[tokio::test]\n    async fn test_tsr() {\n        let app = Router::new()\n            .route_with_tsr(\"/foo\", get(|| async {}))\n            .route_with_tsr(\"/bar/\", get(|| async {}));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n\n        let res = client.get(\"/foo/\").await;\n        assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);\n        assert_eq!(res.headers()[\"location\"], \"/foo\");\n\n        let res = client.get(\"/bar/\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n\n        let res = client.get(\"/bar\").await;\n        assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);\n        assert_eq!(res.headers()[\"location\"], \"/bar/\");\n    }\n\n    #[tokio::test]\n    async fn tsr_with_params() {\n        let app = Router::new()\n            .route_with_tsr(\n                \"/a/{a}\",\n                get(|Path(param): Path<String>| async move { param }),\n            )\n            .route_with_tsr(\n                \"/b/{b}/\",\n                get(|Path(param): Path<String>| async move { param }),\n            );\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/a/foo\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"foo\");\n\n        let res = client.get(\"/a/foo/\").await;\n        assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);\n        assert_eq!(res.headers()[\"location\"], \"/a/foo\");\n\n        let res = client.get(\"/b/foo/\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n        assert_eq!(res.text().await, \"foo\");\n\n        let res = client.get(\"/b/foo\").await;\n        assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);\n        assert_eq!(res.headers()[\"location\"], \"/b/foo/\");\n    }\n\n    #[tokio::test]\n    async fn tsr_maintains_query_params() {\n        let app = Router::new().route_with_tsr(\"/foo\", get(|| async {}));\n\n        let client = TestClient::new(app);\n\n        let res = client.get(\"/foo/?a=a\").await;\n        assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);\n        assert_eq!(res.headers()[\"location\"], \"/foo?a=a\");\n    }\n\n    #[tokio::test]\n    async fn tsr_works_in_nested_router() {\n        let app = Router::new().nest(\n            \"/neko\",\n            Router::new().route_with_tsr(\"/nyan/\", get(|| async {})),\n        );\n\n        let client = TestClient::new(app);\n        let res = client.get(\"/neko/nyan/\").await;\n        assert_eq!(res.status(), StatusCode::OK);\n\n        let res = client.get(\"/neko/nyan\").await;\n        assert_eq!(res.status(), StatusCode::PERMANENT_REDIRECT);\n        assert_eq!(res.headers()[\"location\"], \"/neko/nyan/\");\n    }\n\n    #[test]\n    fn tsr_independent_route_registration() {\n        let _: Router = Router::new()\n            .route_with_tsr(\"/x\", get(|| async {}))\n            .route_with_tsr(\"/x\", post(|| async {}));\n    }\n\n    #[test]\n    #[should_panic = \"Cannot add a trailing slash redirect route for `/`\"]\n    fn tsr_at_root() {\n        let _: Router = Router::new().route_with_tsr(\"/\", get(|| async move {}));\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/routing/resource.rs",
    "content": "use axum::{\n    handler::Handler,\n    routing::{delete, get, on, post, MethodFilter, MethodRouter},\n    Router,\n};\n\n/// A resource which defines a set of conventional CRUD routes.\n///\n/// # Example\n///\n/// ```rust\n/// use axum::{Router, routing::get, extract::Path};\n/// use axum_extra::routing::{RouterExt, Resource};\n///\n/// let users = Resource::named(\"users\")\n///     // Define a route for `GET /users`\n///     .index(|| async {})\n///     // `POST /users`\n///     .create(|| async {})\n///     // `GET /users/new`\n///     .new(|| async {})\n///     // `GET /users/{users_id}`\n///     .show(|Path(user_id): Path<u64>| async {})\n///     // `GET /users/{users_id}/edit`\n///     .edit(|Path(user_id): Path<u64>| async {})\n///     // `PUT or PATCH /users/{users_id}`\n///     .update(|Path(user_id): Path<u64>| async {})\n///     // `DELETE /users/{users_id}`\n///     .destroy(|Path(user_id): Path<u64>| async {});\n///\n/// let app = Router::new().merge(users);\n/// # let _: Router = app;\n/// ```\n#[derive(Debug)]\n#[must_use]\npub struct Resource<S = ()> {\n    pub(crate) name: String,\n    pub(crate) router: Router<S>,\n}\n\nimpl<S> Resource<S>\nwhere\n    S: Clone + Send + Sync + 'static,\n{\n    /// Create a `Resource` with the given name.\n    ///\n    /// All routes will be nested at `/{resource_name}`.\n    pub fn named(resource_name: &str) -> Self {\n        Self {\n            name: resource_name.to_owned(),\n            router: Router::new(),\n        }\n    }\n\n    /// Add a handler at `GET /{resource_name}`.\n    pub fn index<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        let path = self.index_create_path();\n        self.route(&path, get(handler))\n    }\n\n    /// Add a handler at `POST /{resource_name}`.\n    pub fn create<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        let path = self.index_create_path();\n        self.route(&path, post(handler))\n    }\n\n    /// Add a handler at `GET /{resource_name}/new`.\n    pub fn new<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        let path = format!(\"/{}/new\", self.name);\n        self.route(&path, get(handler))\n    }\n\n    /// Add a handler at `GET /<resource_name>/{<resource_name>_id}`.\n    ///\n    /// For example when the resources are posts: `GET /post/{post_id}`.\n    pub fn show<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        let path = self.show_update_destroy_path();\n        self.route(&path, get(handler))\n    }\n\n    /// Add a handler at `GET /<resource_name>/{<resource_name>_id}/edit`.\n    ///\n    /// For example when the resources are posts: `GET /post/{post_id}/edit`.\n    pub fn edit<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        let path = format!(\"/{0}/{{{0}_id}}/edit\", self.name);\n        self.route(&path, get(handler))\n    }\n\n    /// Add a handler at `PUT or PATCH /<resource_name>/{<resource_name>_id}`.\n    ///\n    /// For example when the resources are posts: `PUT /post/{post_id}`.\n    pub fn update<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        let path = self.show_update_destroy_path();\n        self.route(\n            &path,\n            on(MethodFilter::PUT.or(MethodFilter::PATCH), handler),\n        )\n    }\n\n    /// Add a handler at `DELETE /<resource_name>/{<resource_name>_id}`.\n    ///\n    /// For example when the resources are posts: `DELETE /post/{post_id}`.\n    pub fn destroy<H, T>(self, handler: H) -> Self\n    where\n        H: Handler<T, S>,\n        T: 'static,\n    {\n        let path = self.show_update_destroy_path();\n        self.route(&path, delete(handler))\n    }\n\n    fn index_create_path(&self) -> String {\n        format!(\"/{}\", self.name)\n    }\n\n    fn show_update_destroy_path(&self) -> String {\n        format!(\"/{0}/{{{0}_id}}\", self.name)\n    }\n\n    fn route(mut self, path: &str, method_router: MethodRouter<S>) -> Self {\n        self.router = self.router.route(path, method_router);\n        self\n    }\n}\n\nimpl<S> From<Resource<S>> for Router<S> {\n    fn from(resource: Resource<S>) -> Self {\n        resource.router\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    #[allow(unused_imports)]\n    use super::*;\n    use axum::{body::Body, extract::Path, http::Method};\n    use http::Request;\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    #[tokio::test]\n    async fn works() {\n        let users = Resource::named(\"users\")\n            .index(|| async { \"users#index\" })\n            .create(|| async { \"users#create\" })\n            .new(|| async { \"users#new\" })\n            .show(|Path(id): Path<u64>| async move { format!(\"users#show id={id}\") })\n            .edit(|Path(id): Path<u64>| async move { format!(\"users#edit id={id}\") })\n            .update(|Path(id): Path<u64>| async move { format!(\"users#update id={id}\") })\n            .destroy(|Path(id): Path<u64>| async move { format!(\"users#destroy id={id}\") });\n\n        let app = Router::new().merge(users);\n\n        assert_eq!(call_route(&app, Method::GET, \"/users\").await, \"users#index\");\n\n        assert_eq!(\n            call_route(&app, Method::POST, \"/users\").await,\n            \"users#create\"\n        );\n\n        assert_eq!(\n            call_route(&app, Method::GET, \"/users/new\").await,\n            \"users#new\"\n        );\n\n        assert_eq!(\n            call_route(&app, Method::GET, \"/users/1\").await,\n            \"users#show id=1\"\n        );\n\n        assert_eq!(\n            call_route(&app, Method::GET, \"/users/1/edit\").await,\n            \"users#edit id=1\"\n        );\n\n        assert_eq!(\n            call_route(&app, Method::PATCH, \"/users/1\").await,\n            \"users#update id=1\"\n        );\n\n        assert_eq!(\n            call_route(&app, Method::PUT, \"/users/1\").await,\n            \"users#update id=1\"\n        );\n\n        assert_eq!(\n            call_route(&app, Method::DELETE, \"/users/1\").await,\n            \"users#destroy id=1\"\n        );\n    }\n\n    async fn call_route(app: &Router, method: Method, uri: &str) -> String {\n        let res = app\n            .clone()\n            .oneshot(\n                Request::builder()\n                    .method(method)\n                    .uri(uri)\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n        let bytes = res.collect().await.unwrap().to_bytes();\n        String::from_utf8(bytes.to_vec()).unwrap()\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/routing/typed.rs",
    "content": "use std::{any::type_name, fmt};\n\nuse super::sealed::Sealed;\nuse http::Uri;\nuse serde_core::Serialize;\n\n/// A type safe path.\n///\n/// This is used to statically connect a path to its corresponding handler using\n/// [`RouterExt::typed_get`], [`RouterExt::typed_post`], etc.\n///\n/// # Example\n///\n/// ```rust\n/// use serde::Deserialize;\n/// use axum::{Router, extract::Json};\n/// use axum_extra::routing::{\n///     TypedPath,\n///     RouterExt, // for `Router::typed_*`\n/// };\n///\n/// // A type safe route with `/users/{id}` as its associated path.\n/// #[derive(TypedPath, Deserialize)]\n/// #[typed_path(\"/users/{id}\")]\n/// struct UsersMember {\n///     id: u32,\n/// }\n///\n/// // A regular handler function that takes `UsersMember` as the first argument\n/// // and thus creates a typed connection between this handler and the `/users/{id}` path.\n/// //\n/// // The `TypedPath` must be the first argument to the function.\n/// async fn users_show(\n///     UsersMember { id }: UsersMember,\n/// ) {\n///     // ...\n/// }\n///\n/// let app = Router::new()\n///     // Add our typed route to the router.\n///     //\n///     // The path will be inferred to `/users/{id}` since `users_show`'s\n///     // first argument is `UsersMember` which implements `TypedPath`\n///     .typed_get(users_show)\n///     .typed_post(users_create)\n///     .typed_delete(users_destroy);\n///\n/// #[derive(TypedPath)]\n/// #[typed_path(\"/users\")]\n/// struct UsersCollection;\n///\n/// #[derive(Deserialize)]\n/// struct UsersCreatePayload { /* ... */ }\n///\n/// async fn users_create(\n///     _: UsersCollection,\n///     // Our handlers can accept other extractors.\n///     Json(payload): Json<UsersCreatePayload>,\n/// ) {\n///     // ...\n/// }\n///\n/// async fn users_destroy(_: UsersCollection) { /* ... */ }\n///\n/// #\n/// # let app: Router = app;\n/// ```\n///\n/// # Using `#[derive(TypedPath)]`\n///\n/// While `TypedPath` can be implemented manually, it's _highly_ recommended to derive it:\n///\n/// ```\n/// use serde::Deserialize;\n/// use axum_extra::routing::TypedPath;\n///\n/// #[derive(TypedPath, Deserialize)]\n/// #[typed_path(\"/users/{id}\")]\n/// struct UsersMember {\n///     id: u32,\n/// }\n/// ```\n///\n/// The macro expands to:\n///\n/// - A `TypedPath` implementation.\n/// - A [`FromRequest`] implementation compatible with [`RouterExt::typed_get`],\n///   [`RouterExt::typed_post`], etc. This implementation uses [`Path`] and thus your struct must\n///   also implement [`serde::Deserialize`], unless it's a unit struct.\n/// - A [`Display`] implementation that interpolates the captures. This can be used to, among other\n///   things, create links to known paths and have them verified statically. Note that the\n///   [`Display`] implementation for each field must return something that's compatible with its\n///   [`Deserialize`] implementation.\n///\n/// Additionally the macro will verify the captures in the path matches the fields of the struct.\n/// For example this fails to compile since the struct doesn't have a `team_id` field:\n///\n/// ```compile_fail\n/// use serde::Deserialize;\n/// use axum_extra::routing::TypedPath;\n///\n/// #[derive(TypedPath, Deserialize)]\n/// #[typed_path(\"/users/{id}/teams/{team_id}\")]\n/// struct UsersMember {\n///     id: u32,\n/// }\n/// ```\n///\n/// Unit and tuple structs are also supported:\n///\n/// ```\n/// use serde::Deserialize;\n/// use axum_extra::routing::TypedPath;\n///\n/// #[derive(TypedPath)]\n/// #[typed_path(\"/users\")]\n/// struct UsersCollection;\n///\n/// #[derive(TypedPath, Deserialize)]\n/// #[typed_path(\"/users/{id}\")]\n/// struct UsersMember(u32);\n/// ```\n///\n/// ## Percent encoding\n///\n/// The generated [`Display`] implementation will automatically percent-encode the arguments:\n///\n/// ```\n/// use serde::Deserialize;\n/// use axum_extra::routing::TypedPath;\n///\n/// #[derive(TypedPath, Deserialize)]\n/// #[typed_path(\"/users/{id}\")]\n/// struct UsersMember {\n///     id: String,\n/// }\n///\n/// assert_eq!(\n///     UsersMember {\n///         id: \"foo bar\".to_string(),\n///     }.to_string(),\n///     \"/users/foo%20bar\",\n/// );\n/// ```\n///\n/// ## Customizing the rejection\n///\n/// By default the rejection used in the [`FromRequest`] implementation will be [`PathRejection`].\n///\n/// That can be customized using `#[typed_path(\"...\", rejection(YourType))]`:\n///\n/// ```\n/// use serde::Deserialize;\n/// use axum_extra::routing::TypedPath;\n/// use axum::{\n///     response::{IntoResponse, Response},\n///     extract::rejection::PathRejection,\n/// };\n///\n/// #[derive(TypedPath, Deserialize)]\n/// #[typed_path(\"/users/{id}\", rejection(UsersMemberRejection))]\n/// struct UsersMember {\n///     id: String,\n/// }\n///\n/// struct UsersMemberRejection;\n///\n/// // Your rejection type must implement `From<PathRejection>`.\n/// //\n/// // Here you can grab whatever details from the inner rejection\n/// // that you need.\n/// impl From<PathRejection> for UsersMemberRejection {\n///     fn from(rejection: PathRejection) -> Self {\n///         # UsersMemberRejection\n///         // ...\n///     }\n/// }\n///\n/// // Your rejection must implement `IntoResponse`, like all rejections.\n/// impl IntoResponse for UsersMemberRejection {\n///     fn into_response(self) -> Response {\n///         # ().into_response()\n///         // ...\n///     }\n/// }\n/// ```\n///\n/// The `From<PathRejection>` requirement only applies if your typed path is a struct with named\n/// fields or a tuple struct. For unit structs your rejection type must implement `Default`:\n///\n/// ```\n/// use axum_extra::routing::TypedPath;\n/// use axum::response::{IntoResponse, Response};\n///\n/// #[derive(TypedPath)]\n/// #[typed_path(\"/users\", rejection(UsersCollectionRejection))]\n/// struct UsersCollection;\n///\n/// #[derive(Default)]\n/// struct UsersCollectionRejection;\n///\n/// impl IntoResponse for UsersCollectionRejection {\n///     fn into_response(self) -> Response {\n///         # ().into_response()\n///         // ...\n///     }\n/// }\n/// ```\n///\n/// [`FromRequest`]: axum::extract::FromRequest\n/// [`RouterExt::typed_get`]: super::RouterExt::typed_get\n/// [`RouterExt::typed_post`]: super::RouterExt::typed_post\n/// [`Path`]: axum::extract::Path\n/// [`Display`]: std::fmt::Display\n/// [`Deserialize`]: serde::Deserialize\n/// [`PathRejection`]: axum::extract::rejection::PathRejection\npub trait TypedPath: std::fmt::Display {\n    /// The path with optional captures such as `/users/{id}`.\n    const PATH: &'static str;\n\n    /// Convert the path into a `Uri`.\n    ///\n    /// # Panics\n    ///\n    /// The default implementation parses the required [`Display`] implementation. If that fails it\n    /// will panic.\n    ///\n    /// Using `#[derive(TypedPath)]` will never result in a panic since it percent-encodes\n    /// arguments.\n    ///\n    /// [`Display`]: std::fmt::Display\n    fn to_uri(&self) -> Uri {\n        self.to_string().parse().unwrap()\n    }\n\n    /// Add query parameters to a path.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use axum_extra::routing::TypedPath;\n    /// use serde::Serialize;\n    ///\n    /// #[derive(TypedPath)]\n    /// #[typed_path(\"/users\")]\n    /// struct Users;\n    ///\n    /// #[derive(Serialize)]\n    /// struct Pagination {\n    ///     page: u32,\n    ///     per_page: u32,\n    /// }\n    ///\n    /// let path = Users.with_query_params(Pagination {\n    ///     page: 1,\n    ///     per_page: 10,\n    /// });\n    ///\n    /// assert_eq!(path.to_uri(), \"/users?&page=1&per_page=10\");\n    /// ```\n    ///\n    /// # Panics\n    ///\n    /// If `params` doesn't support being serialized as query params [`WithQueryParams`]'s [`Display`]\n    /// implementation will panic, and thus [`WithQueryParams::to_uri`] will also panic.\n    ///\n    /// [`WithQueryParams::to_uri`]: TypedPath::to_uri\n    /// [`Display`]: std::fmt::Display\n    fn with_query_params<T>(self, params: T) -> WithQueryParams<Self, T>\n    where\n        T: Serialize,\n        Self: Sized,\n    {\n        WithQueryParams { path: self, params }\n    }\n}\n\n/// A [`TypedPath`] with query params.\n///\n/// See [`TypedPath::with_query_params`] for more details.\n#[derive(Debug, Clone, Copy)]\npub struct WithQueryParams<P, T> {\n    path: P,\n    params: T,\n}\n\nimpl<P, T> fmt::Display for WithQueryParams<P, T>\nwhere\n    P: TypedPath,\n    T: Serialize,\n{\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        let mut out = self.path.to_string();\n        if !out.contains('?') {\n            out.push('?');\n        }\n        let mut urlencoder = form_urlencoded::Serializer::new(&mut out);\n        self.params\n            .serialize(serde_html_form::ser::Serializer::new(&mut urlencoder))\n            .unwrap_or_else(|err| {\n                panic!(\n                    \"failed to URL encode value of type `{}`: {err}\",\n                    type_name::<T>(),\n                )\n            });\n        f.write_str(&out)?;\n\n        Ok(())\n    }\n}\n\nimpl<P, T> TypedPath for WithQueryParams<P, T>\nwhere\n    P: TypedPath,\n    T: Serialize,\n{\n    const PATH: &'static str = P::PATH;\n}\n\n/// Utility trait used with [`RouterExt`] to ensure the second element of a tuple type is a\n/// given type.\n///\n/// If you see it in type errors it's most likely because the first argument to your handler doesn't\n/// implement [`TypedPath`].\n///\n/// You normally shouldn't have to use this trait directly.\n///\n/// It is sealed such that it cannot be implemented outside this crate.\n///\n/// [`RouterExt`]: super::RouterExt\npub trait SecondElementIs<P>: Sealed {}\n\nmacro_rules! impl_second_element_is {\n    ( $($ty:ident),* $(,)? ) => {\n        impl<M, P, $($ty,)*> SecondElementIs<P> for (M, P, $($ty,)*)\n        where\n            P: TypedPath\n        {}\n\n        impl<M, P, $($ty,)*> Sealed for (M, P, $($ty,)*)\n        where\n            P: TypedPath\n        {}\n\n        impl<M, P, $($ty,)*> SecondElementIs<P> for (M, Option<P>, $($ty,)*)\n        where\n            P: TypedPath\n        {}\n\n        impl<M, P, $($ty,)*> Sealed for (M, Option<P>, $($ty,)*)\n        where\n            P: TypedPath\n        {}\n\n        impl<M, P, E, $($ty,)*> SecondElementIs<P> for (M, Result<P, E>, $($ty,)*)\n        where\n            P: TypedPath\n        {}\n\n        impl<M, P, E, $($ty,)*> Sealed for (M, Result<P, E>, $($ty,)*)\n        where\n            P: TypedPath\n        {}\n    };\n}\n\nimpl_second_element_is!();\nimpl_second_element_is!(T1);\nimpl_second_element_is!(T1, T2);\nimpl_second_element_is!(T1, T2, T3);\nimpl_second_element_is!(T1, T2, T3, T4);\nimpl_second_element_is!(T1, T2, T3, T4, T5);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);\nimpl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);\n\n#[cfg(test)]\nmod tests {\n    use crate::routing::TypedPath;\n    use serde::{Deserialize, Serialize};\n\n    #[derive(TypedPath, Deserialize)]\n    #[typed_path(\"/users/{id}\")]\n    struct UsersShow {\n        id: i32,\n    }\n\n    #[derive(Serialize)]\n    struct Params {\n        foo: &'static str,\n        bar: i32,\n        baz: bool,\n    }\n\n    #[test]\n    fn with_params() {\n        let path = UsersShow { id: 1 }.with_query_params(Params {\n            foo: \"foo\",\n            bar: 123,\n            baz: true,\n        });\n\n        let uri = path.to_uri();\n\n        // according to [the spec] starting the params with `?&` is allowed specifically:\n        //\n        // > If bytes is the empty byte sequence, then continue.\n        //\n        // [the spec]: https://url.spec.whatwg.org/#urlencoded-parsing\n        assert_eq!(uri, \"/users/1?&foo=foo&bar=123&baz=true\");\n    }\n\n    #[test]\n    fn with_params_called_multiple_times() {\n        let path = UsersShow { id: 1 }\n            .with_query_params(Params {\n                foo: \"foo\",\n                bar: 123,\n                baz: true,\n            })\n            .with_query_params([(\"qux\", 1337)]);\n\n        let uri = path.to_uri();\n\n        assert_eq!(uri, \"/users/1?&foo=foo&bar=123&baz=true&qux=1337\");\n    }\n\n    #[cfg(feature = \"with-rejection\")]\n    #[allow(dead_code)] // just needs to compile\n    fn supports_with_rejection() {\n        use crate::routing::RouterExt;\n        use axum::{\n            extract::rejection::PathRejection,\n            response::{IntoResponse, Response},\n            Router,\n        };\n        async fn handler(_: crate::extract::WithRejection<UsersShow, MyRejection>) {}\n\n        struct MyRejection {}\n\n        impl IntoResponse for MyRejection {\n            fn into_response(self) -> Response {\n                unimplemented!()\n            }\n        }\n\n        impl From<PathRejection> for MyRejection {\n            fn from(_: PathRejection) -> Self {\n                unimplemented!()\n            }\n        }\n\n        let _: Router = Router::new().typed_get(handler);\n    }\n}\n"
  },
  {
    "path": "axum-extra/src/typed_header.rs",
    "content": "//! Extractor and response for typed headers.\n\nuse axum_core::{\n    extract::{FromRequestParts, OptionalFromRequestParts},\n    response::{IntoResponse, IntoResponseParts, Response, ResponseParts},\n};\nuse headers::{Header, HeaderMapExt};\nuse http::{request::Parts, StatusCode};\nuse std::convert::Infallible;\n\n/// Extractor and response that works with typed header values from [`headers`].\n///\n/// # As extractor\n///\n/// In general, it's recommended to extract only the needed headers via `TypedHeader` rather than\n/// removing all headers with the `HeaderMap` extractor.\n///\n/// ```rust,no_run\n/// use axum::{\n///     routing::get,\n///     Router,\n/// };\n/// use headers::UserAgent;\n/// use axum_extra::TypedHeader;\n///\n/// async fn users_teams_show(\n///     TypedHeader(user_agent): TypedHeader<UserAgent>,\n/// ) {\n///     // ...\n/// }\n///\n/// let app = Router::new().route(\"/users/{user_id}/team/{team_id}\", get(users_teams_show));\n/// # let _: Router = app;\n/// ```\n///\n/// # As response\n///\n/// ```rust\n/// use axum::{\n///     response::IntoResponse,\n/// };\n/// use headers::ContentType;\n/// use axum_extra::TypedHeader;\n///\n/// async fn handler() -> (TypedHeader<ContentType>, &'static str) {\n///     (\n///         TypedHeader(ContentType::text_utf8()),\n///         \"Hello, World!\",\n///     )\n/// }\n/// ```\n#[cfg(feature = \"typed-header\")]\n#[derive(Debug, Clone, Copy)]\n#[must_use]\npub struct TypedHeader<T>(pub T);\n\nimpl<T, S> FromRequestParts<S> for TypedHeader<T>\nwhere\n    T: Header,\n    S: Send + Sync,\n{\n    type Rejection = TypedHeaderRejection;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        let mut values = parts.headers.get_all(T::name()).iter();\n        let is_missing = values.size_hint() == (0, Some(0));\n        T::decode(&mut values)\n            .map(Self)\n            .map_err(|err| TypedHeaderRejection {\n                name: T::name(),\n                reason: if is_missing {\n                    // Report a more precise rejection for the missing header case.\n                    TypedHeaderRejectionReason::Missing\n                } else {\n                    TypedHeaderRejectionReason::Error(err)\n                },\n            })\n    }\n}\n\nimpl<T, S> OptionalFromRequestParts<S> for TypedHeader<T>\nwhere\n    T: Header,\n    S: Send + Sync,\n{\n    type Rejection = TypedHeaderRejection;\n\n    async fn from_request_parts(\n        parts: &mut Parts,\n        _state: &S,\n    ) -> Result<Option<Self>, Self::Rejection> {\n        let mut values = parts.headers.get_all(T::name()).iter();\n        let is_missing = values.size_hint() == (0, Some(0));\n        match T::decode(&mut values) {\n            Ok(res) => Ok(Some(Self(res))),\n            Err(_) if is_missing => Ok(None),\n            Err(err) => Err(TypedHeaderRejection {\n                name: T::name(),\n                reason: TypedHeaderRejectionReason::Error(err),\n            }),\n        }\n    }\n}\n\naxum_core::__impl_deref!(TypedHeader);\n\nimpl<T> IntoResponseParts for TypedHeader<T>\nwhere\n    T: Header,\n{\n    type Error = Infallible;\n\n    fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {\n        res.headers_mut().typed_insert(self.0);\n        Ok(res)\n    }\n}\n\nimpl<T> IntoResponse for TypedHeader<T>\nwhere\n    T: Header,\n{\n    fn into_response(self) -> Response {\n        let mut res = ().into_response();\n        res.headers_mut().typed_insert(self.0);\n        res\n    }\n}\n\n/// Rejection used for [`TypedHeader`].\n#[cfg(feature = \"typed-header\")]\n#[derive(Debug)]\npub struct TypedHeaderRejection {\n    name: &'static http::header::HeaderName,\n    reason: TypedHeaderRejectionReason,\n}\n\nimpl TypedHeaderRejection {\n    /// Name of the header that caused the rejection\n    #[must_use]\n    pub fn name(&self) -> &http::header::HeaderName {\n        self.name\n    }\n\n    /// Reason why the header extraction has failed\n    #[must_use]\n    pub fn reason(&self) -> &TypedHeaderRejectionReason {\n        &self.reason\n    }\n\n    /// Returns `true` if the typed header rejection reason is [`Missing`].\n    ///\n    /// [`Missing`]: TypedHeaderRejectionReason::Missing\n    #[must_use]\n    pub fn is_missing(&self) -> bool {\n        self.reason.is_missing()\n    }\n}\n\n/// Additional information regarding a [`TypedHeaderRejection`]\n#[cfg(feature = \"typed-header\")]\n#[derive(Debug)]\n#[non_exhaustive]\npub enum TypedHeaderRejectionReason {\n    /// The header was missing from the HTTP request\n    Missing,\n    /// An error occurred when parsing the header from the HTTP request\n    Error(headers::Error),\n}\n\nimpl TypedHeaderRejectionReason {\n    /// Returns `true` if the typed header rejection reason is [`Missing`].\n    ///\n    /// [`Missing`]: TypedHeaderRejectionReason::Missing\n    #[must_use]\n    pub fn is_missing(&self) -> bool {\n        matches!(self, Self::Missing)\n    }\n}\n\nimpl IntoResponse for TypedHeaderRejection {\n    fn into_response(self) -> Response {\n        let status = StatusCode::BAD_REQUEST;\n        let body = self.to_string();\n        axum_core::__log_rejection!(rejection_type = Self, body_text = body, status = status,);\n        (status, body).into_response()\n    }\n}\n\nimpl std::fmt::Display for TypedHeaderRejection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match &self.reason {\n            TypedHeaderRejectionReason::Missing => {\n                write!(f, \"Header of type `{}` was missing\", self.name)\n            }\n            TypedHeaderRejectionReason::Error(err) => {\n                write!(f, \"{err} ({})\", self.name)\n            }\n        }\n    }\n}\n\nimpl std::error::Error for TypedHeaderRejection {\n    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n        match &self.reason {\n            TypedHeaderRejectionReason::Error(err) => Some(err),\n            TypedHeaderRejectionReason::Missing => None,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::test_helpers::*;\n    use axum::{routing::get, Router};\n\n    #[tokio::test]\n    async fn typed_header() {\n        async fn handle(\n            TypedHeader(user_agent): TypedHeader<headers::UserAgent>,\n            TypedHeader(cookies): TypedHeader<headers::Cookie>,\n        ) -> impl IntoResponse {\n            let user_agent = user_agent.as_str();\n            let cookies = cookies.iter().collect::<Vec<_>>();\n            format!(\"User-Agent={user_agent:?}, Cookie={cookies:?}\")\n        }\n\n        let app = Router::new().route(\"/\", get(handle));\n\n        let client = TestClient::new(app);\n\n        let res = client\n            .get(\"/\")\n            .header(\"user-agent\", \"foobar\")\n            .header(\"cookie\", \"a=1; b=2\")\n            .header(\"cookie\", \"c=3\")\n            .await;\n        let body = res.text().await;\n        assert_eq!(\n            body,\n            r#\"User-Agent=\"foobar\", Cookie=[(\"a\", \"1\"), (\"b\", \"2\"), (\"c\", \"3\")]\"#\n        );\n\n        let res = client.get(\"/\").header(\"user-agent\", \"foobar\").await;\n        let body = res.text().await;\n        assert_eq!(body, r#\"User-Agent=\"foobar\", Cookie=[]\"#);\n\n        let res = client.get(\"/\").header(\"cookie\", \"a=1\").await;\n        let body = res.text().await;\n        assert_eq!(body, \"Header of type `user-agent` was missing\");\n    }\n}\n"
  },
  {
    "path": "axum-extra/test_files/index.html",
    "content": "<h1>Hello, World!</h1>\n"
  },
  {
    "path": "axum-extra/test_files/index_2.html",
    "content": "<strong>Hello, World!</strong>\n"
  },
  {
    "path": "axum-extra/test_files/script.js",
    "content": "console.log('hi')\n"
  },
  {
    "path": "axum-macros/CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n# Unreleased\n\n- **breaking:** `#[from_request(via(Extractor))]` now uses the extractor's\n  rejection type instead of `axum::response::Response` ([#3261])\n- **fixed:** Fix compilation error when deriving `TypedPath` with\n  `OptionalFromRequestParts` being in scope ([#3645])\n\n[#3261]: https://github.com/tokio-rs/axum/pull/3261\n[#3645]: https://github.com/tokio-rs/axum/pull/3645\n\n# 0.5.0\n\n*No changes since alpha.1*\n\n## full changelog\n\n- **breaking:** Update code generation for axum-core 0.5.0\n- **change:** Update minimum rust version to 1.75 ([#2943])\n\n## alpha.1\n\n- **breaking:** Update code generation for axum-core 0.5.0-alpha.1\n- **change:** Update minimum rust version to 1.75 ([#2943])\n\n[#2943]: https://github.com/tokio-rs/axum/pull/2943\n\n# 0.4.2\n\n- **added:** Add `#[debug_middleware]` ([#1993], [#2725])\n\n[#1993]: https://github.com/tokio-rs/axum/pull/1993\n[#2725]: https://github.com/tokio-rs/axum/pull/2725\n\n# 0.4.1 (13. January, 2024)\n\n- **fixed:** Improve `debug_handler` on tuple response types ([#2201])\n\n[#2201]: https://github.com/tokio-rs/axum/pull/2201\n\n# 0.4.0 (27. November, 2023)\n\n- **breaking:** `#[debug_handler]` no longer accepts a `body = _` argument. The\n  body type is always `axum::body::Body` ([#1751])\n- **fixed:** Fix `rust-version` specific in Cargo.toml ([#2204])\n\n[#2204]: https://github.com/tokio-rs/axum/pull/2204\n[#1751]: https://github.com/tokio-rs/axum/pull/1751\n\n# 0.3.8 (17. July, 2023)\n\n- **fixed:** Allow unreachable code in `#[debug_handler]` ([#2014])\n\n[#2014]: https://github.com/tokio-rs/axum/pull/2014\n\n# 0.3.7 (22. March, 2023)\n\n- **change:** Update to syn 2.0 ([#1862])\n- **fixed:** Give better error if generics are used with `#[derive(FromRef)]` ([#1874])\n\n[#1862]: https://github.com/tokio-rs/axum/pull/1862\n[#1874]: https://github.com/tokio-rs/axum/pull/1874\n\n# 0.3.6 (13. March, 2023)\n\n- **fixed:** Improve `#[debug_handler]` message for known generic\n  request-consuming extractors ([#1826])\n\n[#1826]: https://github.com/tokio-rs/axum/pull/1826\n\n# 0.3.5 (03. March, 2023)\n\n- **fixed:** In `#[debug_handler]` provide specific errors about `FromRequest`\n  extractors not being the last argument ([#1797])\n\n[#1797]: https://github.com/tokio-rs/axum/pull/1797\n\n# 0.3.4 (12. February, 2022)\n\n- **fixed:** Fix `#[derive(FromRef)]` with `Copy` fields generating clippy warnings ([#1749])\n\n[#1749]: https://github.com/tokio-rs/axum/pull/1749\n\n# 0.3.3 (11. February, 2022)\n\n- **fixed:** Fix `#[debug_handler]` sometimes giving wrong borrow related suggestions ([#1710])\n\n[#1710]: https://github.com/tokio-rs/axum/pull/1710\n\n# 0.3.2 (22. January, 2022)\n\n- No public API changes.\n\n# 0.3.1 (9. January, 2022)\n\n- **fixed:** Fix warnings for cloning references in generated code ([#1676])\n\n[#1676]: https://github.com/tokio-rs/axum/pull/1676\n\n# 0.3.0 (25. November, 2022)\n\n- **added:** Add `#[derive(FromRequestParts)]` for deriving an implementation of\n  `FromRequestParts`, similarly to `#[derive(FromRequest)]` ([#1305])\n- **added:** Add `#[derive(FromRef)]` ([#1430])\n- **added:** Add `#[from_ref(skip)]` to skip implementing `FromRef` for individual fields ([#1537])\n- **added:** Support using a different rejection for `#[derive(FromRequest)]`\n  with `#[from_request(rejection(MyRejection))]` ([#1256])\n- **change:** axum-macro's MSRV is now 1.60 ([#1239])\n- **breaking:** `#[derive(FromRequest)]` will no longer generate a rejection\n  enum but instead generate `type Rejection = axum::response::Response`. Use the\n  new `#[from_request(rejection(MyRejection))]` attribute to change this.\n  The `rejection_derive` attribute has also been removed ([#1272])\n\n[#1239]: https://github.com/tokio-rs/axum/pull/1239\n[#1256]: https://github.com/tokio-rs/axum/pull/1256\n[#1272]: https://github.com/tokio-rs/axum/pull/1272\n[#1305]: https://github.com/tokio-rs/axum/pull/1305\n[#1430]: https://github.com/tokio-rs/axum/pull/1430\n[#1537]: https://github.com/tokio-rs/axum/pull/1537\n\n<details>\n<summary>0.3.0 Pre-Releases</summary>\n\n# 0.3.0-rc.3 (18. November, 2022)\n\n- **added:** Add `#[from_ref(skip)]` to skip implementing `FromRef` for individual fields ([#1537])\n\n[#1537]: https://github.com/tokio-rs/axum/pull/1537\n\n# 0.3.0-rc.2 (8. November, 2022)\n\n- **added:** Add `#[derive(FromRef)]` ([#1430])\n\n[#1430]: https://github.com/tokio-rs/axum/pull/1430\n\n# 0.3.0-rc.1 (23. August, 2022)\n\n- **change:** axum-macro's MSRV is now 1.60 ([#1239])\n- **added:** Support using a different rejection for `#[derive(FromRequest)]`\n  with `#[from_request(rejection(MyRejection))]` ([#1256])\n- **breaking:** `#[derive(FromRequest)]` will no longer generate a rejection\n  enum but instead generate `type Rejection = axum::response::Response`. Use the\n  new `#[from_request(rejection(MyRejection))]` attribute to change this.\n  The `rejection_derive` attribute has also been removed ([#1272])\n- **added:** Add `#[derive(FromRequestParts)]` for deriving an implementation of\n  `FromRequestParts`, similarly to `#[derive(FromRequest)]` ([#1305])\n\n[#1239]: https://github.com/tokio-rs/axum/pull/1239\n[#1256]: https://github.com/tokio-rs/axum/pull/1256\n[#1272]: https://github.com/tokio-rs/axum/pull/1272\n[#1305]: https://github.com/tokio-rs/axum/pull/1305\n\n</details>\n\n# 0.2.3 (27. June, 2022)\n\n- **change:** axum-macros's MSRV is now 1.56 ([#1098])\n- **fixed:** Silence \"unnecessary use of `to_string`\" lint for `#[derive(TypedPath)]` ([#1117])\n\n[#1098]: https://github.com/tokio-rs/axum/pull/1098\n[#1117]: https://github.com/tokio-rs/axum/pull/1117\n\n# 0.2.2 (18. May, 2022)\n\n- **added:** In `debug_handler`, check if `Request` is used as non-final extractor ([#1035])\n- **added:** In `debug_handler`, check if multiple `Path` extractors are used ([#1035])\n- **added:** In `debug_handler`, check if multiple body extractors are used ([#1036])\n- **added:** Support customizing rejections for `#[derive(TypedPath)]` ([#1012])\n\n[#1035]: https://github.com/tokio-rs/axum/pull/1035\n[#1036]: https://github.com/tokio-rs/axum/pull/1036\n[#1012]: https://github.com/tokio-rs/axum/pull/1012\n\n# 0.2.1 (10. May, 2022)\n\n- **fixed:** `Option` and `Result` are now supported in typed path route handler parameters ([#1001])\n- **fixed:** Support wildcards in typed paths ([#1003])\n- **added:** Support `#[derive(FromRequest)]` on enums using `#[from_request(via(OtherExtractor))]` ([#1009])\n- **added:** Support using a custom rejection type for `#[derive(TypedPath)]`\n  instead of `PathRejection` ([#1012])\n\n[#1001]: https://github.com/tokio-rs/axum/pull/1001\n[#1003]: https://github.com/tokio-rs/axum/pull/1003\n[#1009]: https://github.com/tokio-rs/axum/pull/1009\n[#1012]: https://github.com/tokio-rs/axum/pull/1012\n\n# 0.2.0 (31. March, 2022)\n\n- **breaking:** Routes are now required to start with `/`. Previously empty routes or routes such\n  as `:foo` would be accepted but most likely result in bugs ([#823])\n\n[#823]: https://github.com/tokio-rs/axum/pull/823\n\n# 0.1.2 (1. March 2022)\n\n- **fixed:** Use fully qualified `Result` type ([#796])\n\n[#796]: https://github.com/tokio-rs/axum/pull/796\n\n# 0.1.1 (22. February 2022)\n\n- Add `#[derive(TypedPath)]` for use with axum-extra's new \"type safe\" routing API ([#756])\n\n[#756]: https://github.com/tokio-rs/axum/pull/756\n\n# 0.1.0 (31. January, 2022)\n\n- Initial release.\n"
  },
  {
    "path": "axum-macros/Cargo.toml",
    "content": "[package]\ncategories = [\"asynchronous\", \"network-programming\", \"web-programming\"]\ndescription = \"Macros for axum\"\nedition = \"2021\"\nrust-version = { workspace = true }\nhomepage = \"https://github.com/tokio-rs/axum\"\nkeywords = [\"axum\"]\nlicense = \"MIT\"\nname = \"axum-macros\"\nreadme = \"README.md\"\nrepository = \"https://github.com/tokio-rs/axum\"\nversion = \"0.5.0\" # remember to also bump the version that axum and axum-extra depends on\n\n[package.metadata.docs.rs]\nall-features = true\n\n[lib]\nproc-macro = true\n\n[features]\ndefault = []\n__private = [\"syn/visit-mut\"]\n\n[dependencies]\nproc-macro2 = \"1.0\"\nquote = \"1.0\"\nsyn = { version = \"2.0\", features = [\n    \"full\",\n    \"parsing\",\n    # needed for `Hash` impls\n    \"extra-traits\",\n] }\n\n[dev-dependencies]\naxum = { path = \"../axum\", features = [\"macros\"] }\naxum-extra = { path = \"../axum-extra\", features = [\"typed-routing\", \"cookie-private\", \"typed-header\", \"routing\"] }\nrustversion = \"1.0\"\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\nsyn = { version = \"2.0\", features = [\"full\", \"extra-traits\"] }\ntokio = { version = \"1.25.0\", features = [\"full\"] }\ntrybuild = \"1.0.63\"\n\n[lints]\nworkspace = true\n"
  },
  {
    "path": "axum-macros/README.md",
    "content": "# axum-macros\n\n[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum-macros/actions/workflows/CI.yml)\n[![Crates.io](https://img.shields.io/crates/v/axum-macros)](https://crates.io/crates/axum-macros)\n[![Documentation](https://docs.rs/axum-macros/badge.svg)](https://docs.rs/axum-macros)\n\nMacros for [`axum`].\n\nMore information about this crate can be found in the [crate documentation][docs].\n\n## Safety\n\nThis crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% safe Rust.\n\n## Minimum supported Rust version\n\naxum-macros's MSRV is 1.75.\n\n## Getting Help\n\nYou're also welcome to ask in the [Discord channel][chat] or open an [issue]\nwith your question.\n\n## Contributing\n\n🎈 Thanks for your help improving the project! We are so happy to have\nyou! We have a [contributing guide][contributing] to help you get involved in the\n`axum` project.\n\n## License\n\nThis project is licensed under the [MIT license][license].\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in `axum` by you, shall be licensed as MIT, without any\nadditional terms or conditions.\n\n[`axum`]: https://crates.io/crates/axum\n[chat]: https://discord.gg/tokio\n[contributing]: /CONTRIBUTING.md\n[docs]: https://docs.rs/axum-macros\n[license]: /axum-macros/LICENSE\n[issue]: https://github.com/tokio-rs/axum/issues/new\n"
  },
  {
    "path": "axum-macros/rust-toolchain",
    "content": "nightly-2025-09-28\n"
  },
  {
    "path": "axum-macros/src/attr_parsing.rs",
    "content": "use quote::ToTokens;\nuse syn::{\n    parse::{Parse, ParseStream},\n    Token,\n};\n\npub(crate) fn parse_parenthesized_attribute<K, T>(\n    input: ParseStream<'_>,\n    out: &mut Option<(K, T)>,\n) -> syn::Result<()>\nwhere\n    K: Parse + ToTokens,\n    T: Parse,\n{\n    let kw = input.parse()?;\n\n    let content;\n    syn::parenthesized!(content in input);\n    let inner = content.parse()?;\n\n    if out.is_some() {\n        let kw_name = std::any::type_name::<K>().split(\"::\").last().unwrap();\n        let msg = format!(\"`{kw_name}` specified more than once\");\n        return Err(syn::Error::new_spanned(kw, msg));\n    }\n\n    *out = Some((kw, inner));\n\n    Ok(())\n}\n\npub(crate) fn parse_assignment_attribute<K, T>(\n    input: ParseStream<'_>,\n    out: &mut Option<(K, T)>,\n) -> syn::Result<()>\nwhere\n    K: Parse + ToTokens,\n    T: Parse,\n{\n    let kw = input.parse()?;\n    input.parse::<Token![=]>()?;\n    let inner = input.parse()?;\n\n    if out.is_some() {\n        let kw_name = std::any::type_name::<K>().split(\"::\").last().unwrap();\n        let msg = format!(\"`{kw_name}` specified more than once\");\n        return Err(syn::Error::new_spanned(kw, msg));\n    }\n\n    *out = Some((kw, inner));\n\n    Ok(())\n}\n\npub(crate) trait Combine: Sized {\n    fn combine(self, other: Self) -> syn::Result<Self>;\n}\n\npub(crate) fn parse_attrs<T>(ident: &str, attrs: &[syn::Attribute]) -> syn::Result<T>\nwhere\n    T: Combine + Default + Parse,\n{\n    attrs\n        .iter()\n        .filter(|attr| attr.meta.path().is_ident(ident))\n        .map(|attr| attr.parse_args::<T>())\n        .try_fold(T::default(), |out, next| out.combine(next?))\n}\n\npub(crate) fn combine_attribute<K, T>(a: &mut Option<(K, T)>, b: Option<(K, T)>) -> syn::Result<()>\nwhere\n    K: ToTokens,\n{\n    if let Some((kw, inner)) = b {\n        if a.is_some() {\n            let kw_name = std::any::type_name::<K>().split(\"::\").last().unwrap();\n            let msg = format!(\"`{kw_name}` specified more than once\");\n            return Err(syn::Error::new_spanned(kw, msg));\n        }\n        *a = Some((kw, inner));\n    }\n    Ok(())\n}\n\npub(crate) fn combine_unary_attribute<K>(a: &mut Option<K>, b: Option<K>) -> syn::Result<()>\nwhere\n    K: ToTokens,\n{\n    if let Some(kw) = b {\n        if a.is_some() {\n            let kw_name = std::any::type_name::<K>().split(\"::\").last().unwrap();\n            let msg = format!(\"`{kw_name}` specified more than once\");\n            return Err(syn::Error::new_spanned(kw, msg));\n        }\n        *a = Some(kw);\n    }\n    Ok(())\n}\n\npub(crate) fn second<T, K>(tuple: (T, K)) -> K {\n    tuple.1\n}\n"
  },
  {
    "path": "axum-macros/src/axum_test.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::{format_ident, quote};\nuse syn::{parse::Parse, parse_quote, visit_mut::VisitMut, ItemFn};\n\npub(crate) fn expand(_attr: Attrs, mut item_fn: ItemFn) -> TokenStream {\n    item_fn.attrs.push(parse_quote!(#[tokio::test]));\n\n    let nest_service_fn = replace_nest_with_nest_service(item_fn.clone());\n\n    quote! {\n        #item_fn\n        #nest_service_fn\n    }\n}\n\npub(crate) struct Attrs;\n\nimpl Parse for Attrs {\n    fn parse(_input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {\n        Ok(Self)\n    }\n}\n\nfn replace_nest_with_nest_service(mut item_fn: ItemFn) -> Option<ItemFn> {\n    item_fn.sig.ident = format_ident!(\"{}_with_nest_service\", item_fn.sig.ident);\n\n    let mut visitor = NestToNestService::default();\n    syn::visit_mut::visit_item_fn_mut(&mut visitor, &mut item_fn);\n\n    (visitor.count > 0).then_some(item_fn)\n}\n\n#[derive(Default)]\nstruct NestToNestService {\n    count: usize,\n}\n\nimpl VisitMut for NestToNestService {\n    fn visit_expr_method_call_mut(&mut self, i: &mut syn::ExprMethodCall) {\n        if i.method == \"nest\" && i.args.len() == 2 {\n            i.method = parse_quote!(nest_service);\n            self.count += 1;\n        }\n    }\n}\n"
  },
  {
    "path": "axum-macros/src/debug_handler.rs",
    "content": "use std::{collections::HashSet, fmt};\n\nuse crate::{\n    attr_parsing::{parse_assignment_attribute, second},\n    with_position::{Position, WithPosition},\n};\nuse proc_macro2::{Ident, Span, TokenStream};\nuse quote::{format_ident, quote, quote_spanned};\nuse syn::{parse::Parse, spanned::Spanned, FnArg, ItemFn, ReturnType, Token, Type};\n\npub(crate) fn expand(attr: Attrs, item_fn: &ItemFn, kind: FunctionKind) -> TokenStream {\n    let Attrs { state_ty } = attr;\n\n    let mut state_ty = state_ty.map(second);\n\n    let check_extractor_count = check_extractor_count(item_fn, kind);\n    let check_path_extractor = check_path_extractor(item_fn, kind);\n    let check_output_tuples = check_output_tuples(item_fn);\n    let check_output_impls_into_response = if check_output_tuples.is_empty() {\n        check_output_impls_into_response(item_fn)\n    } else {\n        check_output_tuples\n    };\n\n    // If the function is generic, we can't reliably check its inputs or whether the future it\n    // returns is `Send`. Skip those checks to avoid unhelpful additional compiler errors.\n    let check_inputs_and_future_send = if item_fn.sig.generics.params.is_empty() {\n        let mut err = None;\n\n        if state_ty.is_none() {\n            let state_types_from_args = state_types_from_args(item_fn);\n\n            #[allow(clippy::comparison_chain)]\n            if state_types_from_args.len() == 1 {\n                state_ty = state_types_from_args.into_iter().next();\n            } else if state_types_from_args.len() > 1 {\n                err = Some(\n                    syn::Error::new(\n                        Span::call_site(),\n                        format!(\n                            \"can't infer state type, please add set it explicitly, as in \\\n                            `#[axum_macros::debug_{kind}(state = MyStateType)]`\"\n                        ),\n                    )\n                    .into_compile_error(),\n                );\n            }\n        }\n\n        err.unwrap_or_else(|| {\n            let state_ty = state_ty.unwrap_or_else(|| syn::parse_quote!(()));\n\n            let check_future_send = check_future_send(item_fn, kind);\n\n            if let Some(check_input_order) = check_input_order(item_fn, kind) {\n                quote! {\n                    #check_input_order\n                    #check_future_send\n                }\n            } else {\n                let check_inputs_impls_from_request =\n                    check_inputs_impls_from_request(item_fn, &state_ty, kind);\n\n                quote! {\n                    #check_inputs_impls_from_request\n                    #check_future_send\n                }\n            }\n        })\n    } else {\n        syn::Error::new_spanned(\n            &item_fn.sig.generics,\n            format!(\"`#[axum_macros::debug_{kind}]` doesn't support generic functions\"),\n        )\n        .into_compile_error()\n    };\n\n    let middleware_takes_next_as_last_arg =\n        matches!(kind, FunctionKind::Middleware).then(|| next_is_last_input(item_fn));\n\n    quote! {\n        #item_fn\n        #check_extractor_count\n        #check_path_extractor\n        #check_output_impls_into_response\n        #check_inputs_and_future_send\n        #middleware_takes_next_as_last_arg\n    }\n}\n\n#[derive(Clone, Copy)]\npub(crate) enum FunctionKind {\n    Handler,\n    Middleware,\n}\n\nimpl fmt::Display for FunctionKind {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::Handler => f.write_str(\"handler\"),\n            Self::Middleware => f.write_str(\"middleware\"),\n        }\n    }\n}\n\nimpl FunctionKind {\n    fn name_uppercase_plural(self) -> &'static str {\n        match self {\n            Self::Handler => \"Handlers\",\n            Self::Middleware => \"Middleware\",\n        }\n    }\n}\n\nmod kw {\n    syn::custom_keyword!(body);\n    syn::custom_keyword!(state);\n}\n\npub(crate) struct Attrs {\n    state_ty: Option<(kw::state, Type)>,\n}\n\nimpl Parse for Attrs {\n    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {\n        let mut state_ty = None;\n\n        while !input.is_empty() {\n            let lh = input.lookahead1();\n            if lh.peek(kw::state) {\n                parse_assignment_attribute(input, &mut state_ty)?;\n            } else {\n                return Err(lh.error());\n            }\n\n            let _ = input.parse::<Token![,]>();\n        }\n\n        Ok(Self { state_ty })\n    }\n}\n\nfn check_extractor_count(item_fn: &ItemFn, kind: FunctionKind) -> Option<TokenStream> {\n    let max_extractors = 16;\n    let inputs = item_fn\n        .sig\n        .inputs\n        .iter()\n        .filter(|arg| skip_next_arg(arg, kind))\n        .count();\n    if inputs <= max_extractors {\n        None\n    } else {\n        let error_message = format!(\n            \"{} cannot take more than {max_extractors} arguments. \\\n            Use `(a, b): (ExtractorA, ExtractorA)` to further nest extractors\",\n            kind.name_uppercase_plural(),\n        );\n        let error = syn::Error::new_spanned(&item_fn.sig.inputs, error_message).to_compile_error();\n        Some(error)\n    }\n}\n\nfn extractor_idents(\n    item_fn: &ItemFn,\n    kind: FunctionKind,\n) -> impl Iterator<Item = (usize, &syn::FnArg, &syn::Ident)> {\n    item_fn\n        .sig\n        .inputs\n        .iter()\n        .filter(move |arg| skip_next_arg(arg, kind))\n        .enumerate()\n        .filter_map(|(idx, fn_arg)| match fn_arg {\n            FnArg::Receiver(_) => None,\n            FnArg::Typed(pat_type) => {\n                if let Type::Path(type_path) = &*pat_type.ty {\n                    type_path\n                        .path\n                        .segments\n                        .last()\n                        .map(|segment| (idx, fn_arg, &segment.ident))\n                } else {\n                    None\n                }\n            }\n        })\n}\n\nfn check_path_extractor(item_fn: &ItemFn, kind: FunctionKind) -> TokenStream {\n    let path_extractors = extractor_idents(item_fn, kind)\n        .filter(|(_, _, ident)| *ident == \"Path\")\n        .collect::<Vec<_>>();\n\n    if path_extractors.len() > 1 {\n        path_extractors\n            .into_iter()\n            .map(|(_, arg, _)| {\n                syn::Error::new_spanned(\n                    arg,\n                    \"Multiple parameters must be extracted with a tuple \\\n                    `Path<(_, _)>` or a struct `Path<YourParams>`, not by applying \\\n                    multiple `Path<_>` extractors\",\n                )\n                .to_compile_error()\n            })\n            .collect()\n    } else {\n        quote! {}\n    }\n}\n\nfn is_self_pat_type(typed: &syn::PatType) -> bool {\n    let ident = if let syn::Pat::Ident(ident) = &*typed.pat {\n        &ident.ident\n    } else {\n        return false;\n    };\n\n    ident == \"self\"\n}\n\nfn check_inputs_impls_from_request(\n    item_fn: &ItemFn,\n    state_ty: &Type,\n    kind: FunctionKind,\n) -> TokenStream {\n    let takes_self = item_fn.sig.inputs.first().is_some_and(|arg| match arg {\n        FnArg::Receiver(_) => true,\n        FnArg::Typed(typed) => is_self_pat_type(typed),\n    });\n\n    WithPosition::new(\n        item_fn\n            .sig\n            .inputs\n            .iter()\n            .filter(|arg| skip_next_arg(arg, kind)),\n    )\n    .enumerate()\n    .map(|(idx, arg)| {\n        let must_impl_from_request_parts = match &arg {\n            Position::First(_) | Position::Middle(_) => true,\n            Position::Last(_) | Position::Only(_) => false,\n        };\n\n        let arg = arg.into_inner();\n\n        let (span, ty) = match arg {\n            FnArg::Receiver(receiver) => {\n                if receiver.reference.is_some() {\n                    return syn::Error::new_spanned(\n                        receiver,\n                        \"Handlers must only take owned values\",\n                    )\n                    .into_compile_error();\n                }\n\n                let span = receiver.span();\n                (span, syn::parse_quote!(Self))\n            }\n            FnArg::Typed(typed) => {\n                let ty = &typed.ty;\n                let span = ty.span();\n\n                if is_self_pat_type(typed) {\n                    (span, syn::parse_quote!(Self))\n                } else {\n                    (span, ty.clone())\n                }\n            }\n        };\n\n        let consumes_request = request_consuming_type_name(&ty).is_some();\n\n        let check_fn = format_ident!(\n            \"__axum_macros_check_{}_{}_from_request_check\",\n            item_fn.sig.ident,\n            idx,\n            span = span,\n        );\n\n        let call_check_fn = format_ident!(\n            \"__axum_macros_check_{}_{}_from_request_call_check\",\n            item_fn.sig.ident,\n            idx,\n            span = span,\n        );\n\n        let call_check_fn_body = if takes_self {\n            quote_spanned! {span=>\n                Self::#check_fn();\n            }\n        } else {\n            quote_spanned! {span=>\n                #check_fn();\n            }\n        };\n\n        let check_fn_generics = if must_impl_from_request_parts || consumes_request {\n            quote! {}\n        } else {\n            quote! { <M> }\n        };\n\n        let from_request_bound = if must_impl_from_request_parts {\n            quote_spanned! {span=>\n                #ty: ::axum::extract::FromRequestParts<#state_ty> + Send\n            }\n        } else if consumes_request {\n            quote_spanned! {span=>\n                #ty: ::axum::extract::FromRequest<#state_ty> + Send\n            }\n        } else {\n            quote_spanned! {span=>\n                #ty: ::axum::extract::FromRequest<#state_ty, M> + Send\n            }\n        };\n\n        quote_spanned! {span=>\n            #[allow(warnings)]\n            #[doc(hidden)]\n            fn #check_fn #check_fn_generics()\n            where\n                #from_request_bound,\n            {}\n\n            // we have to call the function to actually trigger a compile error\n            // since the function is generic, just defining it is not enough\n            #[allow(warnings)]\n            #[doc(hidden)]\n            fn #call_check_fn()\n            {\n                #call_check_fn_body\n            }\n        }\n    })\n    .collect::<TokenStream>()\n}\n\nfn check_output_tuples(item_fn: &ItemFn) -> TokenStream {\n    let elems = match &item_fn.sig.output {\n        ReturnType::Type(_, ty) => match &**ty {\n            Type::Tuple(tuple) => &tuple.elems,\n            _ => return quote! {},\n        },\n        ReturnType::Default => return quote! {},\n    };\n\n    let handler_ident = &item_fn.sig.ident;\n\n    match elems.len() {\n        0 => quote! {},\n        n if n > 17 => syn::Error::new_spanned(\n            &item_fn.sig.output,\n            \"Cannot return tuples with more than 17 elements\",\n        )\n        .to_compile_error(),\n        _ => WithPosition::new(elems)\n            .enumerate()\n            .map(|(idx, arg)| match arg {\n                Position::First(ty) => match extract_clean_typename(ty).as_deref() {\n                    Some(\"StatusCode\" | \"Response\") => quote! {},\n                    Some(\"Parts\") => check_is_response_parts(ty, handler_ident, idx),\n                    Some(_) | None => {\n                        if let Some(tn) = well_known_last_response_type(ty) {\n                            syn::Error::new_spanned(\n                                ty,\n                                format!(\n                                    \"`{tn}` must be the last element \\\n                                    in a response tuple\"\n                                ),\n                            )\n                            .to_compile_error()\n                        } else {\n                            check_into_response_parts(ty, handler_ident, idx)\n                        }\n                    }\n                },\n                Position::Middle(ty) => {\n                    if let Some(tn) = well_known_last_response_type(ty) {\n                        syn::Error::new_spanned(\n                            ty,\n                            format!(\"`{tn}` must be the last element in a response tuple\"),\n                        )\n                        .to_compile_error()\n                    } else {\n                        check_into_response_parts(ty, handler_ident, idx)\n                    }\n                }\n                Position::Last(ty) | Position::Only(ty) => check_into_response(handler_ident, ty),\n            })\n            .collect::<TokenStream>(),\n    }\n}\n\nfn check_into_response(handler: &Ident, ty: &Type) -> TokenStream {\n    let (span, ty) = (ty.span(), ty.clone());\n\n    let check_fn = format_ident!(\n        \"__axum_macros_check_{handler}_into_response_check\",\n        span = span,\n    );\n\n    let call_check_fn = format_ident!(\n        \"__axum_macros_check_{handler}_into_response_call_check\",\n        span = span,\n    );\n\n    let call_check_fn_body = quote_spanned! {span=>\n        #check_fn();\n    };\n\n    let from_request_bound = quote_spanned! {span=>\n        #ty: ::axum::response::IntoResponse\n    };\n    quote_spanned! {span=>\n        #[allow(warnings)]\n        #[allow(unreachable_code)]\n        #[doc(hidden)]\n        fn #check_fn()\n        where\n            #from_request_bound,\n        {}\n\n        // we have to call the function to actually trigger a compile error\n        // since the function is generic, just defining it is not enough\n        #[allow(warnings)]\n        #[allow(unreachable_code)]\n        #[doc(hidden)]\n        fn #call_check_fn() {\n            #call_check_fn_body\n        }\n    }\n}\n\nfn check_is_response_parts(ty: &Type, ident: &Ident, index: usize) -> TokenStream {\n    let (span, ty) = (ty.span(), ty.clone());\n\n    let check_fn = format_ident!(\n        \"__axum_macros_check_{}_is_response_parts_{index}_check\",\n        ident,\n        span = span,\n    );\n\n    quote_spanned! {span=>\n        #[allow(warnings)]\n        #[allow(unreachable_code)]\n        #[doc(hidden)]\n        fn #check_fn(parts: #ty) -> ::axum::http::response::Parts {\n            parts\n        }\n    }\n}\n\nfn check_into_response_parts(ty: &Type, ident: &Ident, index: usize) -> TokenStream {\n    let (span, ty) = (ty.span(), ty.clone());\n\n    let check_fn = format_ident!(\n        \"__axum_macros_check_{}_into_response_parts_{index}_check\",\n        ident,\n        span = span,\n    );\n\n    let call_check_fn = format_ident!(\n        \"__axum_macros_check_{}_into_response_parts_{index}_call_check\",\n        ident,\n        span = span,\n    );\n\n    let call_check_fn_body = quote_spanned! {span=>\n        #check_fn();\n    };\n\n    let from_request_bound = quote_spanned! {span=>\n        #ty: ::axum::response::IntoResponseParts\n    };\n    quote_spanned! {span=>\n        #[allow(warnings)]\n        #[allow(unreachable_code)]\n        #[doc(hidden)]\n        fn #check_fn()\n        where\n            #from_request_bound,\n        {}\n\n        // we have to call the function to actually trigger a compile error\n        // since the function is generic, just defining it is not enough\n        #[allow(warnings)]\n        #[allow(unreachable_code)]\n        #[doc(hidden)]\n        fn #call_check_fn() {\n            #call_check_fn_body\n        }\n    }\n}\n\nfn check_input_order(item_fn: &ItemFn, kind: FunctionKind) -> Option<TokenStream> {\n    let number_of_inputs = item_fn\n        .sig\n        .inputs\n        .iter()\n        .filter(|arg| skip_next_arg(arg, kind))\n        .count();\n\n    let types_that_consume_the_request = item_fn\n        .sig\n        .inputs\n        .iter()\n        .filter(|arg| skip_next_arg(arg, kind))\n        .enumerate()\n        .filter_map(|(idx, arg)| {\n            let ty = match arg {\n                FnArg::Typed(pat_type) => &*pat_type.ty,\n                FnArg::Receiver(_) => return None,\n            };\n            let type_name = request_consuming_type_name(ty)?;\n\n            Some((idx, type_name, ty.span()))\n        })\n        .collect::<Vec<_>>();\n\n    if types_that_consume_the_request.is_empty() {\n        return None;\n    };\n\n    // exactly one type that consumes the request\n    if types_that_consume_the_request.len() == 1 {\n        // and that is not the last\n        if types_that_consume_the_request[0].0 != number_of_inputs - 1 {\n            let (_idx, type_name, span) = &types_that_consume_the_request[0];\n            let error = format!(\n                \"`{type_name}` consumes the request body and thus must be \\\n                the last argument to the handler function\"\n            );\n            return Some(quote_spanned! {*span=>\n                compile_error!(#error);\n            });\n        } else {\n            return None;\n        }\n    }\n\n    if types_that_consume_the_request.len() == 2 {\n        let (_, first, _) = &types_that_consume_the_request[0];\n        let (_, second, _) = &types_that_consume_the_request[1];\n        let error = format!(\n            \"Can't have two extractors that consume the request body. \\\n            `{first}` and `{second}` both do that.\",\n        );\n        let span = item_fn.sig.inputs.span();\n        Some(quote_spanned! {span=>\n            compile_error!(#error);\n        })\n    } else {\n        let types = WithPosition::new(types_that_consume_the_request)\n            .map(|pos| match pos {\n                Position::First((_, type_name, _)) | Position::Middle((_, type_name, _)) => {\n                    format!(\"`{type_name}`, \")\n                }\n                Position::Last((_, type_name, _)) => format!(\"and `{type_name}`\"),\n                Position::Only(_) => unreachable!(),\n            })\n            .collect::<String>();\n\n        let error = format!(\n            \"Can't have more than one extractor that consume the request body. \\\n            {types} all do that.\",\n        );\n        let span = item_fn.sig.inputs.span();\n        Some(quote_spanned! {span=>\n            compile_error!(#error);\n        })\n    }\n}\n\nfn extract_clean_typename(ty: &Type) -> Option<String> {\n    let path = match ty {\n        Type::Path(type_path) => &type_path.path,\n        _ => return None,\n    };\n    path.segments.last().map(|p| p.ident.to_string())\n}\n\nfn request_consuming_type_name(ty: &Type) -> Option<&'static str> {\n    let typename = extract_clean_typename(ty)?;\n\n    let type_name = match &*typename {\n        \"Json\" => \"Json<_>\",\n        \"RawBody\" => \"RawBody<_>\",\n        \"RawForm\" => \"RawForm\",\n        \"Multipart\" => \"Multipart\",\n        \"Protobuf\" => \"Protobuf\",\n        \"JsonLines\" => \"JsonLines<_>\",\n        \"Form\" => \"Form<_>\",\n        \"Request\" => \"Request<_>\",\n        \"Bytes\" => \"Bytes\",\n        \"String\" => \"String\",\n        \"Parts\" => \"Parts\",\n        _ => return None,\n    };\n\n    Some(type_name)\n}\n\nfn well_known_last_response_type(ty: &Type) -> Option<&'static str> {\n    let typename = extract_clean_typename(ty)?;\n\n    let type_name = match &*typename {\n        \"Json\" => \"Json<_>\",\n        \"Protobuf\" => \"Protobuf\",\n        \"JsonLines\" => \"JsonLines<_>\",\n        \"Form\" => \"Form<_>\",\n        \"Bytes\" => \"Bytes\",\n        \"String\" => \"String\",\n        _ => return None,\n    };\n\n    Some(type_name)\n}\n\nfn check_output_impls_into_response(item_fn: &ItemFn) -> TokenStream {\n    let ty = match &item_fn.sig.output {\n        syn::ReturnType::Default => return quote! {},\n        syn::ReturnType::Type(_, ty) => ty,\n    };\n    let span = ty.span();\n\n    let declare_inputs = item_fn\n        .sig\n        .inputs\n        .iter()\n        .filter_map(|arg| match arg {\n            FnArg::Receiver(_) => None,\n            FnArg::Typed(pat_ty) => {\n                let pat = &pat_ty.pat;\n                let ty = &pat_ty.ty;\n                Some(quote! {\n                    let #pat: #ty = panic!();\n                })\n            }\n        })\n        .collect::<TokenStream>();\n\n    let block = &item_fn.block;\n\n    let make_value_name = format_ident!(\n        \"__axum_macros_check_{}_into_response_make_value\",\n        item_fn.sig.ident\n    );\n\n    let make = if item_fn.sig.asyncness.is_some() {\n        quote_spanned! {span=>\n            #[allow(warnings)]\n            #[allow(unreachable_code)]\n            #[doc(hidden)]\n            async fn #make_value_name() -> #ty {\n                #declare_inputs\n                #block\n            }\n        }\n    } else {\n        quote_spanned! {span=>\n            #[allow(warnings)]\n            #[allow(unreachable_code)]\n            #[doc(hidden)]\n            fn #make_value_name() -> #ty {\n                #declare_inputs\n                #block\n            }\n        }\n    };\n\n    let name = format_ident!(\"__axum_macros_check_{}_into_response\", item_fn.sig.ident);\n\n    if let Some(receiver) = self_receiver(item_fn) {\n        quote_spanned! {span=>\n            #make\n\n            #[allow(warnings)]\n            #[allow(unreachable_code)]\n            #[doc(hidden)]\n            async fn #name() {\n                fn check<T>(_: T)\n                    where T: ::axum::response::IntoResponse\n                {}\n                let value = #receiver #make_value_name().await;\n                check(value);\n            }\n        }\n    } else {\n        quote_spanned! {span=>\n            #[allow(warnings)]\n            #[allow(unreachable_code)]\n            #[doc(hidden)]\n            async fn #name() {\n                #make\n\n                fn check<T>(_: T)\n                where T: ::axum::response::IntoResponse\n                {}\n\n                let value = #make_value_name().await;\n\n                check(value);\n            }\n        }\n    }\n}\n\nfn check_future_send(item_fn: &ItemFn, kind: FunctionKind) -> TokenStream {\n    if item_fn.sig.asyncness.is_none() {\n        match &item_fn.sig.output {\n            syn::ReturnType::Default => {\n                return syn::Error::new_spanned(\n                    item_fn.sig.fn_token,\n                    format!(\"{} must be `async fn`s\", kind.name_uppercase_plural()),\n                )\n                .into_compile_error();\n            }\n            syn::ReturnType::Type(_, ty) => ty,\n        };\n    }\n\n    let span = item_fn.sig.ident.span();\n\n    let handler_name = &item_fn.sig.ident;\n\n    let args = item_fn.sig.inputs.iter().map(|_| {\n        quote_spanned! {span=> panic!() }\n    });\n\n    let name = format_ident!(\"__axum_macros_check_{}_future\", item_fn.sig.ident);\n\n    let define_check = quote! {\n        fn check<T>(_: T)\n            where T: ::std::future::Future + Send\n        {}\n    };\n\n    let do_check = quote! {\n        check(future);\n    };\n\n    if let Some(receiver) = self_receiver(item_fn) {\n        quote! {\n            #[allow(warnings)]\n            #[allow(unreachable_code)]\n            #[doc(hidden)]\n            fn #name() {\n                #define_check\n                let future = #receiver #handler_name(#(#args),*);\n                #do_check\n            }\n        }\n    } else {\n        quote! {\n            #[allow(warnings)]\n            #[allow(unreachable_code)]\n            #[doc(hidden)]\n            fn #name() {\n                #item_fn\n                #define_check\n                let future = #handler_name(#(#args),*);\n                #do_check\n            }\n        }\n    }\n}\n\nfn self_receiver(item_fn: &ItemFn) -> Option<TokenStream> {\n    let takes_self = item_fn.sig.inputs.iter().any(|arg| match arg {\n        FnArg::Receiver(_) => true,\n        FnArg::Typed(typed) => is_self_pat_type(typed),\n    });\n\n    if takes_self {\n        return Some(quote! { Self:: });\n    }\n\n    if let syn::ReturnType::Type(_, ty) = &item_fn.sig.output {\n        if let syn::Type::Path(path) = &**ty {\n            let segments = &path.path.segments;\n            if segments.len() == 1 {\n                if let Some(last) = segments.last() {\n                    match &last.arguments {\n                        syn::PathArguments::None if last.ident == \"Self\" => {\n                            return Some(quote! { Self:: });\n                        }\n                        _ => {}\n                    }\n                }\n            }\n        }\n    }\n\n    None\n}\n\n/// Given a signature like\n///\n/// ```skip\n/// #[debug_handler]\n/// async fn handler(\n///     _: axum::extract::State<AppState>,\n///     _: State<AppState>,\n/// ) {}\n/// ```\n///\n/// This will extract `AppState`.\n///\n/// Returns `None` if there are no `State` args or multiple of different types.\nfn state_types_from_args(item_fn: &ItemFn) -> HashSet<Type> {\n    let types = item_fn\n        .sig\n        .inputs\n        .iter()\n        .filter_map(|input| match input {\n            FnArg::Receiver(_) => None,\n            FnArg::Typed(pat_type) => Some(pat_type),\n        })\n        .map(|pat_type| &*pat_type.ty);\n    crate::infer_state_types(types).collect()\n}\n\nfn next_is_last_input(item_fn: &ItemFn) -> TokenStream {\n    let next_args = item_fn\n        .sig\n        .inputs\n        .iter()\n        .enumerate()\n        .filter(|(_, arg)| !skip_next_arg(arg, FunctionKind::Middleware))\n        .collect::<Vec<_>>();\n\n    if next_args.is_empty() {\n        return quote! {\n            compile_error!(\n                \"Middleware functions must take `axum::middleware::Next` as the last argument\",\n            );\n        };\n    }\n\n    if next_args.len() == 1 {\n        let (idx, arg) = &next_args[0];\n        if *idx != item_fn.sig.inputs.len() - 1 {\n            return quote_spanned! {arg.span()=>\n                compile_error!(\"`axum::middleware::Next` must the last argument\");\n            };\n        }\n    }\n\n    if next_args.len() >= 2 {\n        return quote! {\n            compile_error!(\n                \"Middleware functions can only take one argument of type `axum::middleware::Next`\",\n            );\n        };\n    }\n\n    quote! {}\n}\n\nfn skip_next_arg(arg: &FnArg, kind: FunctionKind) -> bool {\n    match kind {\n        FunctionKind::Handler => true,\n        FunctionKind::Middleware => match arg {\n            FnArg::Receiver(_) => true,\n            FnArg::Typed(pat_type) => {\n                if let Type::Path(type_path) = &*pat_type.ty {\n                    type_path\n                        .path\n                        .segments\n                        .last()\n                        .map_or(true, |path_segment| path_segment.ident != \"Next\")\n                } else {\n                    true\n                }\n            }\n        },\n    }\n}\n\n#[test]\nfn ui_debug_handler() {\n    crate::run_ui_tests(\"debug_handler\");\n}\n\n#[test]\nfn ui_debug_middleware() {\n    crate::run_ui_tests(\"debug_middleware\");\n}\n"
  },
  {
    "path": "axum-macros/src/from_ref.rs",
    "content": "use proc_macro2::{Ident, TokenStream};\nuse quote::quote_spanned;\nuse syn::{\n    parse::{Parse, ParseStream},\n    spanned::Spanned,\n    Field, ItemStruct, Token, Type,\n};\n\nuse crate::attr_parsing::{combine_unary_attribute, parse_attrs, Combine};\n\npub(crate) fn expand(item: ItemStruct) -> syn::Result<TokenStream> {\n    if !item.generics.params.is_empty() {\n        return Err(syn::Error::new_spanned(\n            item.generics,\n            \"`#[derive(FromRef)]` doesn't support generics\",\n        ));\n    }\n\n    let tokens = item\n        .fields\n        .iter()\n        .enumerate()\n        .map(|(idx, field)| expand_field(&item.ident, idx, field))\n        .collect();\n\n    Ok(tokens)\n}\n\nfn expand_field(state: &Ident, idx: usize, field: &Field) -> TokenStream {\n    let FieldAttrs { skip } = match parse_attrs(\"from_ref\", &field.attrs) {\n        Ok(attrs) => attrs,\n        Err(err) => return err.into_compile_error(),\n    };\n\n    if skip.is_some() {\n        return TokenStream::default();\n    }\n\n    let field_ty = &field.ty;\n    let span = field.ty.span();\n\n    let body = if let Some(field_ident) = &field.ident {\n        if matches!(field_ty, Type::Reference(_)) {\n            quote_spanned! {span=> state.#field_ident }\n        } else {\n            quote_spanned! {span=> state.#field_ident.clone() }\n        }\n    } else {\n        let idx = syn::Index {\n            index: idx as _,\n            span: field.span(),\n        };\n        quote_spanned! {span=> state.#idx.clone() }\n    };\n\n    quote_spanned! {span=>\n        #[allow(clippy::clone_on_copy, clippy::clone_on_ref_ptr)]\n        impl ::axum::extract::FromRef<#state> for #field_ty {\n            fn from_ref(state: &#state) -> Self {\n                #body\n            }\n        }\n    }\n}\n\nmod kw {\n    syn::custom_keyword!(skip);\n}\n\n#[derive(Default)]\npub(super) struct FieldAttrs {\n    pub(super) skip: Option<kw::skip>,\n}\n\nimpl Parse for FieldAttrs {\n    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {\n        let mut skip = None;\n\n        while !input.is_empty() {\n            let lh = input.lookahead1();\n            if lh.peek(kw::skip) {\n                skip = Some(input.parse()?);\n            } else {\n                return Err(lh.error());\n            }\n\n            let _ = input.parse::<Token![,]>();\n        }\n\n        Ok(Self { skip })\n    }\n}\n\nimpl Combine for FieldAttrs {\n    fn combine(mut self, other: Self) -> syn::Result<Self> {\n        let Self { skip } = other;\n        combine_unary_attribute(&mut self.skip, skip)?;\n        Ok(self)\n    }\n}\n\n#[test]\nfn ui() {\n    crate::run_ui_tests(\"from_ref\");\n}\n"
  },
  {
    "path": "axum-macros/src/from_request/attr.rs",
    "content": "use crate::attr_parsing::{combine_attribute, parse_parenthesized_attribute, Combine};\nuse syn::{\n    parse::{Parse, ParseStream},\n    Token,\n};\n\npub(crate) mod kw {\n    syn::custom_keyword!(via);\n    syn::custom_keyword!(rejection);\n    syn::custom_keyword!(state);\n}\n\n#[derive(Default)]\npub(super) struct FromRequestContainerAttrs {\n    pub(super) via: Option<(kw::via, syn::Path)>,\n    pub(super) rejection: Option<(kw::rejection, syn::Path)>,\n    pub(super) state: Option<(kw::state, syn::Type)>,\n}\n\nimpl Parse for FromRequestContainerAttrs {\n    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {\n        let mut via = None;\n        let mut rejection = None;\n        let mut state = None;\n\n        while !input.is_empty() {\n            let lh = input.lookahead1();\n            if lh.peek(kw::via) {\n                parse_parenthesized_attribute(input, &mut via)?;\n            } else if lh.peek(kw::rejection) {\n                parse_parenthesized_attribute(input, &mut rejection)?;\n            } else if lh.peek(kw::state) {\n                parse_parenthesized_attribute(input, &mut state)?;\n            } else {\n                return Err(lh.error());\n            }\n\n            let _ = input.parse::<Token![,]>();\n        }\n\n        Ok(Self {\n            via,\n            rejection,\n            state,\n        })\n    }\n}\n\nimpl Combine for FromRequestContainerAttrs {\n    fn combine(mut self, other: Self) -> syn::Result<Self> {\n        let Self {\n            via,\n            rejection,\n            state,\n        } = other;\n        combine_attribute(&mut self.via, via)?;\n        combine_attribute(&mut self.rejection, rejection)?;\n        combine_attribute(&mut self.state, state)?;\n        Ok(self)\n    }\n}\n\n#[derive(Default)]\npub(super) struct FromRequestFieldAttrs {\n    pub(super) via: Option<(kw::via, syn::Path)>,\n}\n\nimpl Parse for FromRequestFieldAttrs {\n    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {\n        let mut via = None;\n\n        while !input.is_empty() {\n            let lh = input.lookahead1();\n            if lh.peek(kw::via) {\n                parse_parenthesized_attribute(input, &mut via)?;\n            } else {\n                return Err(lh.error());\n            }\n\n            let _ = input.parse::<Token![,]>();\n        }\n\n        Ok(Self { via })\n    }\n}\n\nimpl Combine for FromRequestFieldAttrs {\n    fn combine(mut self, other: Self) -> syn::Result<Self> {\n        let Self { via } = other;\n        combine_attribute(&mut self.via, via)?;\n        Ok(self)\n    }\n}\n"
  },
  {
    "path": "axum-macros/src/from_request/mod.rs",
    "content": "use self::attr::FromRequestContainerAttrs;\nuse crate::{\n    attr_parsing::{parse_attrs, second},\n    from_request::attr::FromRequestFieldAttrs,\n};\nuse proc_macro2::{Span, TokenStream};\nuse quote::{quote, quote_spanned, ToTokens};\nuse std::{collections::HashSet, fmt, iter};\nuse syn::{\n    parse_quote, punctuated::Punctuated, spanned::Spanned, Fields, Ident, Path, Token, Type,\n};\n\nmod attr;\n\n#[derive(Clone, Copy)]\npub(crate) enum Trait {\n    FromRequest,\n    FromRequestParts,\n}\n\nimpl Trait {\n    fn via_marker_type(self) -> Option<Type> {\n        match self {\n            Self::FromRequest => Some(parse_quote!(M)),\n            Self::FromRequestParts => None,\n        }\n    }\n}\n\nimpl fmt::Display for Trait {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::FromRequest => f.write_str(\"FromRequest\"),\n            Self::FromRequestParts => f.write_str(\"FromRequestParts\"),\n        }\n    }\n}\n\n#[derive(Debug)]\nenum State {\n    Custom(syn::Type),\n    Default(syn::Type),\n    CannotInfer,\n}\n\nimpl State {\n    /// ```not_rust\n    /// impl<T> A for B {}\n    ///      ^ this type\n    /// ```\n    fn impl_generics(&self) -> impl Iterator<Item = Type> {\n        match self {\n            Self::Default(inner) => Some(inner.clone()),\n            Self::Custom(_) => None,\n            Self::CannotInfer => Some(parse_quote!(S)),\n        }\n        .into_iter()\n    }\n\n    /// ```not_rust\n    /// impl<T> A<T> for B {}\n    ///           ^ this type\n    /// ```\n    fn trait_generics(&self) -> impl Iterator<Item = Type> {\n        match self {\n            Self::Default(inner) | Self::Custom(inner) => iter::once(inner.clone()),\n            Self::CannotInfer => iter::once(parse_quote!(S)),\n        }\n    }\n\n    fn bounds(&self) -> TokenStream {\n        match self {\n            Self::Custom(_) => quote! {},\n            Self::Default(inner) => quote! {\n                #inner: ::std::marker::Send + ::std::marker::Sync,\n            },\n            Self::CannotInfer => quote! {\n                S: ::std::marker::Send + ::std::marker::Sync,\n            },\n        }\n    }\n}\n\nimpl ToTokens for State {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        match self {\n            Self::Custom(inner) | Self::Default(inner) => inner.to_tokens(tokens),\n            Self::CannotInfer => quote! { S }.to_tokens(tokens),\n        }\n    }\n}\n\npub(crate) fn expand(item: syn::Item, tr: Trait) -> syn::Result<TokenStream> {\n    match item {\n        syn::Item::Struct(item) => {\n            let syn::ItemStruct {\n                attrs,\n                ident,\n                generics,\n                fields,\n                semi_token: _,\n                vis: _,\n                struct_token: _,\n            } = item;\n\n            let generic_ident = parse_single_generic_type_on_struct(generics, &fields, tr)?;\n\n            let FromRequestContainerAttrs {\n                via,\n                rejection,\n                state,\n            } = parse_attrs(\"from_request\", &attrs)?;\n\n            let state = if let Some((_, state)) = state {\n                State::Custom(state)\n            } else {\n                let mut inferred_state_types: HashSet<_> =\n                    infer_state_type_from_field_types(&fields)\n                        .chain(infer_state_type_from_field_attributes(&fields))\n                        .collect();\n\n                if let Some((_, via)) = &via {\n                    inferred_state_types.extend(state_from_via(&ident, via));\n                }\n\n                match inferred_state_types.len() {\n                    0 => State::Default(syn::parse_quote!(S)),\n                    1 => State::Custom(inferred_state_types.iter().next().unwrap().to_owned()),\n                    _ => State::CannotInfer,\n                }\n            };\n\n            let trait_impl = match (via.map(second), rejection.map(second)) {\n                (Some(via), rejection) => impl_struct_by_extracting_all_at_once(\n                    &ident,\n                    fields,\n                    &via,\n                    rejection.as_ref(),\n                    generic_ident.as_ref(),\n                    &state,\n                    tr,\n                )?,\n                (None, rejection) => {\n                    error_on_generic_ident(generic_ident, tr)?;\n                    impl_struct_by_extracting_each_field(&ident, &fields, rejection, &state, tr)?\n                }\n            };\n\n            if matches!(state, State::CannotInfer) {\n                let attr_name = match tr {\n                    Trait::FromRequest => \"from_request\",\n                    Trait::FromRequestParts => \"from_request_parts\",\n                };\n                let compile_error = syn::Error::new(\n                    Span::call_site(),\n                    format_args!(\n                        \"can't infer state type, please add \\\n                         `#[{attr_name}(state = MyStateType)]` attribute\",\n                    ),\n                )\n                .into_compile_error();\n\n                Ok(quote! {\n                    #trait_impl\n                    #compile_error\n                })\n            } else {\n                Ok(trait_impl)\n            }\n        }\n        syn::Item::Enum(item) => {\n            let syn::ItemEnum {\n                attrs,\n                vis: _,\n                enum_token: _,\n                ident,\n                generics,\n                brace_token: _,\n                variants,\n            } = item;\n\n            let generics_error = format!(\"`#[derive({tr})]` on enums don't support generics\");\n\n            if !generics.params.is_empty() {\n                return Err(syn::Error::new_spanned(generics, generics_error));\n            }\n\n            if let Some(where_clause) = generics.where_clause {\n                return Err(syn::Error::new_spanned(where_clause, generics_error));\n            }\n\n            let FromRequestContainerAttrs {\n                via,\n                rejection,\n                state,\n            } = parse_attrs(\"from_request\", &attrs)?;\n\n            let state = match state {\n                Some((_, state)) => State::Custom(state),\n                None => (|| {\n                    let via = via.as_ref().map(|(_, via)| via)?;\n                    state_from_via(&ident, via).map(State::Custom)\n                })()\n                .unwrap_or_else(|| State::Default(syn::parse_quote!(S))),\n            };\n\n            match (via.map(second), rejection) {\n                (Some(via), rejection) => impl_enum_by_extracting_all_at_once(\n                    &ident,\n                    variants,\n                    &via,\n                    rejection.map(second).as_ref(),\n                    &state,\n                    tr,\n                ),\n                (None, Some((rejection_kw, _))) => Err(syn::Error::new_spanned(\n                    rejection_kw,\n                    \"cannot use `rejection` without `via`\",\n                )),\n                (None, _) => Err(syn::Error::new(\n                    Span::call_site(),\n                    \"missing `#[from_request(via(...))]`\",\n                )),\n            }\n        }\n        _ => Err(syn::Error::new_spanned(item, \"expected `struct` or `enum`\")),\n    }\n}\n\nfn parse_single_generic_type_on_struct(\n    generics: syn::Generics,\n    fields: &syn::Fields,\n    tr: Trait,\n) -> syn::Result<Option<Ident>> {\n    if let Some(where_clause) = generics.where_clause {\n        return Err(syn::Error::new_spanned(\n            where_clause,\n            format_args!(\"#[derive({tr})] doesn't support structs with `where` clauses\"),\n        ));\n    }\n\n    match generics.params.len() {\n        0 => Ok(None),\n        1 => {\n            let param = generics.params.first().unwrap();\n            let ty_ident = match param {\n                syn::GenericParam::Type(ty) => &ty.ident,\n                syn::GenericParam::Lifetime(lifetime) => {\n                    return Err(syn::Error::new_spanned(\n                        lifetime,\n                        format_args!(\n                            \"#[derive({tr})] doesn't support structs \\\n                             that are generic over lifetimes\"\n                        ),\n                    ));\n                }\n                syn::GenericParam::Const(konst) => {\n                    return Err(syn::Error::new_spanned(\n                        konst,\n                        format_args!(\n                            \"#[derive({tr})] doesn't support structs \\\n                             that have const generics\"\n                        ),\n                    ));\n                }\n            };\n\n            match fields {\n                syn::Fields::Named(fields_named) => {\n                    return Err(syn::Error::new_spanned(\n                        fields_named,\n                        format_args!(\n                            \"#[derive({tr})] doesn't support named fields \\\n                             for generic structs. Use a tuple struct instead\"\n                        ),\n                    ));\n                }\n                syn::Fields::Unnamed(fields_unnamed) => {\n                    if fields_unnamed.unnamed.len() != 1 {\n                        return Err(syn::Error::new_spanned(\n                            fields_unnamed,\n                            format_args!(\n                                \"#[derive({tr})] only supports generics on \\\n                                 tuple structs that have exactly one field\"\n                            ),\n                        ));\n                    }\n\n                    let field = fields_unnamed.unnamed.first().unwrap();\n\n                    if let syn::Type::Path(type_path) = &field.ty {\n                        if type_path.path.get_ident() != Some(ty_ident) {\n                            return Err(syn::Error::new_spanned(\n                                type_path,\n                                format_args!(\n                                    \"#[derive({tr})] only supports generics on \\\n                                     tuple structs that have exactly one field of the generic type\"\n                                ),\n                            ));\n                        }\n                    } else {\n                        return Err(syn::Error::new_spanned(&field.ty, \"Expected type path\"));\n                    }\n                }\n                syn::Fields::Unit => return Ok(None),\n            }\n\n            Ok(Some(ty_ident.clone()))\n        }\n        _ => Err(syn::Error::new_spanned(\n            generics,\n            format_args!(\"#[derive({tr})] only supports 0 or 1 generic type parameters\"),\n        )),\n    }\n}\n\nfn error_on_generic_ident(generic_ident: Option<Ident>, tr: Trait) -> syn::Result<()> {\n    if let Some(generic_ident) = generic_ident {\n        Err(syn::Error::new_spanned(\n            generic_ident,\n            format_args!(\n                \"#[derive({tr})] only supports generics when used with #[from_request(via)]\"\n            ),\n        ))\n    } else {\n        Ok(())\n    }\n}\n\nfn impl_struct_by_extracting_each_field(\n    ident: &syn::Ident,\n    fields: &syn::Fields,\n    rejection: Option<syn::Path>,\n    state: &State,\n    tr: Trait,\n) -> syn::Result<TokenStream> {\n    let trait_fn_body = if matches!(state, State::CannotInfer) {\n        quote! {\n            ::std::unimplemented!()\n        }\n    } else {\n        let extract_fields = extract_fields(fields, rejection.as_ref(), tr)?;\n        quote! {\n            ::std::result::Result::Ok(Self {\n                #(#extract_fields)*\n            })\n        }\n    };\n\n    let rejection_ident = if let Some(rejection) = rejection {\n        quote!(#rejection)\n    } else if has_no_fields(fields) {\n        quote!(::std::convert::Infallible)\n    } else {\n        quote!(::axum::response::Response)\n    };\n\n    let impl_generics = state\n        .impl_generics()\n        .collect::<Punctuated<Type, Token![,]>>();\n\n    let trait_generics = state\n        .trait_generics()\n        .collect::<Punctuated<Type, Token![,]>>();\n\n    let state_bounds = state.bounds();\n\n    Ok(match tr {\n        Trait::FromRequest => quote! {\n            #[automatically_derived]\n            impl<#impl_generics> ::axum::extract::FromRequest<#trait_generics> for #ident\n            where\n                #state_bounds\n            {\n                type Rejection = #rejection_ident;\n\n                async fn from_request(\n                    mut req: ::axum::http::Request<::axum::body::Body>,\n                    state: &#state,\n                ) -> ::std::result::Result<Self, Self::Rejection> {\n                    #trait_fn_body\n                }\n            }\n        },\n        Trait::FromRequestParts => quote! {\n            #[automatically_derived]\n            impl<#impl_generics> ::axum::extract::FromRequestParts<#trait_generics> for #ident\n            where\n                #state_bounds\n            {\n                type Rejection = #rejection_ident;\n\n                async fn from_request_parts(\n                    parts: &mut ::axum::http::request::Parts,\n                    state: &#state,\n                ) -> ::std::result::Result<Self, Self::Rejection> {\n                    #trait_fn_body\n                }\n            }\n        },\n    })\n}\n\nfn has_no_fields(fields: &syn::Fields) -> bool {\n    match fields {\n        syn::Fields::Named(fields) => fields.named.is_empty(),\n        syn::Fields::Unnamed(fields) => fields.unnamed.is_empty(),\n        syn::Fields::Unit => true,\n    }\n}\n\nfn extract_fields(\n    fields: &syn::Fields,\n    rejection: Option<&syn::Path>,\n    tr: Trait,\n) -> syn::Result<Vec<TokenStream>> {\n    fn member(field: &syn::Field, index: usize) -> TokenStream {\n        if let Some(ident) = &field.ident {\n            quote! { #ident }\n        } else {\n            let member = syn::Member::Unnamed(syn::Index {\n                index: index as u32,\n                span: field.span(),\n            });\n            quote! { #member }\n        }\n    }\n\n    fn into_inner(via: Option<&(attr::kw::via, syn::Path)>, ty_span: Span) -> TokenStream {\n        if let Some((_, path)) = via {\n            let span = path.span();\n            quote_spanned! {span=>\n                |#path(inner)| inner\n            }\n        } else {\n            quote_spanned! {ty_span=>\n                ::std::convert::identity\n            }\n        }\n    }\n\n    fn into_outer(\n        via: Option<&(attr::kw::via, syn::Path)>,\n        ty_span: Span,\n        field_ty: &Type,\n    ) -> TokenStream {\n        if let Some((_, path)) = via {\n            let span = path.span();\n            quote_spanned! {span=>\n                #path<#field_ty>\n            }\n        } else {\n            quote_spanned! {ty_span=>\n                #field_ty\n            }\n        }\n    }\n\n    let mut fields_iter = fields.iter();\n\n    let last = match tr {\n        // Use FromRequestParts for all elements except the last\n        Trait::FromRequest => fields_iter.next_back(),\n        // Use FromRequestParts for all elements\n        Trait::FromRequestParts => None,\n    };\n\n    let mut res: Vec<_> = fields_iter\n        .enumerate()\n        .map(|(index, field)| {\n            let FromRequestFieldAttrs { via } = parse_attrs(\"from_request\", &field.attrs)?;\n\n            let member = member(field, index);\n            let ty_span = field.ty.span();\n            let into_inner = into_inner(via.as_ref(), ty_span);\n\n            if peel_option(&field.ty).is_some() {\n                let field_ty = into_outer(via.as_ref(), ty_span, peel_option(&field.ty).unwrap());\n                let tokens = match tr {\n                    Trait::FromRequest => {\n                        quote_spanned! {ty_span=>\n                            #member: {\n                                let (mut parts, body) = req.into_parts();\n                                let value =\n                                    <#field_ty as ::axum::extract::FromRequestParts<_>>::from_request_parts(\n                                        &mut parts,\n                                        state,\n                                    )\n                                    .await\n                                    .ok()\n                                    .map(#into_inner);\n                                req = ::axum::http::Request::from_parts(parts, body);\n                                value\n                            },\n                        }\n                    }\n                    Trait::FromRequestParts => {\n                        quote_spanned! {ty_span=>\n                            #member: {\n                                <#field_ty as ::axum::extract::FromRequestParts<_>>::from_request_parts(\n                                    parts,\n                                    state,\n                                )\n                                .await\n                                .ok()\n                                .map(#into_inner)\n                            },\n                        }\n                    }\n                };\n                Ok(tokens)\n            } else if peel_result_ok(&field.ty).is_some() {\n                let field_ty = into_outer(via.as_ref(), ty_span, peel_result_ok(&field.ty).unwrap());\n                let tokens = match tr {\n                    Trait::FromRequest => {\n                        quote_spanned! {ty_span=>\n                            #member: {\n                                let (mut parts, body) = req.into_parts();\n                                let value =\n                                    <#field_ty as ::axum::extract::FromRequestParts<_>>::from_request_parts(\n                                        &mut parts,\n                                        state,\n                                    )\n                                    .await\n                                    .map(#into_inner);\n                                req = ::axum::http::Request::from_parts(parts, body);\n                                value\n                            },\n                        }\n                    }\n                    Trait::FromRequestParts => {\n                        quote_spanned! {ty_span=>\n                            #member: {\n                                <#field_ty as ::axum::extract::FromRequestParts<_>>::from_request_parts(\n                                    parts,\n                                    state,\n                                )\n                                .await\n                                .map(#into_inner)\n                            },\n                        }\n                    }\n                };\n                Ok(tokens)\n            } else {\n                let field_ty = into_outer(via.as_ref(), ty_span, &field.ty);\n                let map_err = if let Some(rejection) = rejection {\n                    quote! { <#rejection as ::std::convert::From<_>>::from }\n                } else {\n                    quote! { ::axum::response::IntoResponse::into_response }\n                };\n\n                let tokens = match tr {\n                    Trait::FromRequest => {\n                        quote_spanned! {ty_span=>\n                            #member: {\n                                let (mut parts, body) = req.into_parts();\n                                let value =\n                                    <#field_ty as ::axum::extract::FromRequestParts<_>>::from_request_parts(\n                                        &mut parts,\n                                        state,\n                                    )\n                                    .await\n                                    .map(#into_inner)\n                                    .map_err(#map_err)?;\n                                req = ::axum::http::Request::from_parts(parts, body);\n                                value\n                            },\n                        }\n                    }\n                    Trait::FromRequestParts => {\n                        quote_spanned! {ty_span=>\n                            #member: {\n                                <#field_ty as ::axum::extract::FromRequestParts<_>>::from_request_parts(\n                                    parts,\n                                    state,\n                                )\n                                .await\n                                .map(#into_inner)\n                                .map_err(#map_err)?\n                            },\n                        }\n                    }\n                };\n                Ok(tokens)\n            }\n        })\n        .collect::<syn::Result<_>>()?;\n\n    // Handle the last element, if deriving FromRequest\n    if let Some(field) = last {\n        let FromRequestFieldAttrs { via } = parse_attrs(\"from_request\", &field.attrs)?;\n\n        let member = member(field, fields.len() - 1);\n        let ty_span = field.ty.span();\n        let into_inner = into_inner(via.as_ref(), ty_span);\n\n        let item = if peel_option(&field.ty).is_some() {\n            let field_ty = into_outer(via.as_ref(), ty_span, peel_option(&field.ty).unwrap());\n            quote_spanned! {ty_span=>\n                #member: {\n                    <#field_ty as ::axum::extract::FromRequest<_, _>>::from_request(req, state)\n                        .await\n                        .ok()\n                        .map(#into_inner)\n                },\n            }\n        } else if peel_result_ok(&field.ty).is_some() {\n            let field_ty = into_outer(via.as_ref(), ty_span, peel_result_ok(&field.ty).unwrap());\n            quote_spanned! {ty_span=>\n                #member: {\n                    <#field_ty as ::axum::extract::FromRequest<_, _>>::from_request(req, state)\n                        .await\n                        .map(#into_inner)\n                },\n            }\n        } else {\n            let field_ty = into_outer(via.as_ref(), ty_span, &field.ty);\n            let map_err = if let Some(rejection) = rejection {\n                quote! { <#rejection as ::std::convert::From<_>>::from }\n            } else {\n                quote! { ::axum::response::IntoResponse::into_response }\n            };\n\n            quote_spanned! {ty_span=>\n                #member: {\n                    <#field_ty as ::axum::extract::FromRequest<_, _>>::from_request(req, state)\n                        .await\n                        .map(#into_inner)\n                        .map_err(#map_err)?\n                },\n            }\n        };\n\n        res.push(item);\n    }\n\n    Ok(res)\n}\n\nfn peel_option(ty: &syn::Type) -> Option<&syn::Type> {\n    let syn::Type::Path(type_path) = ty else {\n        return None;\n    };\n\n    let segment = type_path.path.segments.last()?;\n\n    if segment.ident != \"Option\" {\n        return None;\n    }\n\n    let args = match &segment.arguments {\n        syn::PathArguments::AngleBracketed(args) => args,\n        syn::PathArguments::Parenthesized(_) | syn::PathArguments::None => return None,\n    };\n\n    let ty = if args.args.len() == 1 {\n        args.args.last().unwrap()\n    } else {\n        return None;\n    };\n\n    if let syn::GenericArgument::Type(ty) = ty {\n        Some(ty)\n    } else {\n        None\n    }\n}\n\nfn peel_result_ok(ty: &syn::Type) -> Option<&syn::Type> {\n    let syn::Type::Path(type_path) = ty else {\n        return None;\n    };\n\n    let segment = type_path.path.segments.last()?;\n\n    if segment.ident != \"Result\" {\n        return None;\n    }\n\n    let args = match &segment.arguments {\n        syn::PathArguments::AngleBracketed(args) => args,\n        syn::PathArguments::Parenthesized(_) | syn::PathArguments::None => return None,\n    };\n\n    let ty = if args.args.len() == 2 {\n        args.args.first().unwrap()\n    } else {\n        return None;\n    };\n\n    if let syn::GenericArgument::Type(ty) = ty {\n        Some(ty)\n    } else {\n        None\n    }\n}\n\nfn impl_struct_by_extracting_all_at_once(\n    ident: &syn::Ident,\n    fields: syn::Fields,\n    via_path: &syn::Path,\n    rejection: Option<&syn::Path>,\n    generic_ident: Option<&Ident>,\n    state: &State,\n    tr: Trait,\n) -> syn::Result<TokenStream> {\n    let fields = match fields {\n        syn::Fields::Named(fields) => fields.named.into_iter(),\n        syn::Fields::Unnamed(fields) => fields.unnamed.into_iter(),\n        syn::Fields::Unit => Punctuated::<_, Token![,]>::new().into_iter(),\n    };\n\n    for field in fields {\n        let FromRequestFieldAttrs { via } = parse_attrs(\"from_request\", &field.attrs)?;\n\n        if let Some((via, _)) = via {\n            return Err(syn::Error::new_spanned(\n                via,\n                \"`#[from_request(via(...))]` on a field cannot be used \\\n                together with `#[from_request(...)]` on the container\",\n            ));\n        }\n    }\n\n    let path_span = via_path.span();\n\n    // for something like\n    //\n    // ```\n    // #[derive(Clone, Default, FromRequest)]\n    // #[from_request(via(State))]\n    // struct AppState {}\n    // ```\n    //\n    // we need to implement `impl<M> FromRequest<AppState, M>` but only for\n    // - `#[derive(FromRequest)]`, not `#[derive(FromRequestParts)]`\n    // - `State`, not other extractors\n    //\n    // honestly not sure why but the tests all pass\n    let via_marker_type = if path_ident_is_state(via_path) {\n        tr.via_marker_type()\n    } else {\n        None\n    };\n\n    let impl_generics = via_marker_type\n        .iter()\n        .cloned()\n        .chain(state.impl_generics())\n        .chain(generic_ident.is_some().then(|| parse_quote!(T)))\n        .collect::<Punctuated<Type, Token![,]>>();\n\n    let trait_generics = state\n        .trait_generics()\n        .chain(via_marker_type)\n        .collect::<Punctuated<Type, Token![,]>>();\n\n    let ident_generics = if generic_ident.is_some() {\n        quote! { <T> }\n    } else {\n        TokenStream::new()\n    };\n\n    let rejection_bound = rejection.as_ref().map(|rejection| {\n        match (tr, generic_ident.is_some()) {\n            (Trait::FromRequest, true) => {\n                quote! {\n                    #rejection: ::std::convert::From<<#via_path<T> as ::axum::extract::FromRequest<#trait_generics>>::Rejection>,\n                }\n            },\n            (Trait::FromRequest, false) => {\n                quote! {\n                    #rejection: ::std::convert::From<<#via_path<Self> as ::axum::extract::FromRequest<#trait_generics>>::Rejection>,\n                }\n            },\n            (Trait::FromRequestParts, true) => {\n                quote! {\n                    #rejection: ::std::convert::From<<#via_path<T> as ::axum::extract::FromRequestParts<#trait_generics>>::Rejection>,\n                }\n            },\n            (Trait::FromRequestParts, false) => {\n                quote! {\n                    #rejection: ::std::convert::From<<#via_path<Self> as ::axum::extract::FromRequestParts<#trait_generics>>::Rejection>,\n                }\n            }\n        }\n    }).unwrap_or_default();\n\n    let via_type_generics = if generic_ident.is_some() {\n        quote! { T }\n    } else {\n        quote! { Self }\n    };\n\n    let associated_rejection_type = if let Some(rejection) = &rejection {\n        quote! { #rejection }\n    } else {\n        match tr {\n            Trait::FromRequest => quote! {\n                <#via_path<#via_type_generics> as ::axum::extract::FromRequest<#trait_generics>>::Rejection\n            },\n            Trait::FromRequestParts => quote! {\n                <#via_path<#via_type_generics> as ::axum::extract::FromRequestParts<#trait_generics>>::Rejection\n            },\n        }\n    };\n\n    let value_to_self = if generic_ident.is_some() {\n        quote! {\n            #ident(value)\n        }\n    } else {\n        quote! { value }\n    };\n\n    let state_bounds = state.bounds();\n\n    let tokens = match tr {\n        Trait::FromRequest => {\n            quote_spanned! {path_span=>\n                #[automatically_derived]\n                impl<#impl_generics> ::axum::extract::FromRequest<#trait_generics> for #ident #ident_generics\n                where\n                    #via_path<#via_type_generics>: ::axum::extract::FromRequest<#trait_generics>,\n                    #rejection_bound\n                    #state_bounds\n                {\n                    type Rejection = #associated_rejection_type;\n\n                    async fn from_request(\n                        req: ::axum::http::Request<::axum::body::Body>,\n                        state: &#state,\n                    ) -> ::std::result::Result<Self, Self::Rejection> {\n                        <#via_path<#via_type_generics> as ::axum::extract::FromRequest<_, _>>::from_request(req, state)\n                            .await\n                            .map(|#via_path(value)| #value_to_self)\n                            .map_err(::std::convert::From::from)\n                    }\n                }\n            }\n        }\n        Trait::FromRequestParts => {\n            quote_spanned! {path_span=>\n                #[automatically_derived]\n                impl<#impl_generics> ::axum::extract::FromRequestParts<#trait_generics> for #ident #ident_generics\n                where\n                    #via_path<#via_type_generics>: ::axum::extract::FromRequestParts<#trait_generics>,\n                    #rejection_bound\n                    #state_bounds\n                {\n                    type Rejection = #associated_rejection_type;\n\n                    async fn from_request_parts(\n                        parts: &mut ::axum::http::request::Parts,\n                        state: &#state,\n                    ) -> ::std::result::Result<Self, Self::Rejection> {\n                        <#via_path<#via_type_generics> as ::axum::extract::FromRequestParts<_>>::from_request_parts(parts, state)\n                            .await\n                            .map(|#via_path(value)| #value_to_self)\n                            .map_err(::std::convert::From::from)\n                    }\n                }\n            }\n        }\n    };\n\n    Ok(tokens)\n}\n\nfn impl_enum_by_extracting_all_at_once(\n    ident: &syn::Ident,\n    variants: Punctuated<syn::Variant, Token![,]>,\n    path: &syn::Path,\n    rejection: Option<&syn::Path>,\n    state: &State,\n    tr: Trait,\n) -> syn::Result<TokenStream> {\n    for variant in variants {\n        let FromRequestFieldAttrs { via } = parse_attrs(\"from_request\", &variant.attrs)?;\n\n        if let Some((via, _)) = via {\n            return Err(syn::Error::new_spanned(\n                via,\n                \"`#[from_request(via(...))]` cannot be used on variants\",\n            ));\n        }\n\n        let fields = match variant.fields {\n            syn::Fields::Named(fields) => fields.named.into_iter(),\n            syn::Fields::Unnamed(fields) => fields.unnamed.into_iter(),\n            syn::Fields::Unit => Punctuated::<_, Token![,]>::new().into_iter(),\n        };\n\n        for field in fields {\n            let FromRequestFieldAttrs { via } = parse_attrs(\"from_request\", &field.attrs)?;\n            if let Some((via, _)) = via {\n                return Err(syn::Error::new_spanned(\n                    via,\n                    \"`#[from_request(via(...))]` cannot be used inside variants\",\n                ));\n            }\n        }\n    }\n\n    let (associated_rejection_type, map_err) = if let Some(rejection) = &rejection {\n        let rejection = quote! { #rejection };\n        let map_err = quote! { ::std::convert::From::from };\n        (rejection, map_err)\n    } else {\n        let rejection = quote! {\n            ::axum::response::Response\n        };\n        let map_err = quote! { ::axum::response::IntoResponse::into_response };\n        (rejection, map_err)\n    };\n\n    let path_span = path.span();\n\n    let impl_generics = state\n        .impl_generics()\n        .collect::<Punctuated<Type, Token![,]>>();\n\n    let trait_generics = state\n        .trait_generics()\n        .collect::<Punctuated<Type, Token![,]>>();\n\n    let state_bounds = state.bounds();\n\n    let tokens = match tr {\n        Trait::FromRequest => {\n            quote_spanned! {path_span=>\n                #[automatically_derived]\n                impl<#impl_generics> ::axum::extract::FromRequest<#trait_generics> for #ident\n                where\n                    #state_bounds\n                {\n                    type Rejection = #associated_rejection_type;\n\n                    async fn from_request(\n                        req: ::axum::http::Request<::axum::body::Body>,\n                        state: &#state,\n                    ) -> ::std::result::Result<Self, Self::Rejection> {\n                        <#path::<#ident> as ::axum::extract::FromRequest<_, _>>::from_request(req, state)\n                            .await\n                            .map(|#path(inner)| inner)\n                            .map_err(#map_err)\n                    }\n                }\n            }\n        }\n        Trait::FromRequestParts => {\n            quote_spanned! {path_span=>\n                #[automatically_derived]\n                impl<#impl_generics> ::axum::extract::FromRequestParts<#trait_generics> for #ident\n                where\n                    #state_bounds\n                {\n                    type Rejection = #associated_rejection_type;\n\n                    async fn from_request_parts(\n                        parts: &mut ::axum::http::request::Parts,\n                        state: &#state,\n                    ) -> ::std::result::Result<Self, Self::Rejection> {\n                        <#path::<#ident> as ::axum::extract::FromRequestParts<_>>::from_request_parts(parts, state)\n                            .await\n                            .map(|#path(inner)| inner)\n                            .map_err(#map_err)\n                    }\n                }\n            }\n        }\n    };\n\n    Ok(tokens)\n}\n\n/// For a struct like\n///\n/// ```skip\n/// struct Extractor {\n///     state: State<AppState>,\n/// }\n/// ```\n///\n/// We can infer the state type to be `AppState` because it appears inside a `State`\nfn infer_state_type_from_field_types(fields: &Fields) -> impl Iterator<Item = Type> + '_ {\n    match fields {\n        Fields::Named(fields_named) => Box::new(crate::infer_state_types(\n            fields_named.named.iter().map(|field| &field.ty),\n        )) as Box<dyn Iterator<Item = Type>>,\n        Fields::Unnamed(fields_unnamed) => Box::new(crate::infer_state_types(\n            fields_unnamed.unnamed.iter().map(|field| &field.ty),\n        )),\n        Fields::Unit => Box::new(iter::empty()),\n    }\n}\n\n/// For a struct like\n///\n/// ```skip\n/// struct Extractor {\n///     #[from_request(via(State))]\n///     state: AppState,\n/// }\n/// ```\n///\n/// We can infer the state type to be `AppState` because it has `via(State)` and thus can be\n/// extracted with `State<AppState>`\nfn infer_state_type_from_field_attributes(fields: &Fields) -> impl Iterator<Item = Type> + '_ {\n    match fields {\n        Fields::Named(fields_named) => {\n            Box::new(fields_named.named.iter().filter_map(|field| {\n                // TODO(david): it's a little wasteful to parse the attributes again here\n                // ideally we should parse things once and pass the data down\n                let FromRequestFieldAttrs { via } =\n                    parse_attrs(\"from_request\", &field.attrs).ok()?;\n                let (_, via_path) = via?;\n                path_ident_is_state(&via_path).then(|| field.ty.clone())\n            })) as Box<dyn Iterator<Item = Type>>\n        }\n        Fields::Unnamed(fields_unnamed) => {\n            Box::new(fields_unnamed.unnamed.iter().filter_map(|field| {\n                // TODO(david): it's a little wasteful to parse the attributes again here\n                // ideally we should parse things once and pass the data down\n                let FromRequestFieldAttrs { via } =\n                    parse_attrs(\"from_request\", &field.attrs).ok()?;\n                let (_, via_path) = via?;\n                path_ident_is_state(&via_path).then(|| field.ty.clone())\n            }))\n        }\n        Fields::Unit => Box::new(iter::empty()),\n    }\n}\n\nfn path_ident_is_state(path: &Path) -> bool {\n    if let Some(last_segment) = path.segments.last() {\n        last_segment.ident == \"State\"\n    } else {\n        false\n    }\n}\n\nfn state_from_via(ident: &Ident, via: &Path) -> Option<Type> {\n    path_ident_is_state(via).then(|| parse_quote!(#ident))\n}\n\n#[test]\nfn ui() {\n    crate::run_ui_tests(\"from_request\");\n}\n\n/// For some reason the compiler error for this is different locally and on CI. No idea why... So\n/// we don't use trybuild for this test.\n///\n/// ```compile_fail\n/// #[derive(axum_macros::FromRequest)]\n/// struct Extractor {\n///     thing: bool,\n/// }\n/// ```\n#[allow(dead_code)]\nfn test_field_doesnt_impl_from_request() {}\n"
  },
  {
    "path": "axum-macros/src/lib.rs",
    "content": "//! Macros for [`axum`].\n//!\n//! [`axum`]: https://crates.io/crates/axum\n\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(test, allow(clippy::float_cmp))]\n#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]\n\nuse debug_handler::FunctionKind;\nuse proc_macro::TokenStream;\nuse quote::{quote, ToTokens};\nuse syn::{parse::Parse, Type};\n\nmod attr_parsing;\n#[cfg(feature = \"__private\")]\nmod axum_test;\nmod debug_handler;\nmod from_ref;\nmod from_request;\nmod typed_path;\nmod with_position;\n\nuse from_request::Trait::{FromRequest, FromRequestParts};\n\n/// Derive an implementation of [`FromRequest`].\n///\n/// Supports generating two kinds of implementations:\n/// 1. One that extracts each field individually.\n/// 2. Another that extracts the whole type at once via another extractor.\n///\n/// # Each field individually\n///\n/// By default `#[derive(FromRequest)]` will call `FromRequest::from_request` for each field:\n///\n/// ```\n/// use axum_macros::FromRequest;\n/// use axum::{\n///     extract::Extension,\n///     body::Bytes,\n/// };\n/// use axum_extra::{\n///     TypedHeader,\n///     headers::ContentType,\n/// };\n///\n/// #[derive(FromRequest)]\n/// struct MyExtractor {\n///     state: Extension<State>,\n///     content_type: TypedHeader<ContentType>,\n///     request_body: Bytes,\n/// }\n///\n/// #[derive(Clone)]\n/// struct State {\n///     // ...\n/// }\n///\n/// async fn handler(extractor: MyExtractor) {}\n/// ```\n///\n/// This requires that each field is an extractor (i.e. implements [`FromRequest`]).\n///\n/// Note that only the last field can consume the request body. Therefore this doesn't compile:\n///\n/// ```compile_fail\n/// use axum_macros::FromRequest;\n/// use axum::body::Bytes;\n///\n/// #[derive(FromRequest)]\n/// struct MyExtractor {\n///     // only the last field can implement `FromRequest`\n///     // other fields must only implement `FromRequestParts`\n///     bytes: Bytes,\n///     string: String,\n/// }\n/// ```\n///\n/// ## Extracting via another extractor\n///\n/// You can use `#[from_request(via(...))]` to extract a field via another extractor, meaning the\n/// field itself doesn't need to implement `FromRequest`:\n///\n/// ```\n/// use axum_macros::FromRequest;\n/// use axum::{\n///     extract::Extension,\n///     body::Bytes,\n/// };\n/// use axum_extra::{\n///     TypedHeader,\n///     headers::ContentType,\n/// };\n///\n/// #[derive(FromRequest)]\n/// struct MyExtractor {\n///     // This will extracted via `Extension::<State>::from_request`\n///     #[from_request(via(Extension))]\n///     state: State,\n///     // and this via `TypedHeader::<ContentType>::from_request`\n///     #[from_request(via(TypedHeader))]\n///     content_type: ContentType,\n///     // Can still be combined with other extractors\n///     request_body: Bytes,\n/// }\n///\n/// #[derive(Clone)]\n/// struct State {\n///     // ...\n/// }\n///\n/// async fn handler(extractor: MyExtractor) {}\n/// ```\n///\n/// Note this requires the via extractor to be a generic newtype struct (a tuple struct with\n/// exactly one public field) that implements `FromRequest`:\n///\n/// ```\n/// pub struct ViaExtractor<T>(pub T);\n///\n/// // impl<T, S> FromRequest<S> for ViaExtractor<T> { ... }\n/// ```\n///\n/// More complex via extractors are not supported and require writing a manual implementation.\n///\n/// ## Optional fields\n///\n/// `#[from_request(via(...))]` supports `Option<_>` and `Result<_, _>` to make fields optional:\n///\n/// ```\n/// use axum_macros::FromRequest;\n/// use axum_extra::{\n///     TypedHeader,\n///     headers::{ContentType, UserAgent},\n///     typed_header::TypedHeaderRejection,\n/// };\n///\n/// #[derive(FromRequest)]\n/// struct MyExtractor {\n///     // This will extracted via `Option::<TypedHeader<ContentType>>::from_request`\n///     #[from_request(via(TypedHeader))]\n///     content_type: Option<ContentType>,\n///     // This will extracted via\n///     // `Result::<TypedHeader<UserAgent>, TypedHeaderRejection>::from_request`\n///     #[from_request(via(TypedHeader))]\n///     user_agent: Result<UserAgent, TypedHeaderRejection>,\n/// }\n///\n/// async fn handler(extractor: MyExtractor) {}\n/// ```\n///\n/// ## The rejection\n///\n/// By default [`axum::response::Response`] will be used as the rejection. You can also use your own\n/// rejection type with `#[from_request(rejection(YourType))]`:\n///\n/// ```\n/// use axum::{\n///     extract::{\n///         rejection::{ExtensionRejection, StringRejection},\n///         FromRequest,\n///     },\n///     Extension,\n///     response::{Response, IntoResponse},\n/// };\n///\n/// #[derive(FromRequest)]\n/// #[from_request(rejection(MyRejection))]\n/// struct MyExtractor {\n///     state: Extension<String>,\n///     body: String,\n/// }\n///\n/// struct MyRejection(Response);\n///\n/// // This tells axum how to convert `Extension`'s rejections into `MyRejection`\n/// impl From<ExtensionRejection> for MyRejection {\n///     fn from(rejection: ExtensionRejection) -> Self {\n///         // ...\n///         # todo!()\n///     }\n/// }\n///\n/// // This tells axum how to convert `String`'s rejections into `MyRejection`\n/// impl From<StringRejection> for MyRejection {\n///     fn from(rejection: StringRejection) -> Self {\n///         // ...\n///         # todo!()\n///     }\n/// }\n///\n/// // All rejections must implement `IntoResponse`\n/// impl IntoResponse for MyRejection {\n///     fn into_response(self) -> Response {\n///         self.0\n///     }\n/// }\n/// ```\n///\n/// ## Concrete state\n///\n/// If the extraction can be done only for a concrete state, that type can be specified with\n/// `#[from_request(state(YourState))]`:\n///\n/// ```\n/// use axum::extract::{FromRequest, FromRequestParts};\n///\n/// #[derive(Clone)]\n/// struct CustomState;\n///\n/// struct MyInnerType;\n///\n/// impl FromRequestParts<CustomState> for MyInnerType {\n///     // ...\n///     # type Rejection = ();\n///\n///     # async fn from_request_parts(\n///         # _parts: &mut axum::http::request::Parts,\n///         # _state: &CustomState\n///     # ) -> Result<Self, Self::Rejection> {\n///     #    todo!()\n///     # }\n/// }\n///\n/// #[derive(FromRequest)]\n/// #[from_request(state(CustomState))]\n/// struct MyExtractor {\n///     custom: MyInnerType,\n///     body: String,\n/// }\n/// ```\n///\n/// This is not needed for a `State<T>` as the type is inferred in that case.\n///\n/// ```\n/// use axum::extract::{FromRequest, FromRequestParts, State};\n///\n/// #[derive(Clone)]\n/// struct CustomState;\n///\n/// #[derive(FromRequest)]\n/// struct MyExtractor {\n///     custom: State<CustomState>,\n///     body: String,\n/// }\n/// ```\n///\n/// # The whole type at once\n///\n/// By using `#[from_request(via(...))]` on the container you can extract the whole type at once,\n/// instead of each field individually:\n///\n/// ```\n/// use axum_macros::FromRequest;\n/// use axum::extract::Extension;\n///\n/// // This will extracted via `Extension::<State>::from_request`\n/// #[derive(Clone, FromRequest)]\n/// #[from_request(via(Extension))]\n/// struct State {\n///     // ...\n/// }\n///\n/// async fn handler(state: State) {}\n/// ```\n///\n/// The rejection will be the \"via extractors\"'s rejection. For the previous example that would be\n/// [`axum::extract::rejection::ExtensionRejection`].\n///\n/// You can use a different rejection type with `#[from_request(rejection(YourType))]`:\n///\n/// ```\n/// use axum_macros::FromRequest;\n/// use axum::{\n///     extract::{Extension, rejection::ExtensionRejection},\n///     response::{IntoResponse, Response},\n///     Json,\n///     http::StatusCode,\n/// };\n/// use serde_json::json;\n///\n/// // This will extracted via `Extension::<State>::from_request`\n/// #[derive(Clone, FromRequest)]\n/// #[from_request(\n///     via(Extension),\n///     // Use your own rejection type\n///     rejection(MyRejection),\n/// )]\n/// struct State {\n///     // ...\n/// }\n///\n/// struct MyRejection(Response);\n///\n/// // This tells axum how to convert `Extension`'s rejections into `MyRejection`\n/// impl From<ExtensionRejection> for MyRejection {\n///     fn from(rejection: ExtensionRejection) -> Self {\n///         let response = (\n///             StatusCode::INTERNAL_SERVER_ERROR,\n///             Json(json!({ \"error\": \"Something went wrong...\" })),\n///         ).into_response();\n///\n///         MyRejection(response)\n///     }\n/// }\n///\n/// // All rejections must implement `IntoResponse`\n/// impl IntoResponse for MyRejection {\n///     fn into_response(self) -> Response {\n///         self.0\n///     }\n/// }\n///\n/// async fn handler(state: State) {}\n/// ```\n///\n/// This allows you to wrap other extractors and easily customize the rejection:\n///\n/// ```\n/// use axum_macros::FromRequest;\n/// use axum::{\n///     extract::{Extension, rejection::JsonRejection},\n///     response::{IntoResponse, Response},\n///     http::StatusCode,\n/// };\n/// use serde_json::json;\n/// use serde::Deserialize;\n///\n/// // create an extractor that internally uses `axum::Json` but has a custom rejection\n/// #[derive(FromRequest)]\n/// #[from_request(via(axum::Json), rejection(MyRejection))]\n/// struct MyJson<T>(T);\n///\n/// struct MyRejection(Response);\n///\n/// impl From<JsonRejection> for MyRejection {\n///     fn from(rejection: JsonRejection) -> Self {\n///         let response = (\n///             StatusCode::INTERNAL_SERVER_ERROR,\n///             axum::Json(json!({ \"error\": rejection.to_string() })),\n///         ).into_response();\n///\n///         MyRejection(response)\n///     }\n/// }\n///\n/// impl IntoResponse for MyRejection {\n///     fn into_response(self) -> Response {\n///         self.0\n///     }\n/// }\n///\n/// #[derive(Deserialize)]\n/// struct Payload {}\n///\n/// async fn handler(\n///     // make sure to use `MyJson` and not `axum::Json`\n///     MyJson(payload): MyJson<Payload>,\n/// ) {}\n/// ```\n///\n/// # Known limitations\n///\n/// Generics are only supported on tuple structs with exactly one field. Thus this doesn't work\n///\n/// ```compile_fail\n/// #[derive(axum_macros::FromRequest)]\n/// struct MyExtractor<T> {\n///     thing: Option<T>,\n/// }\n/// ```\n///\n/// [`FromRequest`]: https://docs.rs/axum/0.8/axum/extract/trait.FromRequest.html\n/// [`axum::response::Response`]: https://docs.rs/axum/0.8/axum/response/type.Response.html\n/// [`axum::extract::rejection::ExtensionRejection`]: https://docs.rs/axum/0.8/axum/extract/rejection/enum.ExtensionRejection.html\n#[proc_macro_derive(FromRequest, attributes(from_request))]\npub fn derive_from_request(item: TokenStream) -> TokenStream {\n    expand_with(item, |item| from_request::expand(item, FromRequest))\n}\n\n/// Derive an implementation of [`FromRequestParts`].\n///\n/// This works similarly to `#[derive(FromRequest)]` except it uses [`FromRequestParts`]. All the\n/// same options are supported.\n///\n/// # Example\n///\n/// ```\n/// use axum_macros::FromRequestParts;\n/// use axum::{\n///     extract::Query,\n/// };\n/// use axum_extra::{\n///     TypedHeader,\n///     headers::ContentType,\n/// };\n/// use std::collections::HashMap;\n///\n/// #[derive(FromRequestParts)]\n/// struct MyExtractor {\n///     #[from_request(via(Query))]\n///     query_params: HashMap<String, String>,\n///     content_type: TypedHeader<ContentType>,\n/// }\n///\n/// async fn handler(extractor: MyExtractor) {}\n/// ```\n///\n/// # Cannot extract the body\n///\n/// [`FromRequestParts`] cannot extract the request body:\n///\n/// ```compile_fail\n/// use axum_macros::FromRequestParts;\n///\n/// #[derive(FromRequestParts)]\n/// struct MyExtractor {\n///     body: String,\n/// }\n/// ```\n///\n/// Use `#[derive(FromRequest)]` for that.\n///\n/// [`FromRequestParts`]: https://docs.rs/axum/0.8/axum/extract/trait.FromRequestParts.html\n#[proc_macro_derive(FromRequestParts, attributes(from_request))]\npub fn derive_from_request_parts(item: TokenStream) -> TokenStream {\n    expand_with(item, |item| from_request::expand(item, FromRequestParts))\n}\n\n/// Generates better error messages when applied to handler functions.\n///\n/// While using [`axum`], you can get long error messages for simple mistakes. For example:\n///\n/// ```compile_fail\n/// use axum::{routing::get, Router};\n///\n/// #[tokio::main]\n/// async fn main() {\n///     let app = Router::new().route(\"/\", get(handler));\n///\n///     let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n///     axum::serve(listener, app).await;\n/// }\n///\n/// fn handler() -> &'static str {\n///     \"Hello, world\"\n/// }\n/// ```\n///\n/// You will get a long error message about function not implementing [`Handler`] trait. But why\n/// does this function not implement it? To figure it out, the [`debug_handler`] macro can be used.\n///\n/// ```compile_fail\n/// # use axum::{routing::get, Router};\n/// # use axum_macros::debug_handler;\n/// #\n/// # #[tokio::main]\n/// # async fn main() {\n/// #     let app = Router::new().route(\"/\", get(handler));\n/// #\n/// #     let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n/// #     axum::serve(listener, app).await;\n/// # }\n/// #\n/// #[debug_handler]\n/// fn handler() -> &'static str {\n///     \"Hello, world\"\n/// }\n/// ```\n///\n/// ```text\n/// error: handlers must be async functions\n///   --> main.rs:xx:1\n///    |\n/// xx | fn handler() -> &'static str {\n///    | ^^\n/// ```\n///\n/// As the error message says, handler function needs to be async.\n///\n/// ```no_run\n/// use axum::{routing::get, Router, debug_handler};\n///\n/// #[tokio::main]\n/// async fn main() {\n///     let app = Router::new().route(\"/\", get(handler));\n///\n///     let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n///     axum::serve(listener, app).await;\n/// }\n///\n/// #[debug_handler]\n/// async fn handler() -> &'static str {\n///     \"Hello, world\"\n/// }\n/// ```\n///\n/// # Changing state type\n///\n/// By default `#[debug_handler]` assumes your state type is `()` unless your handler has a\n/// [`axum::extract::State`] argument:\n///\n/// ```\n/// use axum::{debug_handler, extract::State};\n///\n/// #[debug_handler]\n/// async fn handler(\n///     // this makes `#[debug_handler]` use `AppState`\n///     State(state): State<AppState>,\n/// ) {}\n///\n/// #[derive(Clone)]\n/// struct AppState {}\n/// ```\n///\n/// If your handler takes multiple [`axum::extract::State`] arguments or you need to otherwise\n/// customize the state type you can set it with `#[debug_handler(state = ...)]`:\n///\n/// ```\n/// use axum::{debug_handler, extract::{State, FromRef}};\n///\n/// #[debug_handler(state = AppState)]\n/// async fn handler(\n///     State(app_state): State<AppState>,\n///     State(inner_state): State<InnerState>,\n/// ) {}\n///\n/// #[derive(Clone)]\n/// struct AppState {\n///     inner: InnerState,\n/// }\n///\n/// #[derive(Clone)]\n/// struct InnerState {}\n///\n/// impl FromRef<AppState> for InnerState {\n///     fn from_ref(state: &AppState) -> Self {\n///         state.inner.clone()\n///     }\n/// }\n/// ```\n///\n/// # Limitations\n///\n/// This macro does not work for functions in an `impl` block that don't have a `self` parameter:\n///\n/// ```compile_fail\n/// use axum::{debug_handler, extract::Path};\n///\n/// struct App {}\n///\n/// impl App {\n///     #[debug_handler]\n///     async fn handler(Path(_): Path<String>) {}\n/// }\n/// ```\n///\n/// This will yield an error similar to this:\n///\n/// ```text\n/// error[E0425]: cannot find function `__axum_macros_check_handler_0_from_request_check` in this scope\n//    --> src/main.rs:xx:xx\n//     |\n//  xx |     pub async fn handler(Path(_): Path<String>)  {}\n//     |                                   ^^^^ not found in this scope\n/// ```\n///\n/// # Performance\n///\n/// This macro has no effect when compiled with the release profile. (eg. `cargo build --release`)\n///\n/// [`axum`]: https://docs.rs/axum/0.8\n/// [`Handler`]: https://docs.rs/axum/0.8/axum/handler/trait.Handler.html\n/// [`axum::extract::State`]: https://docs.rs/axum/0.8/axum/extract/struct.State.html\n/// [`debug_handler`]: macro@debug_handler\n#[proc_macro_attribute]\npub fn debug_handler(_attr: TokenStream, input: TokenStream) -> TokenStream {\n    #[cfg(not(debug_assertions))]\n    return input;\n\n    #[cfg(debug_assertions)]\n    return expand_attr_with(_attr, input, |attrs, item_fn| {\n        debug_handler::expand(attrs, &item_fn, FunctionKind::Handler)\n    });\n}\n\n/// Generates better error messages when applied to middleware functions.\n///\n/// This works similarly to [`#[debug_handler]`](macro@debug_handler) except for middleware using\n/// [`axum::middleware::from_fn`].\n///\n/// # Example\n///\n/// ```no_run\n/// use axum::{\n///     routing::get,\n///     extract::Request,\n///     response::Response,\n///     Router,\n///     middleware::{self, Next},\n///     debug_middleware,\n/// };\n///\n/// #[tokio::main]\n/// async fn main() {\n///     let app = Router::new()\n///         .route(\"/\", get(|| async {}))\n///         .layer(middleware::from_fn(my_middleware));\n///\n///     let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n///     axum::serve(listener, app).await;\n/// }\n///\n/// // if this wasn't a valid middleware function #[debug_middleware] would\n/// // improve compile error\n/// #[debug_middleware]\n/// async fn my_middleware(\n///     request: Request,\n///     next: Next,\n/// ) -> Response {\n///     next.run(request).await\n/// }\n/// ```\n///\n/// # Performance\n///\n/// This macro has no effect when compiled with the release profile. (eg. `cargo build --release`)\n///\n/// [`axum`]: https://docs.rs/axum/latest\n/// [`axum::middleware::from_fn`]: https://docs.rs/axum/0.8/axum/middleware/fn.from_fn.html\n/// [`debug_middleware`]: macro@debug_middleware\n#[proc_macro_attribute]\npub fn debug_middleware(_attr: TokenStream, input: TokenStream) -> TokenStream {\n    #[cfg(not(debug_assertions))]\n    return input;\n\n    #[cfg(debug_assertions)]\n    return expand_attr_with(_attr, input, |attrs, item_fn| {\n        debug_handler::expand(attrs, &item_fn, FunctionKind::Middleware)\n    });\n}\n\n/// Private API: Do no use this!\n///\n/// Attribute macro to be placed on test functions that'll generate two functions:\n///\n/// 1. One identical to the function it was placed on.\n/// 2. One where calls to `Router::nest` has been replaced with `Router::nest_service`\n///\n/// This makes it easy to that `nest` and `nest_service` behaves in the same way, without having to\n/// manually write identical tests for both methods.\n#[cfg(feature = \"__private\")]\n#[proc_macro_attribute]\n#[doc(hidden)]\npub fn __private_axum_test(_attr: TokenStream, input: TokenStream) -> TokenStream {\n    expand_attr_with(_attr, input, axum_test::expand)\n}\n\n/// Derive an implementation of [`axum_extra::routing::TypedPath`].\n///\n/// See that trait for more details.\n///\n/// [`axum_extra::routing::TypedPath`]: https://docs.rs/axum-extra/latest/axum_extra/routing/trait.TypedPath.html\n#[proc_macro_derive(TypedPath, attributes(typed_path))]\npub fn derive_typed_path(input: TokenStream) -> TokenStream {\n    expand_with(input, |item_struct| typed_path::expand(&item_struct))\n}\n\n/// Derive an implementation of [`FromRef`] for each field in a struct.\n///\n/// # Example\n///\n/// ```\n/// use axum::{\n///     Router,\n///     routing::get,\n///     extract::{State, FromRef},\n/// };\n///\n/// #\n/// # type AuthToken = String;\n/// # type DatabasePool = ();\n/// #\n/// // This will implement `FromRef` for each field in the struct.\n/// #[derive(FromRef, Clone)]\n/// struct AppState {\n///     auth_token: AuthToken,\n///     database_pool: DatabasePool,\n///     // fields can also be skipped\n///     #[from_ref(skip)]\n///     api_token: String,\n/// }\n///\n/// // So those types can be extracted via `State`\n/// async fn handler(State(auth_token): State<AuthToken>) {}\n///\n/// async fn other_handler(State(database_pool): State<DatabasePool>) {}\n///\n/// # let auth_token = Default::default();\n/// # let database_pool = Default::default();\n/// let state = AppState {\n///     auth_token,\n///     database_pool,\n///     api_token: \"secret\".to_owned(),\n/// };\n///\n/// let app = Router::new()\n///     .route(\"/\", get(handler).post(other_handler))\n///     .with_state(state);\n/// # let _: axum::Router = app;\n/// ```\n///\n/// [`FromRef`]: https://docs.rs/axum/0.8/axum/extract/trait.FromRef.html\n#[proc_macro_derive(FromRef, attributes(from_ref))]\npub fn derive_from_ref(item: TokenStream) -> TokenStream {\n    expand_with(item, from_ref::expand)\n}\n\nfn expand_with<F, I, K>(input: TokenStream, f: F) -> TokenStream\nwhere\n    F: FnOnce(I) -> syn::Result<K>,\n    I: Parse,\n    K: ToTokens,\n{\n    expand(syn::parse(input).and_then(f))\n}\n\nfn expand_attr_with<F, A, I, K>(attr: TokenStream, input: TokenStream, f: F) -> TokenStream\nwhere\n    F: FnOnce(A, I) -> K,\n    A: Parse,\n    I: Parse,\n    K: ToTokens,\n{\n    let expand_result = (|| {\n        let attr = syn::parse(attr)?;\n        let input = syn::parse(input)?;\n        Ok(f(attr, input))\n    })();\n    expand(expand_result)\n}\n\nfn expand<T>(result: syn::Result<T>) -> TokenStream\nwhere\n    T: ToTokens,\n{\n    match result {\n        Ok(tokens) => {\n            let tokens = (quote! { #tokens }).into();\n            if std::env::var_os(\"AXUM_MACROS_DEBUG\").is_some() {\n                eprintln!(\"{tokens}\");\n            }\n            tokens\n        }\n        Err(err) => err.into_compile_error().into(),\n    }\n}\n\nfn infer_state_types<'a, I>(types: I) -> impl Iterator<Item = Type> + 'a\nwhere\n    I: Iterator<Item = &'a Type> + 'a,\n{\n    types\n        .filter_map(|ty| {\n            if let Type::Path(path) = ty {\n                Some(&path.path)\n            } else {\n                None\n            }\n        })\n        .filter_map(|path| {\n            if let Some(last_segment) = path.segments.last() {\n                if last_segment.ident != \"State\" {\n                    return None;\n                }\n\n                match &last_segment.arguments {\n                    syn::PathArguments::AngleBracketed(args) if args.args.len() == 1 => {\n                        Some(args.args.first().unwrap())\n                    }\n                    _ => None,\n                }\n            } else {\n                None\n            }\n        })\n        .filter_map(|generic_arg| {\n            if let syn::GenericArgument::Type(ty) = generic_arg {\n                Some(ty)\n            } else {\n                None\n            }\n        })\n        .cloned()\n}\n\n#[cfg(test)]\nfn run_ui_tests(directory: &str) {\n    #[rustversion::nightly]\n    fn go(directory: &str) {\n        let t = trybuild::TestCases::new();\n\n        if let Ok(mut path) = std::env::var(\"AXUM_TEST_ONLY\") {\n            if let Some(path_without_prefix) = path.strip_prefix(\"axum-macros/\") {\n                path = path_without_prefix.to_owned();\n            }\n\n            if !path.contains(&format!(\"/{directory}/\")) {\n                return;\n            }\n\n            if path.contains(\"/fail/\") {\n                t.compile_fail(path);\n            } else if path.contains(\"/pass/\") {\n                t.pass(path);\n            } else {\n                panic!()\n            }\n        } else {\n            t.compile_fail(format!(\"tests/{directory}/fail/*.rs\"));\n            t.pass(format!(\"tests/{directory}/pass/*.rs\"));\n        }\n    }\n\n    #[rustversion::not(nightly)]\n    fn go(_directory: &str) {}\n\n    go(directory);\n}\n"
  },
  {
    "path": "axum-macros/src/typed_path.rs",
    "content": "use proc_macro2::{Span, TokenStream};\nuse quote::{format_ident, quote, quote_spanned};\nuse syn::{parse::Parse, ItemStruct, LitStr, Token};\n\nuse crate::attr_parsing::{combine_attribute, parse_parenthesized_attribute, second, Combine};\n\npub(crate) fn expand(item_struct: &ItemStruct) -> syn::Result<TokenStream> {\n    let ItemStruct {\n        attrs,\n        ident,\n        generics,\n        fields,\n        ..\n    } = item_struct;\n\n    if !generics.params.is_empty() || generics.where_clause.is_some() {\n        return Err(syn::Error::new_spanned(\n            generics,\n            \"`#[derive(TypedPath)]` doesn't support generics\",\n        ));\n    }\n\n    let Attrs { path, rejection } = crate::attr_parsing::parse_attrs(\"typed_path\", attrs)?;\n\n    let path = path.ok_or_else(|| {\n        syn::Error::new(\n            Span::call_site(),\n            \"Missing path: `#[typed_path(\\\"/foo/bar\\\")]`\",\n        )\n    })?;\n\n    let rejection = rejection.map(second);\n\n    match fields {\n        syn::Fields::Named(_) => {\n            let segments = parse_path(&path)?;\n            Ok(expand_named_fields(\n                ident,\n                &path,\n                &segments,\n                rejection.as_ref(),\n            ))\n        }\n        syn::Fields::Unnamed(fields) => {\n            let segments = parse_path(&path)?;\n            expand_unnamed_fields(fields, ident, &path, &segments, rejection.as_ref())\n        }\n        syn::Fields::Unit => expand_unit_fields(ident, &path, rejection.as_ref()),\n    }\n}\n\nmod kw {\n    syn::custom_keyword!(rejection);\n}\n\n#[derive(Default)]\nstruct Attrs {\n    path: Option<LitStr>,\n    rejection: Option<(kw::rejection, syn::Path)>,\n}\n\nimpl Parse for Attrs {\n    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {\n        let mut path = None;\n        let mut rejection = None;\n\n        while !input.is_empty() {\n            let lh = input.lookahead1();\n            if lh.peek(LitStr) {\n                path = Some(input.parse()?);\n            } else if lh.peek(kw::rejection) {\n                parse_parenthesized_attribute(input, &mut rejection)?;\n            } else {\n                return Err(lh.error());\n            }\n\n            let _ = input.parse::<Token![,]>();\n        }\n\n        Ok(Self { path, rejection })\n    }\n}\n\nimpl Combine for Attrs {\n    fn combine(mut self, other: Self) -> syn::Result<Self> {\n        let Self { path, rejection } = other;\n        if let Some(path) = path {\n            if self.path.is_some() {\n                return Err(syn::Error::new_spanned(\n                    path,\n                    \"path specified more than once\",\n                ));\n            }\n            self.path = Some(path);\n        }\n        combine_attribute(&mut self.rejection, rejection)?;\n        Ok(self)\n    }\n}\n\nfn expand_named_fields(\n    ident: &syn::Ident,\n    path: &LitStr,\n    segments: &[Segment],\n    rejection: Option<&syn::Path>,\n) -> TokenStream {\n    let format_str = format_str_from_path(segments);\n    let captures = captures_from_path(segments);\n\n    let typed_path_impl = quote_spanned! {path.span()=>\n        #[automatically_derived]\n        impl ::axum_extra::routing::TypedPath for #ident {\n            const PATH: &'static str = #path;\n        }\n    };\n\n    let display_impl = quote_spanned! {path.span()=>\n        #[automatically_derived]\n        impl ::std::fmt::Display for #ident {\n            #[allow(clippy::unnecessary_to_owned)]\n            #[allow(clippy::implicit_clone)]\n            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {\n                let Self { #(#captures,)* } = self;\n                write!(\n                    f,\n                    #format_str,\n                    #(\n                        #captures = ::axum_extra::__private::utf8_percent_encode(\n                            &#captures.to_string(),\n                            ::axum_extra::__private::PATH_SEGMENT,\n                        )\n                    ),*\n                )\n            }\n        }\n    };\n\n    let rejection_assoc_type = rejection_assoc_type(rejection);\n    let map_err_rejection = map_err_rejection(rejection);\n\n    let from_request_impl = quote! {\n        #[automatically_derived]\n        impl<S> ::axum::extract::FromRequestParts<S> for #ident\n        where\n            S: Send + Sync,\n        {\n            type Rejection = #rejection_assoc_type;\n\n            async fn from_request_parts(\n                parts: &mut ::axum::http::request::Parts,\n                state: &S,\n            ) -> ::std::result::Result<Self, Self::Rejection> {\n                <::axum::extract::Path<#ident> as ::axum::extract::FromRequestParts<S>>\n                    ::from_request_parts(parts, state)\n                    .await\n                    .map(|path| path.0)\n                    #map_err_rejection\n            }\n        }\n    };\n\n    quote! {\n        #typed_path_impl\n        #display_impl\n        #from_request_impl\n    }\n}\n\nfn expand_unnamed_fields(\n    fields: &syn::FieldsUnnamed,\n    ident: &syn::Ident,\n    path: &LitStr,\n    segments: &[Segment],\n    rejection: Option<&syn::Path>,\n) -> syn::Result<TokenStream> {\n    let num_captures = segments\n        .iter()\n        .filter(|segment| match segment {\n            Segment::Capture(_, _) => true,\n            Segment::Static(_) => false,\n        })\n        .count();\n    let num_fields = fields.unnamed.len();\n    if num_fields != num_captures {\n        return Err(syn::Error::new_spanned(\n            fields,\n            format!(\n                \"Mismatch in number of captures and fields. Path has {} but struct has {}\",\n                simple_pluralize(num_captures, \"capture\"),\n                simple_pluralize(num_fields, \"field\"),\n            ),\n        ));\n    }\n\n    let destructure_self = segments\n        .iter()\n        .filter_map(|segment| match segment {\n            Segment::Capture(capture, _) => Some(capture),\n            Segment::Static(_) => None,\n        })\n        .enumerate()\n        .map(|(idx, capture)| {\n            let idx = syn::Index {\n                index: idx as _,\n                span: Span::call_site(),\n            };\n            let capture = format_ident!(\"{}\", capture, span = path.span());\n            quote_spanned! {path.span()=>\n                #idx: #capture,\n            }\n        });\n\n    let format_str = format_str_from_path(segments);\n    let captures = captures_from_path(segments);\n\n    let typed_path_impl = quote_spanned! {path.span()=>\n        #[automatically_derived]\n        impl ::axum_extra::routing::TypedPath for #ident {\n            const PATH: &'static str = #path;\n        }\n    };\n\n    let display_impl = quote_spanned! {path.span()=>\n        #[automatically_derived]\n        impl ::std::fmt::Display for #ident {\n            #[allow(clippy::unnecessary_to_owned)]\n            #[allow(clippy::implicit_clone)]\n            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {\n                let Self { #(#destructure_self)* } = self;\n                write!(\n                    f,\n                    #format_str,\n                    #(\n                        #captures = ::axum_extra::__private::utf8_percent_encode(\n                            &#captures.to_string(),\n                            ::axum_extra::__private::PATH_SEGMENT,\n                        )\n                    ),*\n                )\n            }\n        }\n    };\n\n    let rejection_assoc_type = rejection_assoc_type(rejection);\n    let map_err_rejection = map_err_rejection(rejection);\n\n    let from_request_impl = quote! {\n        #[automatically_derived]\n        impl<S> ::axum::extract::FromRequestParts<S> for #ident\n        where\n            S: Send + Sync,\n        {\n            type Rejection = #rejection_assoc_type;\n\n            async fn from_request_parts(\n                parts: &mut ::axum::http::request::Parts,\n                state: &S,\n            ) -> ::std::result::Result<Self, Self::Rejection> {\n                ::axum::extract::Path::from_request_parts(parts, state)\n                    .await\n                    .map(|path| path.0)\n                    #map_err_rejection\n            }\n        }\n    };\n\n    Ok(quote! {\n        #typed_path_impl\n        #display_impl\n        #from_request_impl\n    })\n}\n\nfn simple_pluralize(count: usize, word: &str) -> String {\n    if count == 1 {\n        format!(\"{count} {word}\")\n    } else {\n        format!(\"{count} {word}s\")\n    }\n}\n\nfn expand_unit_fields(\n    ident: &syn::Ident,\n    path: &LitStr,\n    rejection: Option<&syn::Path>,\n) -> syn::Result<TokenStream> {\n    for segment in parse_path(path)? {\n        match segment {\n            Segment::Capture(_, span) => {\n                return Err(syn::Error::new(\n                    span,\n                    \"Typed paths for unit structs cannot contain captures\",\n                ));\n            }\n            Segment::Static(_) => {}\n        }\n    }\n\n    let typed_path_impl = quote_spanned! {path.span()=>\n        #[automatically_derived]\n        impl ::axum_extra::routing::TypedPath for #ident {\n            const PATH: &'static str = #path;\n        }\n    };\n\n    let display_impl = quote_spanned! {path.span()=>\n        #[automatically_derived]\n        impl ::std::fmt::Display for #ident {\n            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {\n                write!(f, #path)\n            }\n        }\n    };\n\n    let rejection_assoc_type = if let Some(rejection) = &rejection {\n        quote! { #rejection }\n    } else {\n        quote! { ::axum::http::StatusCode }\n    };\n    let create_rejection = if let Some(rejection) = &rejection {\n        quote! {\n            Err(<#rejection as ::std::default::Default>::default())\n        }\n    } else {\n        quote! {\n            Err(::axum::http::StatusCode::NOT_FOUND)\n        }\n    };\n\n    let from_request_impl = quote! {\n        #[automatically_derived]\n        impl<S> ::axum::extract::FromRequestParts<S> for #ident\n        where\n            S: Send + Sync,\n        {\n            type Rejection = #rejection_assoc_type;\n\n            async fn from_request_parts(\n                parts: &mut ::axum::http::request::Parts,\n                _state: &S,\n            ) -> ::std::result::Result<Self, Self::Rejection> {\n                if parts.uri.path() == <Self as ::axum_extra::routing::TypedPath>::PATH {\n                    Ok(Self)\n                } else {\n                    #create_rejection\n                }\n            }\n        }\n    };\n\n    Ok(quote! {\n        #typed_path_impl\n        #display_impl\n        #from_request_impl\n    })\n}\n\nfn format_str_from_path(segments: &[Segment]) -> String {\n    segments\n        .iter()\n        .map(|segment| match segment {\n            Segment::Capture(capture, _) => format!(\"{{{capture}}}\"),\n            Segment::Static(segment) => segment.to_owned(),\n        })\n        .collect::<Vec<_>>()\n        .join(\"/\")\n}\n\nfn captures_from_path(segments: &[Segment]) -> Vec<syn::Ident> {\n    segments\n        .iter()\n        .filter_map(|segment| match segment {\n            Segment::Capture(capture, span) => Some(format_ident!(\"{}\", capture, span = *span)),\n            Segment::Static(_) => None,\n        })\n        .collect::<Vec<_>>()\n}\n\nfn parse_path(path: &LitStr) -> syn::Result<Vec<Segment>> {\n    let value = path.value();\n    if value.is_empty() {\n        return Err(syn::Error::new_spanned(\n            path,\n            \"paths must start with a `/`. Use \\\"/\\\" for root routes\",\n        ));\n    } else if !path.value().starts_with('/') {\n        return Err(syn::Error::new_spanned(path, \"paths must start with a `/`\"));\n    }\n\n    path.value()\n        .split('/')\n        .map(|segment| {\n            if let Some(capture) = segment\n                .strip_prefix('{')\n                .and_then(|segment| segment.strip_suffix('}'))\n                .and_then(|segment| {\n                    (!segment.starts_with('{') && !segment.ends_with('}')).then_some(segment)\n                })\n                .map(|capture| capture.strip_prefix('*').unwrap_or(capture))\n            {\n                Ok(Segment::Capture(capture.to_owned(), path.span()))\n            } else {\n                Ok(Segment::Static(segment.to_owned()))\n            }\n        })\n        .collect()\n}\n\nenum Segment {\n    Capture(String, Span),\n    Static(String),\n}\n\nfn path_rejection() -> TokenStream {\n    quote! {\n        <::axum::extract::Path<Self> as ::axum::extract::FromRequestParts<S>>::Rejection\n    }\n}\n\nfn rejection_assoc_type(rejection: Option<&syn::Path>) -> TokenStream {\n    match rejection {\n        Some(rejection) => quote! { #rejection },\n        None => path_rejection(),\n    }\n}\n\nfn map_err_rejection(rejection: Option<&syn::Path>) -> TokenStream {\n    rejection\n        .as_ref()\n        .map(|rejection| {\n            let path_rejection = path_rejection();\n            quote! {\n                .map_err(|rejection| {\n                    <#rejection as ::std::convert::From<#path_rejection>>::from(rejection)\n                })\n            }\n        })\n        .unwrap_or_default()\n}\n\n#[test]\nfn ui() {\n    crate::run_ui_tests(\"typed_path\");\n}\n"
  },
  {
    "path": "axum-macros/src/with_position.rs",
    "content": "// this is copied from itertools under the following license\n//\n// Copyright (c) 2015\n//\n// Permission is hereby granted, free of charge, to any\n// person obtaining a copy of this software and associated\n// documentation files (the \"Software\"), to deal in the\n// Software without restriction, including without\n// limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of\n// the Software, and to permit persons to whom the Software\n// is furnished to do so, subject to the following\n// conditions:\n//\n// The above copyright notice and this permission notice\n// shall be included in all copies or substantial portions\n// of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\n// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\n// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\n// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\n// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nuse std::iter::{Fuse, FusedIterator, Peekable};\n\npub(crate) struct WithPosition<I>\nwhere\n    I: Iterator,\n{\n    handled_first: bool,\n    peekable: Peekable<Fuse<I>>,\n}\n\nimpl<I> WithPosition<I>\nwhere\n    I: Iterator,\n{\n    pub(crate) fn new(iter: impl IntoIterator<IntoIter = I>) -> Self {\n        Self {\n            handled_first: false,\n            peekable: iter.into_iter().fuse().peekable(),\n        }\n    }\n}\n\nimpl<I> Clone for WithPosition<I>\nwhere\n    I: Clone + Iterator,\n    I::Item: Clone,\n{\n    fn clone(&self) -> Self {\n        Self {\n            handled_first: self.handled_first,\n            peekable: self.peekable.clone(),\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq)]\npub(crate) enum Position<T> {\n    First(T),\n    Middle(T),\n    Last(T),\n    Only(T),\n}\n\nimpl<T> Position<T> {\n    pub(crate) fn into_inner(self) -> T {\n        match self {\n            Self::First(x) | Self::Middle(x) | Self::Last(x) | Self::Only(x) => x,\n        }\n    }\n}\n\nimpl<I: Iterator> Iterator for WithPosition<I> {\n    type Item = Position<I::Item>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        match self.peekable.next() {\n            Some(item) => {\n                if !self.handled_first {\n                    // Haven't seen the first item yet, and there is one to give.\n                    self.handled_first = true;\n                    // Peek to see if this is also the last item,\n                    // in which case tag it as `Only`.\n                    match self.peekable.peek() {\n                        Some(_) => Some(Position::First(item)),\n                        None => Some(Position::Only(item)),\n                    }\n                } else {\n                    // Have seen the first item, and there's something left.\n                    // Peek to see if this is the last item.\n                    match self.peekable.peek() {\n                        Some(_) => Some(Position::Middle(item)),\n                        None => Some(Position::Last(item)),\n                    }\n                }\n            }\n            // Iterator is finished.\n            None => None,\n        }\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.peekable.size_hint()\n    }\n}\n\nimpl<I> ExactSizeIterator for WithPosition<I> where I: ExactSizeIterator {}\n\nimpl<I: Iterator> FusedIterator for WithPosition<I> {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/.gitkeep",
    "content": ""
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/argument_not_extractor.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler(_foo: bool) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/argument_not_extractor.stderr",
    "content": "error[E0277]: the trait bound `bool: FromRequest<(), axum_core::extract::private::ViaParts>` is not satisfied\n --> tests/debug_handler/fail/argument_not_extractor.rs:4:24\n  |\n4 | async fn handler(_foo: bool) {}\n  |                        ^^^^ the trait `FromRequestParts<()>` is not implemented for `bool`\n  |\n  = note: Function argument is not a valid axum extractor.\n          See `https://docs.rs/axum/0.8/axum/extract/index.html` for details\n  = help: the following other types implement trait `FromRequestParts<S>`:\n            `ConnectInfo<T>` implements `FromRequestParts<S>`\n            `Extension<T>` implements `FromRequestParts<S>`\n            `HeaderMap` implements `FromRequestParts<S>`\n            `MatchedPath` implements `FromRequestParts<S>`\n            `Method` implements `FromRequestParts<S>`\n            `OriginalUri` implements `FromRequestParts<S>`\n            `Query<T>` implements `FromRequestParts<S>`\n            `RawPathParams` implements `FromRequestParts<S>`\n          and $N others\n  = note: required for `bool` to implement `FromRequest<(), axum_core::extract::private::ViaParts>`\nnote: required by a bound in `__axum_macros_check_handler_0_from_request_check`\n --> tests/debug_handler/fail/argument_not_extractor.rs:4:24\n  |\n4 | async fn handler(_foo: bool) {}\n  |                        ^^^^ required by this bound in `__axum_macros_check_handler_0_from_request_check`\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/duplicate_args.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler(state = (), state = ())]\nasync fn handler() {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/duplicate_args.stderr",
    "content": "error: `state` specified more than once\n --> tests/debug_handler/fail/duplicate_args.rs:3:29\n  |\n3 | #[debug_handler(state = (), state = ())]\n  |                             ^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/extension_not_clone.rs",
    "content": "use axum::extract::Extension;\nuse axum_macros::debug_handler;\n\nstruct NonCloneType;\n\n#[debug_handler]\nasync fn test_extension_non_clone(_: Extension<NonCloneType>) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/extension_not_clone.stderr",
    "content": "error[E0277]: the trait bound `NonCloneType: Clone` is not satisfied\n --> tests/debug_handler/fail/extension_not_clone.rs:7:38\n  |\n7 | async fn test_extension_non_clone(_: Extension<NonCloneType>) {}\n  |                                      ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `NonCloneType`\n  |\n  = help: the following other types implement trait `FromRequest<S, M>`:\n            Body\n            Form<T>\n            Json<T>\n            RawForm\n            Result<T, <T as FromRequest<S>>::Rejection>\n            String\n            axum::body::Bytes\n            axum::http::Request<Body>\n  = note: required for `Extension<NonCloneType>` to implement `FromRequestParts<()>`\n  = note: required for `Extension<NonCloneType>` to implement `FromRequest<(), axum_core::extract::private::ViaParts>`\nnote: required by a bound in `__axum_macros_check_test_extension_non_clone_0_from_request_check`\n --> tests/debug_handler/fail/extension_not_clone.rs:7:38\n  |\n7 | async fn test_extension_non_clone(_: Extension<NonCloneType>) {}\n  |                                      ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `__axum_macros_check_test_extension_non_clone_0_from_request_check`\nhelp: consider annotating `NonCloneType` with `#[derive(Clone)]`\n  |\n4 + #[derive(Clone)]\n5 | struct NonCloneType;\n  |\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/extract_self_mut.rs",
    "content": "use axum::extract::{FromRequest, Request};\nuse axum_macros::debug_handler;\n\nstruct A;\n\nimpl<S> FromRequest<S> for A\nwhere\n    S: Send + Sync,\n{\n    type Rejection = ();\n\n    async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        unimplemented!()\n    }\n}\n\nimpl A {\n    #[debug_handler]\n    async fn handler(&mut self) {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/extract_self_mut.stderr",
    "content": "error: Handlers must only take owned values\n  --> tests/debug_handler/fail/extract_self_mut.rs:19:22\n   |\n19 |     async fn handler(&mut self) {}\n   |                      ^^^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/extract_self_ref.rs",
    "content": "use axum::extract::{FromRequest, Request};\nuse axum_macros::debug_handler;\n\nstruct A;\n\nimpl<S> FromRequest<S> for A\nwhere\n    S: Send + Sync,\n{\n    type Rejection = ();\n\n    async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        unimplemented!()\n    }\n}\n\nimpl A {\n    #[debug_handler]\n    async fn handler(&self) {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/extract_self_ref.stderr",
    "content": "error: Handlers must only take owned values\n  --> tests/debug_handler/fail/extract_self_ref.rs:19:22\n   |\n19 |     async fn handler(&self) {}\n   |                      ^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/generics.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler<T>(_extract: T) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/generics.stderr",
    "content": "error: `#[axum_macros::debug_handler]` doesn't support generic functions\n --> tests/debug_handler/fail/generics.rs:4:17\n  |\n4 | async fn handler<T>(_extract: T) {}\n  |                 ^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/invalid_attrs.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler(foo)]\nasync fn handler() {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/invalid_attrs.stderr",
    "content": "error: expected `state`\n --> tests/debug_handler/fail/invalid_attrs.rs:3:17\n  |\n3 | #[debug_handler(foo)]\n  |                 ^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/json_not_deserialize.rs",
    "content": "use axum::Json;\nuse axum_macros::debug_handler;\n\nstruct Struct {}\n\n#[debug_handler]\nasync fn handler(_foo: Json<Struct>) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/json_not_deserialize.stderr",
    "content": "error[E0277]: the trait bound `Struct: serde::Deserialize<'de>` is not satisfied\n --> tests/debug_handler/fail/json_not_deserialize.rs:7:24\n  |\n7 | async fn handler(_foo: Json<Struct>) {}\n  |                        ^^^^^^^^^^^^ unsatisfied trait bound\n  |\nhelp: the trait `for<'de> serde_core::de::Deserialize<'de>` is not implemented for `Struct`\n --> tests/debug_handler/fail/json_not_deserialize.rs:4:1\n  |\n4 | struct Struct {}\n  | ^^^^^^^^^^^^^\n  = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `Struct` type\n  = note: for types from other crates check whether the crate offers a `serde` feature flag\n  = help: the following other types implement trait `serde_core::de::Deserialize<'de>`:\n            &'a [u8]\n            &'a serde_json::raw::RawValue\n            &'a std::path::Path\n            &'a str\n            ()\n            (T,)\n            (T0, T1)\n            (T0, T1, T2)\n          and $N others\n  = note: required for `Struct` to implement `serde_core::de::DeserializeOwned`\n  = note: required for `Json<Struct>` to implement `FromRequest<()>`\n  = help: see issue #48214\nhelp: add `#![feature(trivial_bounds)]` to the crate attributes to enable\n  |\n1 + #![feature(trivial_bounds)]\n  |\n\nerror[E0277]: the trait bound `Struct: serde::Deserialize<'de>` is not satisfied\n --> tests/debug_handler/fail/json_not_deserialize.rs:7:24\n  |\n7 | async fn handler(_foo: Json<Struct>) {}\n  |                        ^^^^^^^^^^^^ unsatisfied trait bound\n  |\nhelp: the trait `for<'de> serde_core::de::Deserialize<'de>` is not implemented for `Struct`\n --> tests/debug_handler/fail/json_not_deserialize.rs:4:1\n  |\n4 | struct Struct {}\n  | ^^^^^^^^^^^^^\n  = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `Struct` type\n  = note: for types from other crates check whether the crate offers a `serde` feature flag\n  = help: the following other types implement trait `serde_core::de::Deserialize<'de>`:\n            &'a [u8]\n            &'a serde_json::raw::RawValue\n            &'a std::path::Path\n            &'a str\n            ()\n            (T,)\n            (T0, T1)\n            (T0, T1, T2)\n          and $N others\n  = note: required for `Struct` to implement `serde_core::de::DeserializeOwned`\n  = note: required for `Json<Struct>` to implement `FromRequest<()>`\nnote: required by a bound in `__axum_macros_check_handler_0_from_request_check`\n --> tests/debug_handler/fail/json_not_deserialize.rs:7:24\n  |\n7 | async fn handler(_foo: Json<Struct>) {}\n  |                        ^^^^^^^^^^^^ required by this bound in `__axum_macros_check_handler_0_from_request_check`\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/multiple_paths.rs",
    "content": "use axum::extract::Path;\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler(_: Path<String>, _: Path<String>) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/multiple_paths.stderr",
    "content": "error: Multiple parameters must be extracted with a tuple `Path<(_, _)>` or a struct `Path<YourParams>`, not by applying multiple `Path<_>` extractors\n --> tests/debug_handler/fail/multiple_paths.rs:5:18\n  |\n5 | async fn handler(_: Path<String>, _: Path<String>) {}\n  |                  ^^^^^^^^^^^^^^^\n\nerror: Multiple parameters must be extracted with a tuple `Path<(_, _)>` or a struct `Path<YourParams>`, not by applying multiple `Path<_>` extractors\n --> tests/debug_handler/fail/multiple_paths.rs:5:35\n  |\n5 | async fn handler(_: Path<String>, _: Path<String>) {}\n  |                                   ^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/multiple_request_consumers.rs",
    "content": "use axum::{\n    body::Bytes,\n    http::{Method, Uri},\n    Json,\n};\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn one(_: Json<()>, _: String, _: Uri) {}\n\n#[debug_handler]\nasync fn two(_: Json<()>, _: Method, _: Bytes, _: Uri, _: String) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/multiple_request_consumers.stderr",
    "content": "error: Can't have two extractors that consume the request body. `Json<_>` and `String` both do that.\n --> tests/debug_handler/fail/multiple_request_consumers.rs:9:14\n  |\n9 | async fn one(_: Json<()>, _: String, _: Uri) {}\n  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: Can't have more than one extractor that consume the request body. `Json<_>`, `Bytes`, and `String` all do that.\n  --> tests/debug_handler/fail/multiple_request_consumers.rs:12:14\n   |\n12 | async fn two(_: Json<()>, _: Method, _: Bytes, _: Uri, _: String) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/not_a_function.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler]\nstruct A;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/not_a_function.stderr",
    "content": "error: expected `fn`\n --> tests/debug_handler/fail/not_a_function.rs:4:1\n  |\n4 | struct A;\n  | ^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/not_async.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler]\nfn handler() {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/not_async.stderr",
    "content": "error: Handlers must be `async fn`s\n --> tests/debug_handler/fail/not_async.rs:4:1\n  |\n4 | fn handler() {}\n  | ^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/not_send.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler() {\n    let _rc = std::rc::Rc::new(());\n    async {}.await;\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/not_send.stderr",
    "content": "error: future cannot be sent between threads safely\n --> tests/debug_handler/fail/not_send.rs:3:1\n  |\n3 | #[debug_handler]\n  | ^^^^^^^^^^^^^^^^ future returned by `handler` is not `Send`\n  |\n  = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`\nnote: future is not `Send` as this value is used across an await\n --> tests/debug_handler/fail/not_send.rs:6:14\n  |\n5 |     let _rc = std::rc::Rc::new(());\n  |         --- has type `Rc<()>` which is not `Send`\n6 |     async {}.await;\n  |              ^^^^^ await occurs here, with `_rc` maybe used later\nnote: required by a bound in `check`\n --> tests/debug_handler/fail/not_send.rs:3:1\n  |\n3 | #[debug_handler]\n  | ^^^^^^^^^^^^^^^^ required by this bound in `check`\n  = note: this error originates in the attribute macro `debug_handler` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/output_tuple_too_many.rs",
    "content": "use axum::response::AppendHeaders;\n\n#[axum::debug_handler]\nasync fn handler() -> (\n    axum::http::StatusCode,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n    axum::http::StatusCode,\n) {\n    panic!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/output_tuple_too_many.stderr",
    "content": "error: Cannot return tuples with more than 17 elements\n  --> tests/debug_handler/fail/output_tuple_too_many.rs:4:20\n   |\n 4 |   async fn handler() -> (\n   |  ____________________^\n 5 | |     axum::http::StatusCode,\n 6 | |     AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n 7 | |     AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n...  |\n23 | |     axum::http::StatusCode,\n24 | | ) {\n   | |_^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/returning_request_parts.rs",
    "content": "#[axum::debug_handler]\nasync fn handler() -> (\n    axum::http::request::Parts, // this should be response parts, not request parts\n    axum::http::StatusCode,\n) {\n    panic!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/returning_request_parts.stderr",
    "content": "error[E0308]: mismatched types\n --> tests/debug_handler/fail/returning_request_parts.rs:3:5\n  |\n3 |     axum::http::request::Parts, // this should be response parts, not request parts\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n  |     |\n  |     expected `axum::http::response::Parts`, found `axum::http::request::Parts`\n  |     expected `axum::http::response::Parts` because of return type\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/single_wrong_return_tuple.rs",
    "content": "#![allow(unused_parens)]\n\nstruct NotIntoResponse;\n\n#[axum::debug_handler]\nasync fn handler() -> (NotIntoResponse) {\n    panic!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/single_wrong_return_tuple.stderr",
    "content": "error[E0277]: the trait bound `NotIntoResponse: IntoResponse` is not satisfied\n --> tests/debug_handler/fail/single_wrong_return_tuple.rs:6:23\n  |\n6 | async fn handler() -> (NotIntoResponse) {\n  |                       ^^^^^^^^^^^^^^^^^ unsatisfied trait bound\n  |\nhelp: the trait `IntoResponse` is not implemented for `NotIntoResponse`\n --> tests/debug_handler/fail/single_wrong_return_tuple.rs:3:1\n  |\n3 | struct NotIntoResponse;\n  | ^^^^^^^^^^^^^^^^^^^^^^\n  = help: the following other types implement trait `IntoResponse`:\n            &'static [u8; N]\n            &'static [u8]\n            &'static str\n            ()\n            (R,)\n            (Response<()>, R)\n            (Response<()>, T1, R)\n            (Response<()>, T1, T2, R)\n          and $N others\nnote: required by a bound in `__axum_macros_check_handler_into_response::{closure#0}::check`\n --> tests/debug_handler/fail/single_wrong_return_tuple.rs:6:23\n  |\n6 | async fn handler() -> (NotIntoResponse) {\n  |                       ^^^^^^^^^^^^^^^^^ required by this bound in `check`\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/too_many_extractors.rs",
    "content": "use axum::http::Uri;\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler(\n    _e1: Uri,\n    _e2: Uri,\n    _e3: Uri,\n    _e4: Uri,\n    _e5: Uri,\n    _e6: Uri,\n    _e7: Uri,\n    _e8: Uri,\n    _e9: Uri,\n    _e10: Uri,\n    _e11: Uri,\n    _e12: Uri,\n    _e13: Uri,\n    _e14: Uri,\n    _e15: Uri,\n    _e16: Uri,\n    _e17: Uri,\n) {\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/too_many_extractors.stderr",
    "content": "error: Handlers cannot take more than 16 arguments. Use `(a, b): (ExtractorA, ExtractorA)` to further nest extractors\n  --> tests/debug_handler/fail/too_many_extractors.rs:6:5\n   |\n 6 | /     _e1: Uri,\n 7 | |     _e2: Uri,\n 8 | |     _e3: Uri,\n 9 | |     _e4: Uri,\n...  |\n21 | |     _e16: Uri,\n22 | |     _e17: Uri,\n   | |______________^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/wrong_order.rs",
    "content": "use axum::{http::Uri, Json};\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn one(_: Json<()>, _: Uri) {}\n\n#[debug_handler]\nasync fn two(_: String, _: Uri) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/wrong_order.stderr",
    "content": "error: `Json<_>` consumes the request body and thus must be the last argument to the handler function\n --> tests/debug_handler/fail/wrong_order.rs:5:17\n  |\n5 | async fn one(_: Json<()>, _: Uri) {}\n  |                 ^^^^^^^^\n\nerror: `String` consumes the request body and thus must be the last argument to the handler function\n --> tests/debug_handler/fail/wrong_order.rs:8:17\n  |\n8 | async fn two(_: String, _: Uri) {}\n  |                 ^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/wrong_return_tuple.rs",
    "content": "#![allow(unused_parens)]\n\n#[axum::debug_handler]\nasync fn named_type() -> (\n    axum::http::StatusCode,\n    axum::Json<&'static str>,\n    axum::response::AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n) {\n    panic!()\n}\n\nstruct CustomIntoResponse {}\nimpl axum::response::IntoResponse for CustomIntoResponse {\n    fn into_response(self) -> axum::response::Response {\n        todo!()\n    }\n}\n#[axum::debug_handler]\nasync fn custom_type() -> (\n    axum::http::StatusCode,\n    CustomIntoResponse,\n    axum::response::AppendHeaders<[(axum::http::HeaderName, &'static str); 1]>,\n) {\n    panic!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/wrong_return_tuple.stderr",
    "content": "error: `Json<_>` must be the last element in a response tuple\n --> tests/debug_handler/fail/wrong_return_tuple.rs:6:5\n  |\n6 |     axum::Json<&'static str>,\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror[E0277]: the trait bound `CustomIntoResponse: IntoResponseParts` is not satisfied\n  --> tests/debug_handler/fail/wrong_return_tuple.rs:21:5\n   |\n21 |     CustomIntoResponse,\n   |     ^^^^^^^^^^^^^^^^^^ unsatisfied trait bound\n   |\nhelp: the trait `IntoResponseParts` is not implemented for `CustomIntoResponse`\n  --> tests/debug_handler/fail/wrong_return_tuple.rs:12:1\n   |\n12 | struct CustomIntoResponse {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: the following other types implement trait `IntoResponseParts`:\n             ()\n             (T1, T2)\n             (T1, T2, T3)\n             (T1, T2, T3, T4)\n             (T1, T2, T3, T4, T5)\n             (T1, T2, T3, T4, T5, T6)\n             (T1, T2, T3, T4, T5, T6, T7)\n             (T1, T2, T3, T4, T5, T6, T7, T8)\n           and $N others\n   = help: see issue #48214\nhelp: add `#![feature(trivial_bounds)]` to the crate attributes to enable\n   |\n 3 + #![feature(trivial_bounds)]\n   |\n\nerror[E0277]: the trait bound `CustomIntoResponse: IntoResponseParts` is not satisfied\n  --> tests/debug_handler/fail/wrong_return_tuple.rs:21:5\n   |\n21 |     CustomIntoResponse,\n   |     ^^^^^^^^^^^^^^^^^^ unsatisfied trait bound\n   |\nhelp: the trait `IntoResponseParts` is not implemented for `CustomIntoResponse`\n  --> tests/debug_handler/fail/wrong_return_tuple.rs:12:1\n   |\n12 | struct CustomIntoResponse {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: the following other types implement trait `IntoResponseParts`:\n             ()\n             (T1, T2)\n             (T1, T2, T3)\n             (T1, T2, T3, T4)\n             (T1, T2, T3, T4, T5)\n             (T1, T2, T3, T4, T5, T6)\n             (T1, T2, T3, T4, T5, T6, T7)\n             (T1, T2, T3, T4, T5, T6, T7, T8)\n           and $N others\nnote: required by a bound in `__axum_macros_check_custom_type_into_response_parts_1_check`\n  --> tests/debug_handler/fail/wrong_return_tuple.rs:21:5\n   |\n21 |     CustomIntoResponse,\n   |     ^^^^^^^^^^^^^^^^^^ required by this bound in `__axum_macros_check_custom_type_into_response_parts_1_check`\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/wrong_return_type.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler() -> bool {\n    false\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/fail/wrong_return_type.stderr",
    "content": "error[E0277]: the trait bound `bool: IntoResponse` is not satisfied\n --> tests/debug_handler/fail/wrong_return_type.rs:4:23\n  |\n4 | async fn handler() -> bool {\n  |                       ^^^^ the trait `IntoResponse` is not implemented for `bool`\n  |\n  = help: the following other types implement trait `IntoResponse`:\n            &'static [u8; N]\n            &'static [u8]\n            &'static str\n            ()\n            (R,)\n            (Response<()>, R)\n            (Response<()>, T1, R)\n            (Response<()>, T1, T2, R)\n          and $N others\nnote: required by a bound in `__axum_macros_check_handler_into_response::{closure#0}::check`\n --> tests/debug_handler/fail/wrong_return_type.rs:4:23\n  |\n4 | async fn handler() -> bool {\n  |                       ^^^^ required by this bound in `check`\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/associated_fn_without_self.rs",
    "content": "use axum_macros::debug_handler;\n\nstruct A;\n\nimpl A {\n    #[debug_handler]\n    async fn handler() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/deny_unreachable_code.rs",
    "content": "#![deny(unreachable_code)]\n\nuse axum::extract::Path;\n\n#[axum_macros::debug_handler]\nasync fn handler(Path(_): Path<String>) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/impl_future.rs",
    "content": "use axum_macros::debug_handler;\nuse std::future::Future;\n\n#[debug_handler]\nfn handler() -> impl Future<Output = ()> {\n    async {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/impl_into_response.rs",
    "content": "use axum::response::IntoResponse;\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler() -> impl IntoResponse {\n    \"hi!\"\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/infer_state.rs",
    "content": "use axum::extract::State;\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler(_: State<AppState>) {}\n\n#[debug_handler]\nasync fn handler_2(_: axum::extract::State<AppState>) {}\n\n#[debug_handler]\nasync fn handler_3(_: axum::extract::State<AppState>, _: axum::extract::State<AppState>) {}\n\n#[debug_handler]\nasync fn handler_4(_: State<AppState>, _: State<AppState>) {}\n\n#[debug_handler]\nasync fn handler_5(_: axum::extract::State<AppState>, _: State<AppState>) {}\n\n#[derive(Clone)]\nstruct AppState;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/multiple_extractors.rs",
    "content": "use axum::http::{Method, Uri};\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler(_one: Method, _two: Uri, _three: String) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/mut_extractor.rs",
    "content": "use axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler(mut foo: String) -> String {\n    foo += \"bar\";\n    foo\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/ready.rs",
    "content": "use axum_macros::debug_handler;\nuse std::future::{ready, Ready};\n\n#[debug_handler]\nfn handler() -> Ready<()> {\n    ready(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/request_last.rs",
    "content": "use axum::extract::{Extension, Request};\nuse axum_macros::debug_handler;\n\n#[debug_handler]\nasync fn handler(_: Extension<String>, _: Request) {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/result_impl_into_response.rs",
    "content": "use axum::{extract::FromRequestParts, http::request::Parts, response::IntoResponse};\nuse axum_macros::debug_handler;\n\nfn main() {}\n\n#[debug_handler]\nfn concrete_future() -> std::future::Ready<Result<impl IntoResponse, ()>> {\n    std::future::ready(Ok(()))\n}\n\n#[debug_handler]\nfn impl_future() -> impl std::future::Future<Output = Result<impl IntoResponse, ()>> {\n    std::future::ready(Ok(()))\n}\n\n// === no args ===\n\n#[debug_handler]\nasync fn handler_no_arg_one() -> Result<impl IntoResponse, ()> {\n    Ok(())\n}\n\n#[debug_handler]\nasync fn handler_no_arg_two() -> Result<(), impl IntoResponse> {\n    Err(())\n}\n\n#[debug_handler]\nasync fn handler_no_arg_three() -> Result<impl IntoResponse, impl IntoResponse> {\n    Ok::<_, ()>(())\n}\n\n#[debug_handler]\nasync fn handler_no_arg_four() -> Result<impl IntoResponse, impl IntoResponse> {\n    Err::<(), _>(())\n}\n\n// === args ===\n\n#[debug_handler]\nasync fn handler_one(foo: String) -> Result<impl IntoResponse, ()> {\n    dbg!(foo);\n    Ok(())\n}\n\n#[debug_handler]\nasync fn handler_two(foo: String) -> Result<(), impl IntoResponse> {\n    dbg!(foo);\n    Err(())\n}\n\n#[debug_handler]\nasync fn handler_three(foo: String) -> Result<impl IntoResponse, impl IntoResponse> {\n    dbg!(foo);\n    Ok::<_, ()>(())\n}\n\n#[debug_handler]\nasync fn handler_four(foo: String) -> Result<impl IntoResponse, impl IntoResponse> {\n    dbg!(foo);\n    Err::<(), _>(())\n}\n\n// === no args with receiver ===\n\nstruct A;\n\nimpl A {\n    #[debug_handler]\n    async fn handler_no_arg_one(self) -> Result<impl IntoResponse, ()> {\n        Ok(())\n    }\n\n    #[debug_handler]\n    async fn handler_no_arg_two(self) -> Result<(), impl IntoResponse> {\n        Err(())\n    }\n\n    #[debug_handler]\n    async fn handler_no_arg_three(self) -> Result<impl IntoResponse, impl IntoResponse> {\n        Ok::<_, ()>(())\n    }\n\n    #[debug_handler]\n    async fn handler_no_arg_four(self) -> Result<impl IntoResponse, impl IntoResponse> {\n        Err::<(), _>(())\n    }\n}\n\n// === args with receiver ===\n\nimpl A {\n    #[debug_handler]\n    async fn handler_one(self, foo: String) -> Result<impl IntoResponse, ()> {\n        dbg!(foo);\n        Ok(())\n    }\n\n    #[debug_handler]\n    async fn handler_two(self, foo: String) -> Result<(), impl IntoResponse> {\n        dbg!(foo);\n        Err(())\n    }\n\n    #[debug_handler]\n    async fn handler_three(self, foo: String) -> Result<impl IntoResponse, impl IntoResponse> {\n        dbg!(foo);\n        Ok::<_, ()>(())\n    }\n\n    #[debug_handler]\n    async fn handler_four(self, foo: String) -> Result<impl IntoResponse, impl IntoResponse> {\n        dbg!(foo);\n        Err::<(), _>(())\n    }\n}\n\nimpl<S> FromRequestParts<S> for A\nwhere\n    S: Send + Sync,\n{\n    type Rejection = ();\n\n    async fn from_request_parts(_parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        unimplemented!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/returns_self.rs",
    "content": "use axum::response::{IntoResponse, Response};\nuse axum_macros::debug_handler;\n\nstruct A;\n\nimpl A {\n    #[debug_handler]\n    async fn handler() -> Self {\n        A\n    }\n}\n\nimpl IntoResponse for A {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/self_receiver.rs",
    "content": "use axum::extract::{FromRequest, Request};\nuse axum_macros::debug_handler;\n\nstruct A;\n\nimpl<S> FromRequest<S> for A\nwhere\n    S: Send + Sync,\n{\n    type Rejection = ();\n\n    async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        unimplemented!()\n    }\n}\n\nimpl<S> FromRequest<S> for Box<A>\nwhere\n    S: Send + Sync,\n{\n    type Rejection = ();\n\n    async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        unimplemented!()\n    }\n}\n\nimpl A {\n    #[debug_handler]\n    async fn handler(self) {}\n\n    #[debug_handler]\n    async fn handler_with_qualified_self(self: Box<Self>) {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/set_state.rs",
    "content": "use axum::extract::{FromRef, FromRequest, Request};\nuse axum_macros::debug_handler;\n\n#[debug_handler(state = AppState)]\nasync fn handler(_: A) {}\n\n#[derive(Clone)]\nstruct AppState;\n\nstruct A;\n\nimpl<S> FromRequest<S> for A\nwhere\n    S: Send + Sync,\n    AppState: FromRef<S>,\n{\n    type Rejection = ();\n\n    async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        unimplemented!()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_handler/pass/state_and_body.rs",
    "content": "use axum::{extract::Request, extract::State};\nuse axum_macros::debug_handler;\n\n#[debug_handler(state = AppState)]\nasync fn handler(_: State<AppState>, _: Request) {}\n\n#[derive(Clone)]\nstruct AppState;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_middleware/fail/doesnt_take_next.rs",
    "content": "use axum::{\n    debug_middleware,\n    extract::Request,\n    response::{IntoResponse, Response},\n};\n\n#[debug_middleware]\nasync fn my_middleware(request: Request) -> Response {\n    let _ = request;\n    ().into_response()\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_middleware/fail/doesnt_take_next.stderr",
    "content": "error: Middleware functions must take `axum::middleware::Next` as the last argument\n --> tests/debug_middleware/fail/doesnt_take_next.rs:7:1\n  |\n7 | #[debug_middleware]\n  | ^^^^^^^^^^^^^^^^^^^\n  |\n  = note: this error originates in the attribute macro `debug_middleware` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/debug_middleware/fail/next_not_last.rs",
    "content": "use axum::{debug_middleware, extract::Request, middleware::Next, response::Response};\n\n#[debug_middleware]\nasync fn my_middleware(next: Next, request: Request) -> Response {\n    next.run(request).await\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_middleware/fail/next_not_last.stderr",
    "content": "error: `axum::middleware::Next` must the last argument\n --> tests/debug_middleware/fail/next_not_last.rs:4:24\n  |\n4 | async fn my_middleware(next: Next, request: Request) -> Response {\n  |                        ^^^^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/debug_middleware/fail/takes_next_twice.rs",
    "content": "use axum::{debug_middleware, extract::Request, middleware::Next, response::Response};\n\n#[debug_middleware]\nasync fn my_middleware(request: Request, next: Next, next2: Next) -> Response {\n    let _ = next2;\n    next.run(request).await\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/debug_middleware/fail/takes_next_twice.stderr",
    "content": "error: Middleware functions can only take one argument of type `axum::middleware::Next`\n --> tests/debug_middleware/fail/takes_next_twice.rs:3:1\n  |\n3 | #[debug_middleware]\n  | ^^^^^^^^^^^^^^^^^^^\n  |\n  = note: this error originates in the attribute macro `debug_middleware` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/debug_middleware/pass/basic.rs",
    "content": "use axum::{debug_middleware, extract::Request, middleware::Next, response::Response};\n\n#[debug_middleware]\nasync fn my_middleware(request: Request, next: Next) -> Response {\n    next.run(request).await\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_ref/fail/generics.rs",
    "content": "use axum::extract::FromRef;\n\n#[derive(Clone, FromRef)]\nstruct AppState<T> {\n    foo: T,\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_ref/fail/generics.stderr",
    "content": "error: `#[derive(FromRef)]` doesn't support generics\n --> tests/from_ref/fail/generics.rs:4:16\n  |\n4 | struct AppState<T> {\n  |                ^^^\n"
  },
  {
    "path": "axum-macros/tests/from_ref/pass/basic.rs",
    "content": "use axum::{\n    extract::{FromRef, State},\n    routing::get,\n    Router,\n};\n\n// This will implement `FromRef` for each field in the struct.\n#[derive(Clone, FromRef)]\nstruct AppState {\n    auth_token: String,\n}\n\n// So those types can be extracted via `State`\nasync fn handler(_: State<String>) {}\n\nfn main() {\n    let state = AppState {\n        auth_token: Default::default(),\n    };\n\n    let _: axum::Router = Router::new().route(\"/\", get(handler)).with_state(state);\n}\n"
  },
  {
    "path": "axum-macros/tests/from_ref/pass/reference-types.rs",
    "content": "#![deny(noop_method_call)]\n\nuse axum_macros::FromRef;\n\n#[derive(FromRef)]\nstruct State {\n    inner: &'static str,\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_ref/pass/skip.rs",
    "content": "use axum_macros::FromRef;\n\n#[derive(Clone, FromRef)]\nstruct AppState {\n    auth_token: String,\n    #[from_ref(skip)]\n    also_string: String,\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/double_via_attr.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor(#[from_request(via(axum::Extension), via(axum::Extension))] State);\n\n#[derive(Clone)]\nstruct State;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/double_via_attr.stderr",
    "content": "error: `via` specified more than once\n --> tests/from_request/fail/double_via_attr.rs:4:55\n  |\n4 | struct Extractor(#[from_request(via(axum::Extension), via(axum::Extension))] State);\n  |                                                       ^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/enum_from_request_ident_in_variant.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest, Clone)]\n#[from_request(via(axum::Extension))]\nenum Extractor {\n    Foo {\n        #[from_request(via(axum::Extension))]\n        foo: (),\n    },\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/enum_from_request_ident_in_variant.stderr",
    "content": "error: `#[from_request(via(...))]` cannot be used inside variants\n --> tests/from_request/fail/enum_from_request_ident_in_variant.rs:7:24\n  |\n7 |         #[from_request(via(axum::Extension))]\n  |                        ^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/enum_from_request_on_variant.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest, Clone)]\n#[from_request(via(axum::Extension))]\nenum Extractor {\n    #[from_request(via(axum::Extension))]\n    Foo,\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/enum_from_request_on_variant.stderr",
    "content": "error: `#[from_request(via(...))]` cannot be used on variants\n --> tests/from_request/fail/enum_from_request_on_variant.rs:6:20\n  |\n6 |     #[from_request(via(axum::Extension))]\n  |                    ^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/enum_no_via.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest, Clone)]\nenum Extractor {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/enum_no_via.stderr",
    "content": "error: missing `#[from_request(via(...))]`\n --> tests/from_request/fail/enum_no_via.rs:3:10\n  |\n3 | #[derive(FromRequest, Clone)]\n  |          ^^^^^^^^^^^\n  |\n  = note: this error originates in the derive macro `FromRequest` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/generic.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor<T>(Option<T>);\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/generic.stderr",
    "content": "error: #[derive(FromRequest)] only supports generics on tuple structs that have exactly one field of the generic type\n --> tests/from_request/fail/generic.rs:4:21\n  |\n4 | struct Extractor<T>(Option<T>);\n  |                     ^^^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/generic_without_via.rs",
    "content": "use axum::{routing::get, Router};\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest, Clone)]\nstruct Extractor<T>(T);\n\nasync fn foo(_: Extractor<()>) {}\n\nfn main() {\n    _ = Router::<()>::new().route(\"/\", get(foo));\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/generic_without_via.stderr",
    "content": "error: #[derive(FromRequest)] only supports generics when used with #[from_request(via)]\n --> tests/from_request/fail/generic_without_via.rs:5:18\n  |\n5 | struct Extractor<T>(T);\n  |                  ^\n\nerror[E0277]: the trait bound `fn(Extractor<()>) -> impl Future<Output = ()> {foo}: Handler<_, _>` is not satisfied\n  --> tests/from_request/fail/generic_without_via.rs:10:44\n   |\n10 |     _ = Router::<()>::new().route(\"/\", get(foo));\n   |                                        --- ^^^ the trait `Handler<_, _>` is not implemented for fn item `fn(Extractor<()>) -> impl Future<Output = ()> {foo}`\n   |                                        |\n   |                                        required by a bound introduced by this call\n   |\n   = note: Consider using `#[axum::debug_handler]` to improve the error message\nnote: required by a bound in `axum::routing::get`\n  --> $WORKSPACE/axum/src/routing/method_routing.rs\n   |\n   | top_level_handler_fn!(get, GET);\n   | ^^^^^^^^^^^^^^^^^^^^^^---^^^^^^\n   | |                     |\n   | |                     required by a bound in this function\n   | required by this bound in `get`\n   = note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/generic_without_via_rejection.rs",
    "content": "use axum::{routing::get, Router};\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest, Clone)]\n#[from_request(rejection(Foo))]\nstruct Extractor<T>(T);\n\nasync fn foo(_: Extractor<()>) {}\n\nfn main() {\n    _ = Router::<()>::new().route(\"/\", get(foo));\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/generic_without_via_rejection.stderr",
    "content": "error: #[derive(FromRequest)] only supports generics when used with #[from_request(via)]\n --> tests/from_request/fail/generic_without_via_rejection.rs:6:18\n  |\n6 | struct Extractor<T>(T);\n  |                  ^\n\nerror[E0277]: the trait bound `fn(Extractor<()>) -> impl Future<Output = ()> {foo}: Handler<_, _>` is not satisfied\n  --> tests/from_request/fail/generic_without_via_rejection.rs:11:44\n   |\n11 |     _ = Router::<()>::new().route(\"/\", get(foo));\n   |                                        --- ^^^ the trait `Handler<_, _>` is not implemented for fn item `fn(Extractor<()>) -> impl Future<Output = ()> {foo}`\n   |                                        |\n   |                                        required by a bound introduced by this call\n   |\n   = note: Consider using `#[axum::debug_handler]` to improve the error message\nnote: required by a bound in `axum::routing::get`\n  --> $WORKSPACE/axum/src/routing/method_routing.rs\n   |\n   | top_level_handler_fn!(get, GET);\n   | ^^^^^^^^^^^^^^^^^^^^^^---^^^^^^\n   | |                     |\n   | |                     required by a bound in this function\n   | required by this bound in `get`\n   = note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/not_enum_or_struct.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nunion Extractor {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/not_enum_or_struct.stderr",
    "content": "error: expected `struct` or `enum`\n --> tests/from_request/fail/not_enum_or_struct.rs:4:1\n  |\n4 | union Extractor {}\n  | ^^^^^^^^^^^^^^^^^^\n\nerror: unions cannot have zero fields\n --> tests/from_request/fail/not_enum_or_struct.rs:4:1\n  |\n4 | union Extractor {}\n  | ^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/override_rejection_on_enum_without_via.rs",
    "content": "use axum::{\n    extract::rejection::ExtensionRejection,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\nasync fn handler(_: MyExtractor) {}\n\nasync fn handler_result(_: Result<MyExtractor, MyRejection>) {}\n\n#[derive(FromRequest, Clone)]\n#[from_request(rejection(MyRejection))]\nenum MyExtractor {}\n\nstruct MyRejection {}\n\nimpl From<ExtensionRejection> for MyRejection {\n    fn from(_: ExtensionRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/override_rejection_on_enum_without_via.stderr",
    "content": "error: cannot use `rejection` without `via`\n  --> tests/from_request/fail/override_rejection_on_enum_without_via.rs:18:16\n   |\n18 | #[from_request(rejection(MyRejection))]\n   |                ^^^^^^^^^\n\nerror[E0277]: the trait bound `fn(MyExtractor) -> impl Future<Output = ()> {handler}: Handler<_, _>` is not satisfied\n  --> tests/from_request/fail/override_rejection_on_enum_without_via.rs:10:50\n   |\n10 |     let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n   |                                              --- ^^^^^^^ the trait `Handler<_, _>` is not implemented for fn item `fn(MyExtractor) -> impl Future<Output = ()> {handler}`\n   |                                              |\n   |                                              required by a bound introduced by this call\n   |\n   = note: Consider using `#[axum::debug_handler]` to improve the error message\nnote: required by a bound in `axum::routing::get`\n  --> $WORKSPACE/axum/src/routing/method_routing.rs\n   |\n   | top_level_handler_fn!(get, GET);\n   | ^^^^^^^^^^^^^^^^^^^^^^---^^^^^^\n   | |                     |\n   | |                     required by a bound in this function\n   | required by this bound in `get`\n   = note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror[E0277]: the trait bound `fn(Result<MyExtractor, MyRejection>) -> impl Future<Output = ()> {handler_result}: Handler<_, _>` is not satisfied\n  --> tests/from_request/fail/override_rejection_on_enum_without_via.rs:10:64\n   |\n10 |     let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n   |                                                           ---- ^^^^^^^^^^^^^^ the trait `Handler<_, _>` is not implemented for fn item `fn(Result<MyExtractor, MyRejection>) -> impl Future<Output = ()> {handler_result}`\n   |                                                           |\n   |                                                           required by a bound introduced by this call\n   |\n   = note: Consider using `#[axum::debug_handler]` to improve the error message\nnote: required by a bound in `MethodRouter::<S>::post`\n  --> $WORKSPACE/axum/src/routing/method_routing.rs\n   |\n   |     chained_handler_fn!(post, POST);\n   |     ^^^^^^^^^^^^^^^^^^^^----^^^^^^^\n   |     |                   |\n   |     |                   required by a bound in this associated function\n   |     required by this bound in `MethodRouter::<S>::post`\n   = note: this error originates in the macro `chained_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/parts_extracting_body.rs",
    "content": "use axum::{extract::FromRequestParts, response::Response};\n\n#[derive(FromRequestParts)]\nstruct Extractor {\n    body: String,\n}\n\nfn assert_from_request()\nwhere\n    Extractor: FromRequestParts<(), Rejection = Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/parts_extracting_body.stderr",
    "content": "error[E0277]: the trait bound `String: FromRequestParts<_>` is not satisfied\n --> tests/from_request/fail/parts_extracting_body.rs:5:11\n  |\n5 |     body: String,\n  |           ^^^^^^ the trait `FromRequestParts<_>` is not implemented for `String`\n  |\n  = note: Function argument is not a valid axum extractor.\n          See `https://docs.rs/axum/0.8/axum/extract/index.html` for details\n  = help: the following other types implement trait `FromRequestParts<S>`:\n            `ConnectInfo<T>` implements `FromRequestParts<S>`\n            `Extension<T>` implements `FromRequestParts<S>`\n            `Extractor` implements `FromRequestParts<S>`\n            `HeaderMap` implements `FromRequestParts<S>`\n            `MatchedPath` implements `FromRequestParts<S>`\n            `Method` implements `FromRequestParts<S>`\n            `OriginalUri` implements `FromRequestParts<S>`\n            `Query<T>` implements `FromRequestParts<S>`\n          and $N others\n\nerror[E0282]: type annotations needed\n --> tests/from_request/fail/parts_extracting_body.rs:5:11\n  |\n5 |     body: String,\n  |           ^^^^^^ cannot infer type\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/state_infer_multiple_different_types.rs",
    "content": "use axum::extract::State;\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor {\n    inner_state: State<AppState>,\n    other_state: State<OtherState>,\n}\n\n#[derive(Clone)]\nstruct AppState {}\n\n#[derive(Clone)]\nstruct OtherState {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<AppState, Rejection = axum::response::Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/state_infer_multiple_different_types.stderr",
    "content": "error: can't infer state type, please add `#[from_request(state = MyStateType)]` attribute\n --> tests/from_request/fail/state_infer_multiple_different_types.rs:4:10\n  |\n4 | #[derive(FromRequest)]\n  |          ^^^^^^^^^^^\n  |\n  = note: this error originates in the derive macro `FromRequest` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/unknown_attr_container.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\n#[from_request(foo)]\nstruct Extractor;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/unknown_attr_container.stderr",
    "content": "error: expected one of: `via`, `rejection`, `state`\n --> tests/from_request/fail/unknown_attr_container.rs:4:16\n  |\n4 | #[from_request(foo)]\n  |                ^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/unknown_attr_field.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor(#[from_request(foo)] String);\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/unknown_attr_field.stderr",
    "content": "error: expected `via`\n --> tests/from_request/fail/unknown_attr_field.rs:4:33\n  |\n4 | struct Extractor(#[from_request(foo)] String);\n  |                                 ^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/via_on_container_and_field.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\n#[from_request(via(axum::Extension))]\nstruct Extractor(#[from_request(via(axum::Extension))] State);\n\n#[derive(Clone)]\nstruct State;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/fail/via_on_container_and_field.stderr",
    "content": "error: `#[from_request(via(...))]` on a field cannot be used together with `#[from_request(...)]` on the container\n --> tests/from_request/fail/via_on_container_and_field.rs:5:33\n  |\n5 | struct Extractor(#[from_request(via(axum::Extension))] State);\n  |                                 ^^^\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/container.rs",
    "content": "use axum::extract::{\n    rejection::JsonRejection,\n    FromRequest,\n    Json,\n};\nuse serde::Deserialize;\n\n#[derive(Deserialize, FromRequest)]\n#[from_request(via(Json))]\nstruct Extractor {\n    one: i32,\n    two: String,\n    three: bool,\n}\n\nfn assert_from_request()\nwhere\n    Extractor: FromRequest<(), Rejection = JsonRejection>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/container_parts.rs",
    "content": "use axum::extract::{\n    rejection::ExtensionRejection,\n    Extension,\n    FromRequestParts,\n};\n\n#[derive(Clone, FromRequestParts)]\n#[from_request(via(Extension))]\nstruct Extractor {\n    one: i32,\n    two: String,\n    three: bool,\n}\n\nfn assert_from_request()\nwhere\n    Extractor: FromRequestParts<(), Rejection = ExtensionRejection>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/empty_named.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<(), Rejection = std::convert::Infallible>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/empty_named_parts.rs",
    "content": "use axum_macros::FromRequestParts;\n\n#[derive(FromRequestParts)]\nstruct Extractor {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<(), Rejection = std::convert::Infallible>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/empty_tuple.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor();\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<(), Rejection = std::convert::Infallible>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/empty_tuple_parts.rs",
    "content": "use axum_macros::FromRequestParts;\n\n#[derive(FromRequestParts)]\nstruct Extractor();\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<(), Rejection = std::convert::Infallible>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/enum_via.rs",
    "content": "use axum::{routing::get, Extension, Router};\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest, Clone)]\n#[from_request(via(Extension))]\nenum Extractor {}\n\nasync fn foo(_: Extractor) {}\n\nfn main() {\n    _ = Router::<()>::new().route(\"/\", get(foo));\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/enum_via_parts.rs",
    "content": "use axum::{routing::get, Extension, Router};\nuse axum_macros::FromRequestParts;\n\n#[derive(FromRequestParts, Clone)]\n#[from_request(via(Extension))]\nenum Extractor {}\n\nasync fn foo(_: Extractor) {}\n\nfn main() {\n    _ = Router::<()>::new().route(\"/\", get(foo));\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/named.rs",
    "content": "use axum::{extract::FromRequest, response::Response};\nuse axum_extra::{\n    headers::{self, UserAgent},\n    typed_header::TypedHeaderRejection,\n    TypedHeader,\n};\n\n#[derive(FromRequest)]\nstruct Extractor {\n    uri: axum::http::Uri,\n    user_agent: TypedHeader<UserAgent>,\n    content_type: TypedHeader<headers::ContentType>,\n    etag: Option<TypedHeader<headers::ETag>>,\n    host: Result<TypedHeader<headers::Host>, TypedHeaderRejection>,\n    body: String,\n}\n\nfn assert_from_request()\nwhere\n    Extractor: FromRequest<(), Rejection = Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/named_parts.rs",
    "content": "use axum::{extract::FromRequestParts, response::Response};\nuse axum_extra::{\n    headers::{self, UserAgent},\n    typed_header::TypedHeaderRejection,\n    TypedHeader,\n};\n\n#[derive(FromRequestParts)]\nstruct Extractor {\n    uri: axum::http::Uri,\n    user_agent: TypedHeader<UserAgent>,\n    content_type: TypedHeader<headers::ContentType>,\n    etag: Option<TypedHeader<headers::ETag>>,\n    host: Result<TypedHeader<headers::Host>, TypedHeaderRejection>,\n}\n\nfn assert_from_request()\nwhere\n    Extractor: FromRequestParts<(), Rejection = Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/named_via.rs",
    "content": "use axum::{\n    extract::{Extension, FromRequest},\n    response::Response,\n};\nuse axum_extra::{\n    headers::{self, UserAgent},\n    typed_header::TypedHeaderRejection,\n    TypedHeader,\n};\n\n#[derive(FromRequest)]\nstruct Extractor {\n    #[from_request(via(Extension))]\n    state: State,\n    #[from_request(via(TypedHeader))]\n    user_agent: UserAgent,\n    #[from_request(via(TypedHeader))]\n    content_type: headers::ContentType,\n    #[from_request(via(TypedHeader))]\n    etag: Option<headers::ETag>,\n    #[from_request(via(TypedHeader))]\n    host: Result<headers::Host, TypedHeaderRejection>,\n}\n\nfn assert_from_request()\nwhere\n    Extractor: FromRequest<(), Rejection = Response>,\n{\n}\n\n#[derive(Clone)]\nstruct State;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/named_via_parts.rs",
    "content": "use axum::{\n    extract::{Extension, FromRequestParts},\n    response::Response,\n};\nuse axum_extra::{\n    headers::{self, UserAgent},\n    typed_header::TypedHeaderRejection,\n    TypedHeader,\n};\n\n#[derive(FromRequestParts)]\nstruct Extractor {\n    #[from_request(via(Extension))]\n    state: State,\n    #[from_request(via(TypedHeader))]\n    user_agent: UserAgent,\n    #[from_request(via(TypedHeader))]\n    content_type: headers::ContentType,\n    #[from_request(via(TypedHeader))]\n    etag: Option<headers::ETag>,\n    #[from_request(via(TypedHeader))]\n    host: Result<headers::Host, TypedHeaderRejection>,\n}\n\nfn assert_from_request()\nwhere\n    Extractor: FromRequestParts<(), Rejection = Response>,\n{\n}\n\n#[derive(Clone)]\nstruct State;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection.rs",
    "content": "use axum::{\n    extract::{rejection::ExtensionRejection, FromRequest, Request},\n    http::StatusCode,\n    response::{IntoResponse, Response},\n    routing::get,\n    Extension, Router,\n};\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\nasync fn handler(_: MyExtractor) {}\n\nasync fn handler_result(_: Result<MyExtractor, MyRejection>) {}\n\n#[derive(FromRequest)]\n#[from_request(rejection(MyRejection))]\nstruct MyExtractor {\n    one: Extension<String>,\n    #[from_request(via(Extension))]\n    two: String,\n    three: OtherExtractor,\n}\n\nstruct OtherExtractor;\n\nimpl<S> FromRequest<S> for OtherExtractor\nwhere\n    S: Send + Sync,\n{\n    // this rejection doesn't implement `Display` and `Error`\n    type Rejection = (StatusCode, String);\n\n    async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        todo!()\n    }\n}\n\nstruct MyRejection {}\n\nimpl From<ExtensionRejection> for MyRejection {\n    fn from(_: ExtensionRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl From<(StatusCode, String)> for MyRejection {\n    fn from(_: (StatusCode, String)) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection_non_generic.rs",
    "content": "use axum::{\n    extract::rejection::JsonRejection,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\nuse serde::Deserialize;\nuse std::collections::HashMap;\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\nasync fn handler(_: MyJson) {}\n\nasync fn handler_result(_: Result<MyJson, MyJsonRejection>) {}\n\n#[derive(FromRequest, Deserialize)]\n#[from_request(via(axum::extract::Json), rejection(MyJsonRejection))]\n#[serde(transparent)]\nstruct MyJson(HashMap<String, String>);\n\nstruct MyJsonRejection {}\n\nimpl From<JsonRejection> for MyJsonRejection {\n    fn from(_: JsonRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyJsonRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection_non_generic_parts.rs",
    "content": "use axum::{\n    extract::rejection::QueryRejection,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequestParts;\nuse serde::Deserialize;\nuse std::collections::HashMap;\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\nasync fn handler(_: MyQuery) {}\n\nasync fn handler_result(_: Result<MyQuery, MyQueryRejection>) {}\n\n#[derive(FromRequestParts, Deserialize)]\n#[from_request(via(axum::extract::Query), rejection(MyQueryRejection))]\n#[serde(transparent)]\nstruct MyQuery(HashMap<String, String>);\n\nstruct MyQueryRejection {}\n\nimpl From<QueryRejection> for MyQueryRejection {\n    fn from(_: QueryRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyQueryRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection_parts.rs",
    "content": "use axum::{\n    extract::{rejection::ExtensionRejection, FromRequestParts},\n    http::{request::Parts, StatusCode},\n    response::{IntoResponse, Response},\n    routing::get,\n    Extension, Router,\n};\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\nasync fn handler(_: MyExtractor) {}\n\nasync fn handler_result(_: Result<MyExtractor, MyRejection>) {}\n\n#[derive(FromRequestParts)]\n#[from_request(rejection(MyRejection))]\nstruct MyExtractor {\n    one: Extension<String>,\n    #[from_request(via(Extension))]\n    two: String,\n    three: OtherExtractor,\n}\n\nstruct OtherExtractor;\n\nimpl<S> FromRequestParts<S> for OtherExtractor\nwhere\n    S: Send + Sync,\n{\n    // this rejection doesn't implement `Display` and `Error`\n    type Rejection = (StatusCode, String);\n\n    async fn from_request_parts(_parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        todo!()\n    }\n}\n\nstruct MyRejection {}\n\nimpl From<ExtensionRejection> for MyRejection {\n    fn from(_: ExtensionRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl From<(StatusCode, String)> for MyRejection {\n    fn from(_: (StatusCode, String)) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection_with_via_on_enum.rs",
    "content": "use axum::{\n    extract::rejection::ExtensionRejection,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\nasync fn handler(_: MyExtractor) {}\n\nasync fn handler_result(_: Result<MyExtractor, MyRejection>) {}\n\n#[derive(FromRequest, Clone)]\n#[from_request(via(axum::Extension), rejection(MyRejection))]\nenum MyExtractor {}\n\nstruct MyRejection {}\n\nimpl From<ExtensionRejection> for MyRejection {\n    fn from(_: ExtensionRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection_with_via_on_enum_parts.rs",
    "content": "use axum::{\n    extract::rejection::ExtensionRejection,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequestParts;\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\nasync fn handler(_: MyExtractor) {}\n\nasync fn handler_result(_: Result<MyExtractor, MyRejection>) {}\n\n#[derive(FromRequestParts, Clone)]\n#[from_request(via(axum::Extension), rejection(MyRejection))]\nenum MyExtractor {}\n\nstruct MyRejection {}\n\nimpl From<ExtensionRejection> for MyRejection {\n    fn from(_: ExtensionRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection_with_via_on_struct.rs",
    "content": "use axum::{\n    extract::rejection::JsonRejection,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\nuse serde::Deserialize;\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\n#[derive(Deserialize)]\nstruct Payload {}\n\nasync fn handler(_: MyJson<Payload>) {}\n\nasync fn handler_result(_: Result<MyJson<Payload>, MyJsonRejection>) {}\n\n#[derive(FromRequest)]\n#[from_request(via(axum::Json), rejection(MyJsonRejection))]\nstruct MyJson<T>(T);\n\nstruct MyJsonRejection {}\n\nimpl From<JsonRejection> for MyJsonRejection {\n    fn from(_: JsonRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyJsonRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/override_rejection_with_via_on_struct_parts.rs",
    "content": "use axum::{\n    extract::rejection::QueryRejection,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequestParts;\nuse serde::Deserialize;\n\nfn main() {\n    let _: Router = Router::new().route(\"/\", get(handler).post(handler_result));\n}\n\n#[derive(Deserialize)]\nstruct Payload {}\n\nasync fn handler(_: MyQuery<Payload>) {}\n\nasync fn handler_result(_: Result<MyQuery<Payload>, MyQueryRejection>) {}\n\n#[derive(FromRequestParts)]\n#[from_request(via(axum::extract::Query), rejection(MyQueryRejection))]\nstruct MyQuery<T>(T);\n\nstruct MyQueryRejection {}\n\nimpl From<QueryRejection> for MyQueryRejection {\n    fn from(_: QueryRejection) -> Self {\n        todo!()\n    }\n}\n\nimpl IntoResponse for MyQueryRejection {\n    fn into_response(self) -> Response {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_cookie.rs",
    "content": "use axum::extract::FromRef;\nuse axum_extra::extract::cookie::{Key, PrivateCookieJar};\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest)]\n#[from_request(state(AppState))]\nstruct Extractor {\n    cookies: PrivateCookieJar,\n}\n\nstruct AppState {\n    key: Key,\n}\n\nimpl FromRef<AppState> for Key {\n    fn from_ref(input: &AppState) -> Self {\n        input.key.clone()\n    }\n}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<AppState, Rejection = axum::response::Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_enum_via.rs",
    "content": "use axum::{\n    extract::{FromRef, State},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/a\", get(|_: AppState| async {}))\n        .route(\"/b\", get(|_: InnerState| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(Clone, FromRequest)]\n#[from_request(via(State))]\nenum AppState {\n    One,\n}\n\nimpl Default for AppState {\n    fn default() -> AppState {\n        Self::One\n    }\n}\n\n#[derive(FromRequest)]\n#[from_request(via(State), state(AppState))]\nenum InnerState {}\n\nimpl FromRef<AppState> for InnerState {\n    fn from_ref(_: &AppState) -> Self {\n        todo!(\"🤷\")\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_enum_via_parts.rs",
    "content": "use axum::{\n    extract::{FromRef, State},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequestParts;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/a\", get(|_: AppState| async {}))\n        .route(\"/b\", get(|_: InnerState| async {}))\n        .route(\"/c\", get(|_: AppState, _: InnerState| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(Clone, FromRequestParts)]\n#[from_request(via(State))]\nenum AppState {\n    One,\n}\n\nimpl Default for AppState {\n    fn default() -> AppState {\n        Self::One\n    }\n}\n\n#[derive(FromRequestParts)]\n#[from_request(via(State), state(AppState))]\nenum InnerState {}\n\nimpl FromRef<AppState> for InnerState {\n    fn from_ref(_: &AppState) -> Self {\n        todo!(\"🤷\")\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_explicit.rs",
    "content": "use axum::{\n    extract::{FromRef, State},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/b\", get(|_: Extractor| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(FromRequest)]\n#[from_request(state(AppState))]\nstruct Extractor {\n    app_state: State<AppState>,\n    one: State<One>,\n    two: State<Two>,\n    other_extractor: String,\n}\n\n#[derive(Clone, Default)]\nstruct AppState {\n    one: One,\n    two: Two,\n}\n\n#[derive(Clone, Default)]\nstruct One {}\n\nimpl FromRef<AppState> for One {\n    fn from_ref(input: &AppState) -> Self {\n        input.one.clone()\n    }\n}\n\n#[derive(Clone, Default)]\nstruct Two {}\n\nimpl FromRef<AppState> for Two {\n    fn from_ref(input: &AppState) -> Self {\n        input.two.clone()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_explicit_parts.rs",
    "content": "use axum::{\n    extract::{FromRef, Query, State},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequestParts;\nuse std::collections::HashMap;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/b\", get(|_: Extractor| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(FromRequestParts)]\n#[from_request(state(AppState))]\nstruct Extractor {\n    inner_state: State<InnerState>,\n    other: Query<HashMap<String, String>>,\n}\n\n#[derive(Default, Clone)]\nstruct AppState {\n    inner: InnerState,\n}\n\n#[derive(Clone, Default)]\nstruct InnerState {}\n\nimpl FromRef<AppState> for InnerState {\n    fn from_ref(input: &AppState) -> Self {\n        input.inner.clone()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_field_explicit.rs",
    "content": "use axum::{\n    extract::{FromRef, State},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/\", get(|_: Extractor| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(FromRequest)]\n#[from_request(state(AppState))]\nstruct Extractor {\n    #[from_request(via(State))]\n    state: AppState,\n    #[from_request(via(State))]\n    inner: InnerState,\n}\n\n#[derive(Clone, Default)]\nstruct AppState {\n    inner: InnerState,\n}\n\n#[derive(Clone, Default)]\nstruct InnerState {}\n\nimpl FromRef<AppState> for InnerState {\n    fn from_ref(input: &AppState) -> Self {\n        input.inner.clone()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_field_infer.rs",
    "content": "use axum::{extract::State, routing::get, Router};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/\", get(|_: Extractor| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(FromRequest)]\nstruct Extractor {\n    #[from_request(via(State))]\n    state: AppState,\n}\n\n#[derive(Clone, Default)]\nstruct AppState {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_infer.rs",
    "content": "use axum::extract::State;\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor {\n    inner_state: State<AppState>,\n}\n\n#[derive(Clone)]\nstruct AppState {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<AppState, Rejection = axum::response::Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_infer_multiple.rs",
    "content": "use axum::extract::State;\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor {\n    inner_state: State<AppState>,\n    also_inner_state: State<AppState>,\n}\n\n#[derive(Clone)]\nstruct AppState {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<AppState, Rejection = axum::response::Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_infer_parts.rs",
    "content": "use axum::extract::State;\nuse axum_macros::FromRequestParts;\n\n#[derive(FromRequestParts)]\nstruct Extractor {\n    inner_state: State<AppState>,\n}\n\n#[derive(Clone)]\nstruct AppState {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<AppState, Rejection = axum::response::Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_via.rs",
    "content": "use axum::{\n    extract::{FromRef, State},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/b\", get(|_: (), _: AppState| async {}))\n        .route(\"/c\", get(|_: (), _: InnerState| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(Clone, Default, FromRequest)]\n#[from_request(via(State), state(AppState))]\nstruct AppState {\n    inner: InnerState,\n}\n\n#[derive(Clone, Default, FromRequest)]\n#[from_request(via(State), state(AppState))]\nstruct InnerState {}\n\nimpl FromRef<AppState> for InnerState {\n    fn from_ref(input: &AppState) -> Self {\n        input.inner.clone()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_via_infer.rs",
    "content": "use axum::{extract::State, routing::get, Router};\nuse axum_macros::FromRequest;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/b\", get(|_: AppState| async {}))\n        .with_state(AppState::default());\n}\n\n// if we're extract \"via\" `State<AppState>` and not specifying state\n// assume `AppState` is the state\n#[derive(Clone, Default, FromRequest)]\n#[from_request(via(State))]\nstruct AppState {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_via_parts.rs",
    "content": "use axum::{\n    extract::{FromRef, State},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequestParts;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/a\", get(|_: AppState, _: InnerState, _: String| async {}))\n        .route(\"/b\", get(|_: AppState, _: String| async {}))\n        .route(\"/c\", get(|_: InnerState, _: String| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(Clone, Default, FromRequestParts)]\n#[from_request(via(State))]\nstruct AppState {\n    inner: InnerState,\n}\n\n#[derive(Clone, Default, FromRequestParts)]\n#[from_request(via(State), state(AppState))]\nstruct InnerState {}\n\nimpl FromRef<AppState> for InnerState {\n    fn from_ref(input: &AppState) -> Self {\n        input.inner.clone()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/state_with_rejection.rs",
    "content": "use axum::{\n    extract::State,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse axum_macros::FromRequest;\nuse std::convert::Infallible;\n\nfn main() {\n    let _: axum::Router = Router::new()\n        .route(\"/a\", get(|_: Extractor| async {}))\n        .with_state(AppState::default());\n}\n\n#[derive(Clone, Default, FromRequest)]\n#[from_request(rejection(MyRejection))]\nstruct Extractor {\n    state: State<AppState>,\n}\n\n#[derive(Clone, Default)]\nstruct AppState {}\n\nstruct MyRejection {}\n\nimpl From<Infallible> for MyRejection {\n    fn from(err: Infallible) -> Self {\n        match err {}\n    }\n}\n\nimpl IntoResponse for MyRejection {\n    fn into_response(self) -> Response {\n        ().into_response()\n    }\n}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor(axum::http::HeaderMap, String);\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<()>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple_parts.rs",
    "content": "use axum_macros::FromRequestParts;\n\n#[derive(FromRequestParts)]\nstruct Extractor(axum::http::HeaderMap, axum::http::Method);\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<()>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple_same_type_twice.rs",
    "content": "use axum::extract::Query;\nuse axum_macros::FromRequest;\nuse serde::Deserialize;\n\n#[derive(FromRequest)]\nstruct Extractor(Query<Payload>, axum::extract::Json<Payload>);\n\n#[derive(Deserialize)]\nstruct Payload {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<()>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple_same_type_twice_parts.rs",
    "content": "use axum::extract::Query;\nuse axum_macros::FromRequestParts;\nuse serde::Deserialize;\n\n#[derive(FromRequestParts)]\nstruct Extractor(Query<Payload>, axum::extract::Path<Payload>);\n\n#[derive(Deserialize)]\nstruct Payload {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<()>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple_same_type_twice_via.rs",
    "content": "use axum::extract::Query;\nuse axum::response::Response;\nuse axum_macros::FromRequest;\nuse serde::Deserialize;\n\n#[derive(FromRequest)]\nstruct Extractor(\n    #[from_request(via(Query))] Payload,\n    #[from_request(via(axum::extract::Json))] Payload,\n);\n\n#[derive(Deserialize)]\nstruct Payload {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<(), Rejection = Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple_same_type_twice_via_parts.rs",
    "content": "use axum::extract::Query;\nuse axum::response::Response;\nuse axum_macros::FromRequestParts;\nuse serde::Deserialize;\n\n#[derive(FromRequestParts)]\nstruct Extractor(\n    #[from_request(via(Query))] Payload,\n    #[from_request(via(axum::extract::Path))] Payload,\n);\n\n#[derive(Deserialize)]\nstruct Payload {}\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<(), Rejection = Response>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple_via.rs",
    "content": "use axum::Extension;\nuse axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor(#[from_request(via(Extension))] State);\n\n#[derive(Clone)]\nstruct State;\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<()>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/tuple_via_parts.rs",
    "content": "use axum::Extension;\nuse axum_macros::FromRequestParts;\n\n#[derive(FromRequestParts)]\nstruct Extractor(#[from_request(via(Extension))] State);\n\n#[derive(Clone)]\nstruct State;\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<()>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/unit.rs",
    "content": "use axum_macros::FromRequest;\n\n#[derive(FromRequest)]\nstruct Extractor;\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequest<(), Rejection = std::convert::Infallible>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/from_request/pass/unit_parts.rs",
    "content": "use axum_macros::FromRequestParts;\n\n#[derive(FromRequestParts)]\nstruct Extractor;\n\nfn assert_from_request()\nwhere\n    Extractor: axum::extract::FromRequestParts<(), Rejection = std::convert::Infallible>,\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/missing_capture.rs",
    "content": "use axum_macros::TypedPath;\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/users\")]\nstruct MyPath {\n    id: u32,\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/missing_capture.stderr",
    "content": "error[E0027]: pattern does not mention field `id`\n --> tests/typed_path/fail/missing_capture.rs:5:14\n  |\n5 | #[typed_path(\"/users\")]\n  |              ^^^^^^^^ missing field `id`\n  |\nhelp: include the missing field in the pattern\n  |\n5 | #[typed_path(\"/users\" { id })]\n  |                       ++++++\nhelp: if you don't care about this missing field, you can explicitly ignore it\n  |\n5 | #[typed_path(\"/users\" { id: _ })]\n  |                       +++++++++\nhelp: or always ignore missing fields here\n  |\n5 | #[typed_path(\"/users\" { .. })]\n  |                       ++++++\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/missing_field.rs",
    "content": "use axum_macros::TypedPath;\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/users/{id}\")]\nstruct MyPath {}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/missing_field.stderr",
    "content": "error[E0026]: struct `MyPath` does not have a field named `id`\n --> tests/typed_path/fail/missing_field.rs:5:14\n  |\n5 | #[typed_path(\"/users/{id}\")]\n  |              ^^^^^^^^^^^^^ struct `MyPath` does not have this field\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/not_deserialize.rs",
    "content": "use axum_macros::TypedPath;\n\n#[derive(TypedPath)]\n#[typed_path(\"/users/{id}\")]\nstruct MyPath {\n    id: u32,\n}\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/not_deserialize.stderr",
    "content": "error[E0277]: the trait bound `MyPath: serde::de::DeserializeOwned` is not satisfied\n --> tests/typed_path/fail/not_deserialize.rs:3:10\n  |\n3 | #[derive(TypedPath)]\n  |          ^^^^^^^^^ unsatisfied trait bound\n  |\nhelp: the trait `for<'de> serde_core::de::Deserialize<'de>` is not implemented for `MyPath`\n --> tests/typed_path/fail/not_deserialize.rs:5:1\n  |\n5 | struct MyPath {\n  | ^^^^^^^^^^^^^\n  = help: the following other types implement trait `serde_core::de::Deserialize<'de>`:\n            &'a [u8]\n            &'a serde_json::raw::RawValue\n            &'a std::path::Path\n            &'a str\n            ()\n            (T,)\n            (T0, T1)\n            (T0, T1, T2)\n          and $N others\n  = note: required for `MyPath` to implement `serde_core::de::DeserializeOwned`\n  = note: required for `axum::extract::Path<MyPath>` to implement `FromRequestParts<S>`\n  = note: this error originates in the derive macro `TypedPath` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror[E0277]: the trait bound `MyPath: serde::Deserialize<'de>` is not satisfied\n --> tests/typed_path/fail/not_deserialize.rs:3:10\n  |\n3 | #[derive(TypedPath)]\n  |          ^^^^^^^^^ unsatisfied trait bound\n  |\nhelp: the trait `for<'de> serde_core::de::Deserialize<'de>` is not implemented for `MyPath`\n --> tests/typed_path/fail/not_deserialize.rs:5:1\n  |\n5 | struct MyPath {\n  | ^^^^^^^^^^^^^\n  = note: for local types consider adding `#[derive(serde::Deserialize)]` to your `MyPath` type\n  = note: for types from other crates check whether the crate offers a `serde` feature flag\n  = help: the following other types implement trait `serde_core::de::Deserialize<'de>`:\n            &'a [u8]\n            &'a serde_json::raw::RawValue\n            &'a std::path::Path\n            &'a str\n            ()\n            (T,)\n            (T0, T1)\n            (T0, T1, T2)\n          and $N others\n  = note: required for `MyPath` to implement `serde_core::de::DeserializeOwned`\n  = note: required for `axum::extract::Path<MyPath>` to implement `FromRequestParts<S>`\n\nerror[E0277]: the trait bound `MyPath: serde::de::DeserializeOwned` is not satisfied\n --> tests/typed_path/fail/not_deserialize.rs:3:10\n  |\n3 | #[derive(TypedPath)]\n  |          ^^^^^^^^^ unsatisfied trait bound\n  |\nhelp: the trait `for<'de> serde_core::de::Deserialize<'de>` is not implemented for `MyPath`\n --> tests/typed_path/fail/not_deserialize.rs:5:1\n  |\n5 | struct MyPath {\n  | ^^^^^^^^^^^^^\n  = help: the following other types implement trait `serde_core::de::Deserialize<'de>`:\n            &'a [u8]\n            &'a serde_json::raw::RawValue\n            &'a std::path::Path\n            &'a str\n            ()\n            (T,)\n            (T0, T1)\n            (T0, T1, T2)\n          and $N others\n  = note: required for `MyPath` to implement `serde_core::de::DeserializeOwned`\n  = note: required for `axum::extract::Path<MyPath>` to implement `FromRequestParts<S>`\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/route_not_starting_with_slash.rs",
    "content": "use axum_extra::routing::TypedPath;\n\n#[derive(TypedPath)]\n#[typed_path(\"\")]\nstruct MyPath;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/route_not_starting_with_slash.stderr",
    "content": "error: paths must start with a `/`. Use \"/\" for root routes\n --> tests/typed_path/fail/route_not_starting_with_slash.rs:4:14\n  |\n4 | #[typed_path(\"\")]\n  |              ^^\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/route_not_starting_with_slash_non_empty.rs",
    "content": "use axum_extra::routing::TypedPath;\n\n#[derive(TypedPath)]\n#[typed_path(\"{foo}\")]\nstruct MyPath;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/route_not_starting_with_slash_non_empty.stderr",
    "content": "error: paths must start with a `/`\n --> tests/typed_path/fail/route_not_starting_with_slash_non_empty.rs:4:14\n  |\n4 | #[typed_path(\"{foo}\")]\n  |              ^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/unit_with_capture.rs",
    "content": "use axum_macros::TypedPath;\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/users/{id}\")]\nstruct MyPath;\n\nfn main() {}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/fail/unit_with_capture.stderr",
    "content": "error: Typed paths for unit structs cannot contain captures\n --> tests/typed_path/fail/unit_with_capture.rs:5:14\n  |\n5 | #[typed_path(\"/users/{id}\")]\n  |              ^^^^^^^^^^^^^\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/customize_rejection.rs",
    "content": "use axum::{\n    extract::rejection::PathRejection,\n    response::{IntoResponse, Response},\n};\nuse axum_extra::routing::{RouterExt, TypedPath};\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/{foo}\", rejection(MyRejection))]\nstruct MyPathNamed {\n    foo: String,\n}\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/\", rejection(MyRejection))]\nstruct MyPathUnit;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/{foo}\", rejection(MyRejection))]\nstruct MyPathUnnamed(String);\n\nstruct MyRejection;\n\nimpl IntoResponse for MyRejection {\n    fn into_response(self) -> Response {\n        ().into_response()\n    }\n}\n\nimpl From<PathRejection> for MyRejection {\n    fn from(_: PathRejection) -> Self {\n        Self\n    }\n}\n\nimpl Default for MyRejection {\n    fn default() -> Self {\n        Self\n    }\n}\n\nfn main() {\n    _ = axum::Router::<()>::new()\n        .typed_get(|_: Result<MyPathNamed, MyRejection>| async {})\n        .typed_post(|_: Result<MyPathUnnamed, MyRejection>| async {})\n        .typed_put(|_: Result<MyPathUnit, MyRejection>| async {});\n}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/into_uri.rs",
    "content": "use axum::http::Uri;\nuse axum_extra::routing::TypedPath;\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/{id}\")]\nstruct Named {\n    id: u32,\n}\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/{id}\")]\nstruct Unnamed(u32);\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/\")]\nstruct Unit;\n\nfn main() {\n    let _: Uri = Named { id: 1 }.to_uri();\n    let _: Uri = Unnamed(1).to_uri();\n    let _: Uri = Unit.to_uri();\n}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/named_fields_struct.rs",
    "content": "use axum_extra::routing::TypedPath;\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/users/{user_id}/teams/{team_id}\")]\nstruct MyPath {\n    user_id: u32,\n    team_id: u32,\n}\n\nfn main() {\n    _ = axum::Router::<()>::new().route(\"/\", axum::routing::get(|_: MyPath| async {}));\n\n    assert_eq!(MyPath::PATH, \"/users/{user_id}/teams/{team_id}\");\n    assert_eq!(\n        format!(\n            \"{}\",\n            MyPath {\n                user_id: 1,\n                team_id: 2\n            }\n        ),\n        \"/users/1/teams/2\"\n    );\n}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/result_handler.rs",
    "content": "use axum::{extract::rejection::PathRejection, http::StatusCode};\nuse axum_extra::routing::{RouterExt, TypedPath};\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/users/{id}\")]\nstruct UsersShow {\n    id: String,\n}\n\nasync fn result_handler(_: Result<UsersShow, PathRejection>) {}\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/users\")]\nstruct UsersIndex;\n\nasync fn result_handler_unit_struct(_: Result<UsersIndex, StatusCode>) {}\n\nfn main() {\n    _ = axum::Router::<()>::new()\n        .typed_post(result_handler)\n        .typed_post(result_handler_unit_struct);\n}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/tuple_struct.rs",
    "content": "use axum_extra::routing::TypedPath;\nuse serde::Deserialize;\n\npub type Result<T> = std::result::Result<T, ()>;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/users/{user_id}/teams/{team_id}\")]\nstruct MyPath(u32, u32);\n\nfn main() {\n    _ = axum::Router::<()>::new().route(\"/\", axum::routing::get(|_: MyPath| async {}));\n\n    assert_eq!(MyPath::PATH, \"/users/{user_id}/teams/{team_id}\");\n    assert_eq!(format!(\"{}\", MyPath(1, 2)), \"/users/1/teams/2\");\n}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/unit_struct.rs",
    "content": "use axum_extra::routing::TypedPath;\n\n#[derive(TypedPath)]\n#[typed_path(\"/users\")]\nstruct MyPath;\n\nfn main() {\n    _ = axum::Router::<()>::new().route(\"/\", axum::routing::get(|_: MyPath| async {}));\n\n    assert_eq!(MyPath::PATH, \"/users\");\n    assert_eq!(format!(\"{}\", MyPath), \"/users\");\n}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/url_encoding.rs",
    "content": "use axum_extra::routing::TypedPath;\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/{param}\")]\nstruct Named {\n    param: String,\n}\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/{param}\")]\nstruct Unnamed(String);\n\nfn main() {\n    assert_eq!(\n        format!(\n            \"{}\",\n            Named {\n                param: \"a b\".to_string()\n            }\n        ),\n        \"/a%20b\"\n    );\n\n    assert_eq!(format!(\"{}\", Unnamed(\"a b\".to_string()),), \"/a%20b\");\n}\n"
  },
  {
    "path": "axum-macros/tests/typed_path/pass/wildcards.rs",
    "content": "use axum_extra::routing::{RouterExt, TypedPath};\nuse serde::Deserialize;\n\n#[derive(TypedPath, Deserialize)]\n#[typed_path(\"/{*rest}\")]\nstruct MyPath {\n    rest: String,\n}\n\nfn main() {\n    _ = axum::Router::<()>::new().typed_get(|_: MyPath| async {});\n}\n"
  },
  {
    "path": "contrib/ide/vscode/settings.json",
    "content": "// Recommended settings for VSCode.\n//\n// Copy to `.vscode/settings.json` at the crate root too use.\n{\n    \"rust-analyzer.linkedProjects\": [\n        \"Cargo.toml\",\n        \"examples/Cargo.toml\"\n    ]\n}\n"
  },
  {
    "path": "deny.toml",
    "content": "[graph]\nexclude-unpublished = true\n\n[advisories]\nunmaintained = \"none\"\nignore = []\n\n[licenses]\nconfidence-threshold = 0.8\nallow = [\n    \"Apache-2.0\",\n    \"BSD-3-Clause\",\n    \"MIT\",\n    \"Unicode-3.0\",\n]\n\n[bans]\nmultiple-versions = \"deny\"\nhighlight = \"all\"\nskip-tree = [\n    # parking_lot pulls in old versions of windows-sys\n    { name = \"windows-sys\" },\n    # pulled in by quickcheck and cookie\n    { name = \"rand\" },\n    # duplicate dependency is intended, see axum-extra/Cargo.lock\n    { name = \"serde_html_form\" },\n]\n\n[sources]\nunknown-registry = \"warn\"\nunknown-git = \"warn\"\nallow-git = []\n"
  },
  {
    "path": "examples/Cargo.toml",
    "content": "[workspace]\nmembers = [\"*\"]\n# Example has been deleted, but README.md remains\nexclude = [\"async-graphql\", \"target\"]\nresolver = \"2\"\n\n[workspace.package]\nrust-version = \"1.75\"\n\n[workspace.lints.rust]\nunsafe_code = \"forbid\"\n\nrust_2018_idioms = { level = \"warn\", priority = -1 }\nmissing_debug_implementations = \"warn\"\nmissing_docs = \"warn\"\nunreachable_pub = \"warn\"\n\n[workspace.lints.clippy]\ntype_complexity = \"allow\"\n\nawait_holding_lock = \"warn\"\ndbg_macro = \"warn\"\nempty_enum = \"warn\"\nenum_glob_use = \"warn\"\nexit = \"warn\"\nfilter_map_next = \"warn\"\nfn_params_excessive_bools = \"warn\"\nif_let_mutex = \"warn\"\nimprecise_flops = \"warn\"\ninefficient_to_string = \"warn\"\nlinkedlist = \"warn\"\nlossy_float_literal = \"warn\"\nmacro_use_imports = \"warn\"\nmatch_wildcard_for_single_variants = \"warn\"\nmem_forget = \"warn\"\nneedless_borrow = \"warn\"\nneedless_continue = \"warn\"\noption_option = \"warn\"\nrest_pat_in_fully_bound_structs = \"warn\"\nstr_to_string = \"warn\"\nsuboptimal_flops = \"warn\"\ntodo = \"warn\"\nuninlined_format_args = \"warn\"\nunnested_or_patterns = \"warn\"\nunused_self = \"warn\"\nverbose_file_reads = \"warn\"\n"
  },
  {
    "path": "examples/README.md",
    "content": "# Examples\n\nThis folder contains numerous examples showing how to use axum. Each example is\nsetup as its own crate so its dependencies are clear.\n\nFor a list of what the community built with axum, please see the list\n[here](../ECOSYSTEM.md).\n"
  },
  {
    "path": "examples/anyhow-error-response/Cargo.toml",
    "content": "[package]\nname = \"example-anyhow-error-response\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\nanyhow = \"1.0\"\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\n\n[dev-dependencies]\nhttp-body-util = \"0.1.0\"\ntower = { version = \"0.5.2\", features = [\"util\"] }\n"
  },
  {
    "path": "examples/anyhow-error-response/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-anyhow-error-response\n//! ```\n\nuse axum::{\n    http::StatusCode,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\n\n#[tokio::main]\nasync fn main() {\n    let app = app();\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler() -> Result<(), AppError> {\n    try_thing()?;\n    Ok(())\n}\n\nfn try_thing() -> Result<(), anyhow::Error> {\n    anyhow::bail!(\"it failed!\")\n}\n\n// Make our own error that wraps `anyhow::Error`.\nstruct AppError(anyhow::Error);\n\n// Tell axum how to convert `AppError` into a response.\nimpl IntoResponse for AppError {\n    fn into_response(self) -> Response {\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            format!(\"Something went wrong: {}\", self.0),\n        )\n            .into_response()\n    }\n}\n\nfn app() -> Router {\n    Router::new().route(\"/\", get(handler))\n}\n\n// This enables using `?` on functions that return `Result<_, anyhow::Error>` to turn them into\n// `Result<_, AppError>`. That way you don't need to do that manually.\nimpl<E> From<E> for AppError\nwhere\n    E: Into<anyhow::Error>,\n{\n    fn from(err: E) -> Self {\n        Self(err.into())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{body::Body, http::Request, http::StatusCode};\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    #[tokio::test]\n    async fn test_main_page() {\n        let response = app()\n            .oneshot(Request::get(\"/\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);\n        let body = response.into_body();\n        let bytes = body.collect().await.unwrap().to_bytes();\n        let html = String::from_utf8(bytes.to_vec()).unwrap();\n\n        assert_eq!(html, \"Something went wrong: it failed!\");\n    }\n}\n"
  },
  {
    "path": "examples/async-graphql/README.md",
    "content": "See <https://github.com/async-graphql/examples>.\n"
  },
  {
    "path": "examples/auto-reload/Cargo.toml",
    "content": "[package]\nname = \"auto-reload\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nlistenfd = \"1.0.1\"\ntokio = { version = \"1.0\", features = [\"full\"] }\n"
  },
  {
    "path": "examples/auto-reload/README.md",
    "content": "# auto-reload\n\nThis example shows how you can set up a development environment for your axum\nservice such that whenever the source code changes, the app is recompiled and\nrestarted. It uses `listenfd` to be able to migrate connections from an old\nversion of the app to a newly-compiled version.\n\n## Setup\n\n```sh\ncargo install cargo-watch systemfd\n```\n\n## Running\n\n```sh\nsystemfd --no-pid -s http::3000 -- cargo watch -x run\n```\n"
  },
  {
    "path": "examples/auto-reload/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p auto-reload\n//! ```\n\nuse axum::{response::Html, routing::get, Router};\nuse listenfd::ListenFd;\nuse tokio::net::TcpListener;\n\n#[tokio::main]\nasync fn main() {\n    // build our application with a route\n    let app = Router::new().route(\"/\", get(handler));\n\n    let mut listenfd = ListenFd::from_env();\n    let listener = match listenfd.take_tcp_listener(0).unwrap() {\n        // if we are given a tcp listener on listen fd 0, we use that one\n        Some(listener) => {\n            listener.set_nonblocking(true).unwrap();\n            TcpListener::from_std(listener).unwrap()\n        }\n        // otherwise fall back to local listening\n        None => TcpListener::bind(\"127.0.0.1:3000\").await.unwrap(),\n    };\n\n    // run it\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler() -> Html<&'static str> {\n    Html(\"<h1>Hello, World!</h1>\")\n}\n"
  },
  {
    "path": "examples/chat/Cargo.toml",
    "content": "[package]\nname = \"example-chat\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"ws\"] }\nfutures-util = { version = \"0.3\", default-features = false, features = [\"sink\", \"std\"] }\ntokio = { version = \"1\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/chat/chat.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <title>WebSocket Chat</title>\n    </head>\n    <body>\n        <h1>WebSocket Chat Example</h1>\n\n        <input id=\"username\" style=\"display:block; width:100px; box-sizing: border-box\" type=\"text\" placeholder=\"username\">\n        <button id=\"join-chat\" type=\"button\">Join Chat</button>\n        <textarea id=\"chat\" style=\"display:block; width:600px; height:400px; box-sizing: border-box\" cols=\"30\" rows=\"10\"></textarea>\n        <input id=\"input\" style=\"display:block; width:600px; box-sizing: border-box\" type=\"text\" placeholder=\"chat\">\n\n        <script>\n            const username = document.querySelector(\"#username\");\n            const join_btn = document.querySelector(\"#join-chat\");\n            const textarea = document.querySelector(\"#chat\");\n            const input = document.querySelector(\"#input\");\n\n            join_btn.addEventListener(\"click\", function(e) {\n                this.disabled = true;\n\n                const websocket = new WebSocket(\"ws://localhost:3000/websocket\");\n\n                websocket.onopen = function() {\n                    console.log(\"connection opened\");\n                    websocket.send(username.value);\n                }\n\n                const btn = this;\n\n                websocket.onclose = function() {\n                    console.log(\"connection closed\");\n                    btn.disabled = false;\n                }\n\n                websocket.onmessage = function(e) {\n                    console.log(\"received message: \"+e.data);\n                    textarea.value += e.data+\"\\r\\n\";\n                }\n\n                input.onkeydown = function(e) {\n                    if (e.key == \"Enter\") {\n                        websocket.send(input.value);\n                        input.value = \"\";\n                    }\n                }\n            });\n        </script>\n    </body>\n</html>\n"
  },
  {
    "path": "examples/chat/src/main.rs",
    "content": "//! Example chat application.\n//!\n//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-chat\n//! ```\n\nuse axum::{\n    extract::{\n        ws::{Message, Utf8Bytes, WebSocket, WebSocketUpgrade},\n        State,\n    },\n    response::{Html, IntoResponse},\n    routing::get,\n    Router,\n};\nuse futures_util::{sink::SinkExt, stream::StreamExt};\nuse std::{\n    collections::HashSet,\n    sync::{Arc, Mutex},\n};\nuse tokio::sync::broadcast;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n// Our shared state\nstruct AppState {\n    // We require unique usernames. This tracks which usernames have been taken.\n    user_set: Mutex<HashSet<String>>,\n    // Channel used to send messages to all connected clients.\n    tx: broadcast::Sender<String>,\n}\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=trace\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // Set up application state for use with with_state().\n    let user_set = Mutex::new(HashSet::new());\n    let (tx, _rx) = broadcast::channel(100);\n\n    let app_state = Arc::new(AppState { user_set, tx });\n\n    let app = Router::new()\n        .route(\"/\", get(index))\n        .route(\"/websocket\", get(websocket_handler))\n        .with_state(app_state);\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn websocket_handler(\n    ws: WebSocketUpgrade,\n    State(state): State<Arc<AppState>>,\n) -> impl IntoResponse {\n    ws.on_upgrade(|socket| websocket(socket, state))\n}\n\n// This function deals with a single websocket connection, i.e., a single\n// connected client / user, for which we will spawn two independent tasks (for\n// receiving / sending chat messages).\nasync fn websocket(stream: WebSocket, state: Arc<AppState>) {\n    // By splitting, we can send and receive at the same time.\n    let (mut sender, mut receiver) = stream.split();\n\n    // Username gets set in the receive loop, if it's valid.\n    let mut username = String::new();\n    // Loop until a text message is found.\n    while let Some(Ok(message)) = receiver.next().await {\n        if let Message::Text(name) = message {\n            // If username that is sent by client is not taken, fill username string.\n            check_username(&state, &mut username, name.as_str());\n\n            // If not empty we want to quit the loop else we want to quit function.\n            if !username.is_empty() {\n                break;\n            } else {\n                // Only send our client that username is taken.\n                let _ = sender\n                    .send(Message::Text(Utf8Bytes::from_static(\n                        \"Username already taken.\",\n                    )))\n                    .await;\n\n                return;\n            }\n        }\n    }\n\n    // We subscribe *before* sending the \"joined\" message, so that we will also\n    // display it to our client.\n    let mut rx = state.tx.subscribe();\n\n    // Now send the \"joined\" message to all subscribers.\n    let msg = format!(\"{username} joined.\");\n    tracing::debug!(\"{msg}\");\n    let _ = state.tx.send(msg);\n\n    // Spawn the first task that will receive broadcast messages and send text\n    // messages over the websocket to our client.\n    let mut send_task = tokio::spawn(async move {\n        while let Ok(msg) = rx.recv().await {\n            // In any websocket error, break loop.\n            if sender.send(Message::text(msg)).await.is_err() {\n                break;\n            }\n        }\n    });\n\n    // Clone things we want to pass (move) to the receiving task.\n    let tx = state.tx.clone();\n    let name = username.clone();\n\n    // Spawn a task that takes messages from the websocket, prepends the user\n    // name, and sends them to all broadcast subscribers.\n    let mut recv_task = tokio::spawn(async move {\n        while let Some(Ok(Message::Text(text))) = receiver.next().await {\n            // Add username before message.\n            let _ = tx.send(format!(\"{name}: {text}\"));\n        }\n    });\n\n    // If any one of the tasks run to completion, we abort the other.\n    tokio::select! {\n        _ = &mut send_task => recv_task.abort(),\n        _ = &mut recv_task => send_task.abort(),\n    };\n\n    // Send \"user left\" message (similar to \"joined\" above).\n    let msg = format!(\"{username} left.\");\n    tracing::debug!(\"{msg}\");\n    let _ = state.tx.send(msg);\n\n    // Remove username from map so new clients can take it again.\n    state.user_set.lock().unwrap().remove(&username);\n}\n\nfn check_username(state: &AppState, string: &mut String, name: &str) {\n    let mut user_set = state.user_set.lock().unwrap();\n\n    if !user_set.contains(name) {\n        user_set.insert(name.to_owned());\n\n        string.push_str(name);\n    }\n}\n\n// Include utf-8 file at **compile** time.\nasync fn index() -> Html<&'static str> {\n    Html(std::include_str!(\"../chat.html\"))\n}\n"
  },
  {
    "path": "examples/compression/Cargo.toml",
    "content": "[package]\nname = \"example-compression\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nserde_json = \"1\"\ntokio = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\ntower = \"0.5.2\"\ntower-http = { version = \"0.6.1\", features = [\"compression-full\", \"decompression-full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\n[dev-dependencies]\nassert-json-diff = \"2.0\"\nbrotli = \"8\"\nflate2 = \"1\"\nhttp = \"1\"\nzstd = \"0.13\"\n"
  },
  {
    "path": "examples/compression/README.md",
    "content": "# compression\n\nThis example shows how to:\n- automatically decompress request bodies when necessary\n- compress response bodies based on the `accept` header.\n\n## Running\n\n```\ncargo run -p example-compression\n```\n\n## Sending compressed requests\n\n```\ncurl -v -g 'http://localhost:3000/' \\\n    -H \"Content-Type: application/json\" \\\n    -H \"Content-Encoding: gzip\" \\\n    --compressed \\\n    --data-binary @data/products.json.gz\n```\n\n(Notice the `Content-Encoding: gzip` in the request, and `content-encoding: gzip` in the response.)\n\n## Sending uncompressed requests\n\n```\ncurl -v -g 'http://localhost:3000/' \\\n    -H \"Content-Type: application/json\" \\\n    --compressed \\\n    --data-binary @data/products.json\n```\n"
  },
  {
    "path": "examples/compression/data/products.json",
    "content": "{\n    \"products\": [\n        {\n            \"id\": 1,\n            \"name\": \"Product 1\"\n        },\n        {\n            \"id\": 2,\n            \"name\": \"Product 2\"\n        }\n    ]\n}\n"
  },
  {
    "path": "examples/compression/src/main.rs",
    "content": "use axum::{routing::post, Json, Router};\nuse serde_json::Value;\nuse tower::ServiceBuilder;\nuse tower_http::{compression::CompressionLayer, decompression::RequestDecompressionLayer};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[cfg(test)]\nmod tests;\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=trace\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let app: Router = app();\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nfn app() -> Router {\n    Router::new().route(\"/\", post(root)).layer(\n        ServiceBuilder::new()\n            .layer(RequestDecompressionLayer::new())\n            .layer(CompressionLayer::new()),\n    )\n}\n\nasync fn root(Json(value): Json<Value>) -> Json<Value> {\n    Json(value)\n}\n"
  },
  {
    "path": "examples/compression/src/tests.rs",
    "content": "use assert_json_diff::assert_json_eq;\nuse axum::{\n    body::{Body, Bytes},\n    response::Response,\n};\nuse brotli::enc::BrotliEncoderParams;\nuse flate2::{read::GzDecoder, write::GzEncoder, Compression};\nuse http::{header, StatusCode};\nuse serde_json::{json, Value};\nuse std::io::{Read, Write};\nuse tower::ServiceExt;\n\nuse super::*;\n\n#[tokio::test]\nasync fn handle_uncompressed_request_bodies() {\n    // Given\n\n    let body = json();\n\n    let compressed_request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .body(json_body(&body))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(compressed_request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    assert_json_eq!(json_from_response(response).await, json());\n}\n\n#[tokio::test]\nasync fn decompress_gzip_request_bodies() {\n    // Given\n\n    let body = compress_gzip(&json());\n\n    let compressed_request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .header(header::CONTENT_ENCODING, \"gzip\")\n        .body(Body::from(body))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(compressed_request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    assert_json_eq!(json_from_response(response).await, json());\n}\n\n#[tokio::test]\nasync fn decompress_br_request_bodies() {\n    // Given\n\n    let body = compress_br(&json());\n\n    let compressed_request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .header(header::CONTENT_ENCODING, \"br\")\n        .body(Body::from(body))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(compressed_request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    assert_json_eq!(json_from_response(response).await, json());\n}\n\n#[tokio::test]\nasync fn decompress_zstd_request_bodies() {\n    // Given\n\n    let body = compress_zstd(&json());\n\n    let compressed_request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .header(header::CONTENT_ENCODING, \"zstd\")\n        .body(Body::from(body))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(compressed_request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    assert_json_eq!(json_from_response(response).await, json());\n}\n\n#[tokio::test]\nasync fn do_not_compress_response_bodies() {\n    // Given\n    let request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .body(json_body(&json()))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    assert_json_eq!(json_from_response(response).await, json());\n}\n\n#[tokio::test]\nasync fn compress_response_bodies_with_gzip() {\n    // Given\n    let request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .header(header::ACCEPT_ENCODING, \"gzip\")\n        .body(json_body(&json()))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    let response_body = byte_from_response(response).await;\n    let mut decoder = GzDecoder::new(response_body.as_ref());\n    let mut decompress_body = String::new();\n    decoder.read_to_string(&mut decompress_body).unwrap();\n    assert_json_eq!(\n        serde_json::from_str::<serde_json::Value>(&decompress_body).unwrap(),\n        json()\n    );\n}\n\n#[tokio::test]\nasync fn compress_response_bodies_with_br() {\n    // Given\n    let request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .header(header::ACCEPT_ENCODING, \"br\")\n        .body(json_body(&json()))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    let response_body = byte_from_response(response).await;\n    let mut decompress_body = Vec::new();\n    brotli::BrotliDecompress(&mut response_body.as_ref(), &mut decompress_body).unwrap();\n    assert_json_eq!(\n        serde_json::from_slice::<serde_json::Value>(&decompress_body).unwrap(),\n        json()\n    );\n}\n\n#[tokio::test]\nasync fn compress_response_bodies_with_zstd() {\n    // Given\n    let request = http::Request::post(\"/\")\n        .header(header::CONTENT_TYPE, \"application/json\")\n        .header(header::ACCEPT_ENCODING, \"zstd\")\n        .body(json_body(&json()))\n        .unwrap();\n\n    // When\n\n    let response = app().oneshot(request).await.unwrap();\n\n    // Then\n\n    assert_eq!(response.status(), StatusCode::OK);\n    let response_body = byte_from_response(response).await;\n    let decompress_body = zstd::stream::decode_all(std::io::Cursor::new(response_body)).unwrap();\n    assert_json_eq!(\n        serde_json::from_slice::<serde_json::Value>(&decompress_body).unwrap(),\n        json()\n    );\n}\n\nfn json() -> Value {\n    json!({\n      \"name\": \"foo\",\n      \"mainProduct\": {\n        \"typeId\": \"product\",\n        \"id\": \"p1\"\n      },\n    })\n}\n\nfn json_body(input: &Value) -> Body {\n    Body::from(serde_json::to_vec(&input).unwrap())\n}\n\nasync fn json_from_response(response: Response) -> Value {\n    let body = byte_from_response(response).await;\n    body_as_json(body)\n}\n\nasync fn byte_from_response(response: Response) -> Bytes {\n    axum::body::to_bytes(response.into_body(), usize::MAX)\n        .await\n        .unwrap()\n}\n\nfn body_as_json(body: Bytes) -> Value {\n    serde_json::from_slice(body.as_ref()).unwrap()\n}\n\nfn compress_gzip(json: &Value) -> Vec<u8> {\n    let request_body = serde_json::to_vec(&json).unwrap();\n\n    let mut encoder = GzEncoder::new(Vec::new(), Compression::default());\n    encoder.write_all(&request_body).unwrap();\n    encoder.finish().unwrap()\n}\n\nfn compress_br(json: &Value) -> Vec<u8> {\n    let request_body = serde_json::to_vec(&json).unwrap();\n    let mut result = Vec::new();\n\n    let params = BrotliEncoderParams::default();\n    let _ = brotli::enc::BrotliCompress(&mut &request_body[..], &mut result, &params).unwrap();\n\n    result\n}\n\nfn compress_zstd(json: &Value) -> Vec<u8> {\n    let request_body = serde_json::to_vec(&json).unwrap();\n    zstd::stream::encode_all(std::io::Cursor::new(request_body), 4).unwrap()\n}\n"
  },
  {
    "path": "examples/consume-body-in-extractor-or-middleware/Cargo.toml",
    "content": "[package]\nname = \"example-consume-body-in-extractor-or-middleware\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhttp-body-util = \"0.1.0\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/consume-body-in-extractor-or-middleware/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-consume-body-in-extractor-or-middleware\n//! ```\n\nuse axum::{\n    body::{Body, Bytes},\n    extract::{FromRequest, Request},\n    http::StatusCode,\n    middleware::{self, Next},\n    response::{IntoResponse, Response},\n    routing::post,\n    Router,\n};\nuse http_body_util::BodyExt;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let app = Router::new()\n        .route(\"/\", post(handler))\n        .layer(middleware::from_fn(print_request_body));\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n// middleware that shows how to consume the request body upfront\nasync fn print_request_body(request: Request, next: Next) -> Result<impl IntoResponse, Response> {\n    let request = buffer_request_body(request).await?;\n\n    Ok(next.run(request).await)\n}\n\n// the trick is to take the request apart, buffer the body, do what you need to do, then put\n// the request back together\nasync fn buffer_request_body(request: Request) -> Result<Request, Response> {\n    let (parts, body) = request.into_parts();\n\n    // this won't work if the body is an long running stream\n    let bytes = body\n        .collect()\n        .await\n        .map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response())?\n        .to_bytes();\n\n    do_thing_with_request_body(bytes.clone());\n\n    Ok(Request::from_parts(parts, Body::from(bytes)))\n}\n\nfn do_thing_with_request_body(bytes: Bytes) {\n    tracing::debug!(body = ?bytes);\n}\n\nasync fn handler(BufferRequestBody(body): BufferRequestBody) {\n    tracing::debug!(?body, \"handler received body\");\n}\n\n// extractor that shows how to consume the request body upfront\nstruct BufferRequestBody(Bytes);\n\n// we must implement `FromRequest` (and not `FromRequestParts`) to consume the body\nimpl<S> FromRequest<S> for BufferRequestBody\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Response;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        let body = Bytes::from_request(req, state)\n            .await\n            .map_err(|err| err.into_response())?;\n\n        do_thing_with_request_body(body.clone());\n\n        Ok(Self(body))\n    }\n}\n"
  },
  {
    "path": "examples/cors/Cargo.toml",
    "content": "[package]\nname = \"example-cors\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower-http = { version = \"0.6.1\", features = [\"cors\"] }\n"
  },
  {
    "path": "examples/cors/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-cors\n//! ```\n\nuse axum::{\n    http::{HeaderValue, Method},\n    response::{Html, IntoResponse},\n    routing::get,\n    Json, Router,\n};\nuse std::net::SocketAddr;\nuse tower_http::cors::CorsLayer;\n\n#[tokio::main]\nasync fn main() {\n    let frontend = async {\n        let app = Router::new().route(\"/\", get(html));\n        serve(app, 3000).await;\n    };\n\n    let backend = async {\n        let app = Router::new().route(\"/json\", get(json)).layer(\n            // see https://docs.rs/tower-http/latest/tower_http/cors/index.html\n            // for more details\n            //\n            // pay attention that for some request types like posting content-type: application/json\n            // it is required to add \".allow_headers([http::header::CONTENT_TYPE])\"\n            // or see this issue https://github.com/tokio-rs/axum/issues/849\n            CorsLayer::new()\n                .allow_origin(\"http://localhost:3000\".parse::<HeaderValue>().unwrap())\n                .allow_methods([Method::GET]),\n        );\n        serve(app, 4000).await;\n    };\n\n    tokio::join!(frontend, backend);\n}\n\nasync fn serve(app: Router, port: u16) {\n    let addr = SocketAddr::from(([127, 0, 0, 1], port));\n    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();\n    axum::serve(listener, app).await;\n}\n\nasync fn html() -> impl IntoResponse {\n    Html(\n        r#\"\n        <script>\n            fetch('http://localhost:4000/json')\n              .then(response => response.json())\n              .then(data => console.log(data));\n        </script>\n        \"#,\n    )\n}\n\nasync fn json() -> impl IntoResponse {\n    Json(vec![\"one\", \"two\", \"three\"])\n}\n"
  },
  {
    "path": "examples/customize-extractor-error/Cargo.toml",
    "content": "[package]\nname = \"example-customize-extractor-error\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"macros\"] }\naxum-extra = { path = \"../../axum-extra\", features = [\"with-rejection\"] }\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\nthiserror = \"2\"\ntokio = { version = \"1.20\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/customize-extractor-error/README.md",
    "content": "This example explores 3 different ways you can create custom rejections for\nalready existing extractors\n\n- [`with_rejection`](src/with_rejection.rs): Uses\n  `axum_extra::extract::WithRejection` to transform one rejection into another\n- [`derive_from_request`](src/derive_from_request.rs): Uses the\n  `axum::extract::FromRequest` derive macro to wrap another extractor and\n  customize the rejection\n- [`custom_extractor`](src/custom_extractor.rs): Manual implementation of\n  `FromRequest` that wraps another extractor\n\nRun with\n\n```sh\ncargo run -p example-customize-extractor-error\n```\n"
  },
  {
    "path": "examples/customize-extractor-error/src/custom_extractor.rs",
    "content": "//! Manual implementation of `FromRequest` that wraps another extractor\n//!\n//! + Powerful API: Implementing `FromRequest` grants access to `RequestParts`\n//!   and `async/await`. This means that you can create more powerful rejections\n//! - Boilerplate: Requires creating a new extractor for every custom rejection\n//! - Complexity: Manually implementing `FromRequest` results on more complex code\nuse axum::{\n    extract::{rejection::JsonRejection, FromRequest, MatchedPath, Request},\n    http::StatusCode,\n    response::IntoResponse,\n    RequestPartsExt,\n};\nuse serde_json::{json, Value};\n\npub async fn handler(Json(value): Json<Value>) -> impl IntoResponse {\n    Json(dbg!(value));\n}\n\n// We define our own `Json` extractor that customizes the error from `axum::Json`\npub struct Json<T>(pub T);\n\nimpl<S, T> FromRequest<S> for Json<T>\nwhere\n    axum::Json<T>: FromRequest<S, Rejection = JsonRejection>,\n    S: Send + Sync,\n{\n    type Rejection = (StatusCode, axum::Json<Value>);\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        let (mut parts, body) = req.into_parts();\n\n        // We can use other extractors to provide better rejection messages.\n        // For example, here we are using `axum::extract::MatchedPath` to\n        // provide a better error message.\n        //\n        // Have to run that first since `Json` extraction consumes the request.\n        let path = parts\n            .extract::<MatchedPath>()\n            .await\n            .map(|path| path.as_str().to_owned())\n            .ok();\n\n        let req = Request::from_parts(parts, body);\n\n        match axum::Json::<T>::from_request(req, state).await {\n            Ok(value) => Ok(Self(value.0)),\n            // convert the error from `axum::Json` into whatever we want\n            Err(rejection) => {\n                let payload = json!({\n                    \"message\": rejection.body_text(),\n                    \"origin\": \"custom_extractor\",\n                    \"path\": path,\n                });\n\n                Err((rejection.status(), axum::Json(payload)))\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/customize-extractor-error/src/derive_from_request.rs",
    "content": "//! Uses `axum::extract::FromRequest` to wrap another extractor and customize the\n//! rejection\n//!\n//! + Easy learning curve: Deriving `FromRequest` generates a `FromRequest`\n//!   implementation for your type using another extractor. You only need\n//!   to provide a `From` impl between the original rejection type and the\n//!   target rejection. Crates like [`thiserror`] can provide such conversion\n//!   using derive macros.\n//! - Boilerplate: Requires deriving `FromRequest` for every custom rejection\n//! - There are some known limitations: [FromRequest#known-limitations]\n//!\n//! [`thiserror`]: https://crates.io/crates/thiserror\n//! [FromRequest#known-limitations]: https://docs.rs/axum-macros/*/axum_macros/derive.FromRequest.html#known-limitations\nuse axum::{\n    extract::rejection::JsonRejection, extract::FromRequest, http::StatusCode,\n    response::IntoResponse,\n};\nuse serde::Serialize;\nuse serde_json::{json, Value};\n\npub async fn handler(Json(value): Json<Value>) -> impl IntoResponse {\n    Json(dbg!(value))\n}\n\n// create an extractor that internally uses `axum::Json` but has a custom rejection\n#[derive(FromRequest)]\n#[from_request(via(axum::Json), rejection(ApiError))]\npub struct Json<T>(T);\n\n// We implement `IntoResponse` for our extractor so it can be used as a response\nimpl<T: Serialize> IntoResponse for Json<T> {\n    fn into_response(self) -> axum::response::Response {\n        let Self(value) = self;\n        axum::Json(value).into_response()\n    }\n}\n\n// We create our own rejection type\n#[derive(Debug)]\npub struct ApiError {\n    status: StatusCode,\n    message: String,\n}\n\n// We implement `From<JsonRejection> for ApiError`\nimpl From<JsonRejection> for ApiError {\n    fn from(rejection: JsonRejection) -> Self {\n        Self {\n            status: rejection.status(),\n            message: rejection.body_text(),\n        }\n    }\n}\n\n// We implement `IntoResponse` so `ApiError` can be used as a response\nimpl IntoResponse for ApiError {\n    fn into_response(self) -> axum::response::Response {\n        let payload = json!({\n            \"message\": self.message,\n            \"origin\": \"derive_from_request\"\n        });\n\n        (self.status, axum::Json(payload)).into_response()\n    }\n}\n"
  },
  {
    "path": "examples/customize-extractor-error/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-customize-extractor-error\n//! ```\n\nmod custom_extractor;\nmod derive_from_request;\nmod with_rejection;\n\nuse axum::{routing::post, Router};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=trace\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // Build our application with some routes\n    let app = Router::new()\n        .route(\"/with-rejection\", post(with_rejection::handler))\n        .route(\"/custom-extractor\", post(custom_extractor::handler))\n        .route(\"/derive-from-request\", post(derive_from_request::handler));\n\n    // Run our application\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n"
  },
  {
    "path": "examples/customize-extractor-error/src/with_rejection.rs",
    "content": "//! Uses `axum_extra::extract::WithRejection` to transform one rejection into\n//! another\n//!\n//! + Easy learning curve: `WithRejection` acts as a wrapper for another\n//!   already existing extractor. You only need to provide a `From` impl\n//!   between the original rejection type and the target rejection. Crates like\n//!   `thiserror` can provide such conversion using derive macros. See\n//!   [`thiserror`]\n//! - Verbose types: types become much larger, which makes them difficult to\n//!   read. Current limitations on type aliasing makes impossible to destructure\n//!   a type alias. See [#1116]\n//!   \n//! [`thiserror`]: https://crates.io/crates/thiserror\n//! [#1116]: https://github.com/tokio-rs/axum/issues/1116#issuecomment-1186197684\n\nuse axum::{extract::rejection::JsonRejection, response::IntoResponse, Json};\nuse axum_extra::extract::WithRejection;\nuse serde_json::{json, Value};\nuse thiserror::Error;\n\npub async fn handler(\n    // `WithRejection` will extract `Json<Value>` from the request. If it fails,\n    // `JsonRejection` will be transform into `ApiError` and returned as response\n    // to the client.\n    //\n    // The second constructor argument is not meaningful and can be safely ignored\n    WithRejection(Json(value), _): WithRejection<Json<Value>, ApiError>,\n) -> impl IntoResponse {\n    Json(dbg!(value))\n}\n\n// We derive `thiserror::Error`\n#[derive(Debug, Error)]\npub enum ApiError {\n    // The `#[from]` attribute generates `From<JsonRejection> for ApiError`\n    // implementation. See `thiserror` docs for more information\n    #[error(transparent)]\n    JsonExtractorRejection(#[from] JsonRejection),\n}\n\n// We implement `IntoResponse` so ApiError can be used as a response\nimpl IntoResponse for ApiError {\n    fn into_response(self) -> axum::response::Response {\n        let (status, message) = match self {\n            ApiError::JsonExtractorRejection(json_rejection) => {\n                (json_rejection.status(), json_rejection.body_text())\n            }\n        };\n\n        let payload = json!({\n            \"message\": message,\n            \"origin\": \"with_rejection\"\n        });\n\n        (status, Json(payload)).into_response()\n    }\n}\n"
  },
  {
    "path": "examples/customize-path-rejection/Cargo.toml",
    "content": "[package]\nname = \"example-customize-path-rejection\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/customize-path-rejection/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-customize-path-rejection\n//! ```\n\nuse axum::{\n    extract::{path::ErrorKind, rejection::PathRejection, FromRequestParts},\n    http::{request::Parts, StatusCode},\n    response::IntoResponse,\n    routing::get,\n    Router,\n};\nuse serde::{de::DeserializeOwned, Deserialize, Serialize};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with a route\n    let app = Router::new().route(\"/users/{user_id}/teams/{team_id}\", get(handler));\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler(Path(params): Path<Params>) -> impl IntoResponse {\n    axum::Json(params)\n}\n\n#[derive(Debug, Deserialize, Serialize)]\nstruct Params {\n    user_id: u32,\n    team_id: u32,\n}\n\n// We define our own `Path` extractor that customizes the error from `axum::extract::Path`\nstruct Path<T>(T);\n\nimpl<S, T> FromRequestParts<S> for Path<T>\nwhere\n    // these trait bounds are copied from `impl FromRequest for axum::extract::path::Path`\n    T: DeserializeOwned + Send,\n    S: Send + Sync,\n{\n    type Rejection = (StatusCode, axum::Json<PathError>);\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        match axum::extract::Path::<T>::from_request_parts(parts, state).await {\n            Ok(value) => Ok(Self(value.0)),\n            Err(rejection) => {\n                let (status, body) = match rejection {\n                    PathRejection::FailedToDeserializePathParams(inner) => {\n                        let mut status = StatusCode::BAD_REQUEST;\n\n                        let kind = inner.into_kind();\n                        let body = match &kind {\n                            ErrorKind::WrongNumberOfParameters { .. } => PathError {\n                                message: kind.to_string(),\n                                location: None,\n                            },\n\n                            ErrorKind::ParseErrorAtKey { key, .. } => PathError {\n                                message: kind.to_string(),\n                                location: Some(key.clone()),\n                            },\n\n                            ErrorKind::ParseErrorAtIndex { index, .. } => PathError {\n                                message: kind.to_string(),\n                                location: Some(index.to_string()),\n                            },\n\n                            ErrorKind::ParseError { .. } => PathError {\n                                message: kind.to_string(),\n                                location: None,\n                            },\n\n                            ErrorKind::InvalidUtf8InPathParam { key } => PathError {\n                                message: kind.to_string(),\n                                location: Some(key.clone()),\n                            },\n\n                            ErrorKind::UnsupportedType { .. } => {\n                                // this error is caused by the programmer using an unsupported type\n                                // (such as nested maps) so respond with `500` instead\n                                status = StatusCode::INTERNAL_SERVER_ERROR;\n                                PathError {\n                                    message: kind.to_string(),\n                                    location: None,\n                                }\n                            }\n\n                            ErrorKind::Message(msg) => PathError {\n                                message: msg.clone(),\n                                location: None,\n                            },\n\n                            _ => PathError {\n                                message: format!(\"Unhandled deserialization error: {kind}\"),\n                                location: None,\n                            },\n                        };\n\n                        (status, body)\n                    }\n                    PathRejection::MissingPathParams(error) => (\n                        StatusCode::INTERNAL_SERVER_ERROR,\n                        PathError {\n                            message: error.to_string(),\n                            location: None,\n                        },\n                    ),\n                    _ => (\n                        StatusCode::INTERNAL_SERVER_ERROR,\n                        PathError {\n                            message: format!(\"Unhandled path rejection: {rejection}\"),\n                            location: None,\n                        },\n                    ),\n                };\n\n                Err((status, axum::Json(body)))\n            }\n        }\n    }\n}\n\n#[derive(Serialize)]\nstruct PathError {\n    message: String,\n    location: Option<String>,\n}\n"
  },
  {
    "path": "examples/dependency-injection/Cargo.toml",
    "content": "[package]\nname = \"example-dependency-injection\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"tracing\", \"macros\"] }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\nuuid = { version = \"1.0\", features = [\"serde\", \"v4\"] }\n"
  },
  {
    "path": "examples/dependency-injection/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-dependency-injection\n//! ```\n\nuse std::{\n    collections::HashMap,\n    sync::{Arc, Mutex},\n};\n\nuse axum::{\n    extract::{Path, State},\n    http::StatusCode,\n    routing::{get, post},\n    Json, Router,\n};\nuse serde::{Deserialize, Serialize};\nuse tokio::net::TcpListener;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\nuse uuid::Uuid;\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let user_repo = InMemoryUserRepo::default();\n\n    // We generally have two ways to inject dependencies:\n    //\n    // 1. Using trait objects (`dyn SomeTrait`)\n    //     - Pros\n    //         - Likely leads to simpler code due to fewer type parameters.\n    //     - Cons\n    //         - Less flexible because we can only use object safe traits\n    //         - Small amount of additional runtime overhead due to dynamic dispatch.\n    //           This is likely to be negligible.\n    // 2. Using generics (`T where T: SomeTrait`)\n    //     - Pros\n    //         - More flexible since all traits can be used.\n    //         - No runtime overhead.\n    //     - Cons:\n    //         - Additional type parameters and trait bounds can lead to more complex code and\n    //           boilerplate.\n    //\n    // Using trait objects is recommended unless you really need generics.\n\n    let using_dyn = Router::new()\n        .route(\"/users/{id}\", get(get_user_dyn))\n        .route(\"/users\", post(create_user_dyn))\n        .with_state(AppStateDyn {\n            user_repo: Arc::new(user_repo.clone()),\n        });\n\n    let using_generic = Router::new()\n        .route(\"/users/{id}\", get(get_user_generic::<InMemoryUserRepo>))\n        .route(\"/users\", post(create_user_generic::<InMemoryUserRepo>))\n        .with_state(AppStateGeneric { user_repo });\n\n    let app = Router::new()\n        .nest(\"/dyn\", using_dyn)\n        .nest(\"/generic\", using_generic);\n\n    let listener = TcpListener::bind(\"127.0.0.1:3000\").await.unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n#[derive(Clone)]\nstruct AppStateDyn {\n    user_repo: Arc<dyn UserRepo>,\n}\n\n#[derive(Clone)]\nstruct AppStateGeneric<T> {\n    user_repo: T,\n}\n\n#[derive(Debug, Serialize, Clone)]\nstruct User {\n    id: Uuid,\n    name: String,\n}\n\n#[derive(Deserialize)]\nstruct UserParams {\n    name: String,\n}\n\nasync fn create_user_dyn(\n    State(state): State<AppStateDyn>,\n    Json(params): Json<UserParams>,\n) -> Json<User> {\n    let user = User {\n        id: Uuid::new_v4(),\n        name: params.name,\n    };\n\n    state.user_repo.save_user(&user);\n\n    Json(user)\n}\n\nasync fn get_user_dyn(\n    State(state): State<AppStateDyn>,\n    Path(id): Path<Uuid>,\n) -> Result<Json<User>, StatusCode> {\n    match state.user_repo.get_user(id) {\n        Some(user) => Ok(Json(user)),\n        None => Err(StatusCode::NOT_FOUND),\n    }\n}\n\nasync fn create_user_generic<T>(\n    State(state): State<AppStateGeneric<T>>,\n    Json(params): Json<UserParams>,\n) -> Json<User>\nwhere\n    T: UserRepo,\n{\n    let user = User {\n        id: Uuid::new_v4(),\n        name: params.name,\n    };\n\n    state.user_repo.save_user(&user);\n\n    Json(user)\n}\n\nasync fn get_user_generic<T>(\n    State(state): State<AppStateGeneric<T>>,\n    Path(id): Path<Uuid>,\n) -> Result<Json<User>, StatusCode>\nwhere\n    T: UserRepo,\n{\n    match state.user_repo.get_user(id) {\n        Some(user) => Ok(Json(user)),\n        None => Err(StatusCode::NOT_FOUND),\n    }\n}\n\ntrait UserRepo: Send + Sync {\n    fn get_user(&self, id: Uuid) -> Option<User>;\n\n    fn save_user(&self, user: &User);\n}\n\n#[derive(Debug, Clone, Default)]\nstruct InMemoryUserRepo {\n    map: Arc<Mutex<HashMap<Uuid, User>>>,\n}\n\nimpl UserRepo for InMemoryUserRepo {\n    fn get_user(&self, id: Uuid) -> Option<User> {\n        self.map.lock().unwrap().get(&id).cloned()\n    }\n\n    fn save_user(&self, user: &User) {\n        self.map.lock().unwrap().insert(user.id, user.clone());\n    }\n}\n"
  },
  {
    "path": "examples/diesel-async-postgres/Cargo.toml",
    "content": "[package]\nname = \"example-diesel-async-postgres\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"macros\"] }\ndiesel = \"~2.3\"\ndiesel-async = { version = \"0.7\", features = [\"postgres\", \"bb8\", \"migrations\"] }\ndiesel_migrations = \"~2.3\"\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/diesel-async-postgres/migrations/2023-03-14-180127_add_users/down.sql",
    "content": "-- This file should undo anything in \"up.sql\"\nDROP TABLE \"users\";\n"
  },
  {
    "path": "examples/diesel-async-postgres/migrations/2023-03-14-180127_add_users/up.sql",
    "content": "-- Your SQL goes here\nCREATE TABLE \"users\"(\n    \"id\" SERIAL PRIMARY KEY,\n    \"name\" TEXT NOT NULL,\n    \"hair_color\" TEXT\n);\n"
  },
  {
    "path": "examples/diesel-async-postgres/src/main.rs",
    "content": "//! Run with\n//!\n//! ```sh\n//! export DATABASE_URL=postgres://localhost/your_db\n//! cargo run -p example-diesel-async-postgres\n//! ```\n//!\n//! Checkout the [diesel webpage](https://diesel.rs) for\n//! longer guides about diesel\n//!\n//! Checkout the [crates.io source code](https://github.com/rust-lang/crates.io/)\n//! for a real world application using axum and diesel\n\nuse axum::{\n    extract::{FromRef, FromRequestParts, State},\n    http::{request::Parts, StatusCode},\n    response::Json,\n    routing::{get, post},\n    Router,\n};\nuse diesel::prelude::*;\nuse diesel_async::{\n    pooled_connection::{bb8, AsyncDieselConnectionManager},\n    AsyncMigrationHarness, AsyncPgConnection, RunQueryDsl,\n};\nuse diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};\nuse std::net::SocketAddr;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\npub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();\n\n// normally part of your generated schema.rs file\ntable! {\n    users (id) {\n        id -> Integer,\n        name -> Text,\n        hair_color -> Nullable<Text>,\n    }\n}\n\n#[derive(serde::Serialize, HasQuery)]\nstruct User {\n    id: i32,\n    name: String,\n    hair_color: Option<String>,\n}\n\n#[derive(serde::Deserialize, Insertable)]\n#[diesel(table_name = users)]\nstruct NewUser {\n    name: String,\n    hair_color: Option<String>,\n}\n\ntype Pool = bb8::Pool<AsyncPgConnection>;\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let db_url = std::env::var(\"DATABASE_URL\").unwrap();\n\n    // set up connection pool\n    let config = AsyncDieselConnectionManager::<diesel_async::AsyncPgConnection>::new(db_url);\n    let pool = bb8::Pool::builder().build(config).await.unwrap();\n\n    let mut harness = AsyncMigrationHarness::new(pool.get_owned().await.unwrap());\n    harness.run_pending_migrations(MIGRATIONS).unwrap();\n\n    // build our application with some routes\n    let app = Router::new()\n        .route(\"/user/list\", get(list_users))\n        .route(\"/user/create\", post(create_user))\n        .with_state(pool);\n\n    // run it with hyper\n    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));\n    tracing::debug!(\"listening on {addr}\");\n    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();\n    axum::serve(listener, app).await;\n}\n\nasync fn create_user(\n    State(pool): State<Pool>,\n    Json(new_user): Json<NewUser>,\n) -> Result<Json<User>, (StatusCode, String)> {\n    let mut conn = pool.get().await.map_err(internal_error)?;\n\n    let res = diesel::insert_into(users::table)\n        .values(new_user)\n        .returning(User::as_returning())\n        .get_result(&mut conn)\n        .await\n        .map_err(internal_error)?;\n    Ok(Json(res))\n}\n\n// we can also write a custom extractor that grabs a connection from the pool\n// which setup is appropriate depends on your application\nstruct DatabaseConnection(bb8::PooledConnection<'static, AsyncPgConnection>);\n\nimpl<S> FromRequestParts<S> for DatabaseConnection\nwhere\n    S: Send + Sync,\n    Pool: FromRef<S>,\n{\n    type Rejection = (StatusCode, String);\n\n    async fn from_request_parts(_parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let pool = Pool::from_ref(state);\n\n        let conn = pool.get_owned().await.map_err(internal_error)?;\n\n        Ok(Self(conn))\n    }\n}\n\nasync fn list_users(\n    DatabaseConnection(mut conn): DatabaseConnection,\n) -> Result<Json<Vec<User>>, (StatusCode, String)> {\n    let res = User::query()\n        .load(&mut conn)\n        .await\n        .map_err(internal_error)?;\n    Ok(Json(res))\n}\n\n/// Utility function for mapping any error into a `500 Internal Server Error`\n/// response.\nfn internal_error<E>(err: E) -> (StatusCode, String)\nwhere\n    E: std::error::Error,\n{\n    (StatusCode::INTERNAL_SERVER_ERROR, err.to_string())\n}\n"
  },
  {
    "path": "examples/diesel-postgres/Cargo.toml",
    "content": "[package]\nname = \"example-diesel-postgres\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"macros\"] }\ndeadpool-diesel = { version = \"0.6.1\", features = [\"postgres\"] }\ndiesel = { version = \"2\", features = [\"postgres\"] }\ndiesel_migrations = \"2\"\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/diesel-postgres/migrations/2023-03-14-180127_add_users/down.sql",
    "content": "-- This file should undo anything in \"up.sql\"\nDROP TABLE \"users\";\n"
  },
  {
    "path": "examples/diesel-postgres/migrations/2023-03-14-180127_add_users/up.sql",
    "content": "-- Your SQL goes here\nCREATE TABLE \"users\"(\n    \"id\" SERIAL PRIMARY KEY,\n    \"name\" TEXT NOT NULL,\n    \"hair_color\" TEXT\n);\n"
  },
  {
    "path": "examples/diesel-postgres/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-diesel-postgres\n//! ```\n//!\n//! Checkout the [diesel webpage](https://diesel.rs) for\n//! longer guides about diesel\n//!\n//! Checkout the [crates.io source code](https://github.com/rust-lang/crates.io/)\n//! for a real world application using axum and diesel\n\nuse axum::{\n    extract::State,\n    http::StatusCode,\n    response::Json,\n    routing::{get, post},\n    Router,\n};\nuse diesel::prelude::*;\nuse diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};\nuse std::net::SocketAddr;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n// this embeds the migrations into the application binary\n// the migration path is relative to the `CARGO_MANIFEST_DIR`\npub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(\"migrations/\");\n\n// normally part of your generated schema.rs file\ntable! {\n    users (id) {\n        id -> Integer,\n        name -> Text,\n        hair_color -> Nullable<Text>,\n    }\n}\n\n#[derive(serde::Serialize, HasQuery)]\nstruct User {\n    id: i32,\n    name: String,\n    hair_color: Option<String>,\n}\n\n#[derive(serde::Deserialize, Insertable)]\n#[diesel(table_name = users)]\nstruct NewUser {\n    name: String,\n    hair_color: Option<String>,\n}\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let db_url = std::env::var(\"DATABASE_URL\").unwrap();\n\n    // set up connection pool\n    let manager = deadpool_diesel::postgres::Manager::new(db_url, deadpool_diesel::Runtime::Tokio1);\n    let pool = deadpool_diesel::postgres::Pool::builder(manager)\n        .build()\n        .unwrap();\n\n    // run the migrations on server startup\n    {\n        let conn = pool.get().await.unwrap();\n        conn.interact(|conn| conn.run_pending_migrations(MIGRATIONS).map(|_| ()))\n            .await\n            .unwrap()\n            .unwrap();\n    }\n\n    // build our application with some routes\n    let app = Router::new()\n        .route(\"/user/list\", get(list_users))\n        .route(\"/user/create\", post(create_user))\n        .with_state(pool);\n\n    // run it with hyper\n    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));\n    tracing::debug!(\"listening on {addr}\");\n    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();\n    axum::serve(listener, app).await;\n}\n\nasync fn create_user(\n    State(pool): State<deadpool_diesel::postgres::Pool>,\n    Json(new_user): Json<NewUser>,\n) -> Result<Json<User>, (StatusCode, String)> {\n    let conn = pool.get().await.map_err(internal_error)?;\n    let res = conn\n        .interact(|conn| {\n            diesel::insert_into(users::table)\n                .values(new_user)\n                .returning(User::as_returning())\n                .get_result(conn)\n        })\n        .await\n        .map_err(internal_error)?\n        .map_err(internal_error)?;\n    Ok(Json(res))\n}\n\nasync fn list_users(\n    State(pool): State<deadpool_diesel::postgres::Pool>,\n) -> Result<Json<Vec<User>>, (StatusCode, String)> {\n    let conn = pool.get().await.map_err(internal_error)?;\n    let res = conn\n        .interact(|conn| User::query().load(conn))\n        .await\n        .map_err(internal_error)?\n        .map_err(internal_error)?;\n    Ok(Json(res))\n}\n\n/// Utility function for mapping any error into a `500 Internal Server Error`\n/// response.\nfn internal_error<E>(err: E) -> (StatusCode, String)\nwhere\n    E: std::error::Error,\n{\n    (StatusCode::INTERNAL_SERVER_ERROR, err.to_string())\n}\n"
  },
  {
    "path": "examples/error-handling/Cargo.toml",
    "content": "[package]\nname = \"example-error-handling\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"macros\"] }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower-http = { version = \"0.6.1\", features = [\"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/error-handling/src/main.rs",
    "content": "//! Example showing how to convert errors into responses.\n//!\n//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-error-handling\n//! ```\n//!\n//! For successful requests the log output will be\n//!\n//! ```ignore\n//! DEBUG request{method=POST uri=/users matched_path=\"/users\"}: tower_http::trace::on_request: started processing request\n//! DEBUG request{method=POST uri=/users matched_path=\"/users\"}: tower_http::trace::on_response: finished processing request latency=0 ms status=200\n//! ```\n//!\n//! For failed requests the log output will be\n//!\n//! ```ignore\n//! DEBUG request{method=POST uri=/users matched_path=\"/users\"}: tower_http::trace::on_request: started processing request\n//! ERROR request{method=POST uri=/users matched_path=\"/users\"}: example_error_handling: error from time_library err=failed to get time\n//! DEBUG request{method=POST uri=/users matched_path=\"/users\"}: tower_http::trace::on_response: finished processing request latency=0 ms status=500\n//! ```\n\nuse std::{\n    collections::HashMap,\n    sync::{\n        atomic::{AtomicU64, Ordering},\n        Arc, Mutex,\n    },\n};\n\nuse axum::{\n    extract::{rejection::JsonRejection, FromRequest, MatchedPath, Request, State},\n    http::StatusCode,\n    middleware::{from_fn, Next},\n    response::{IntoResponse, Response},\n    routing::post,\n    Router,\n};\nuse serde::{Deserialize, Serialize};\nuse time_library::Timestamp;\nuse tower_http::trace::TraceLayer;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let state = AppState::default();\n\n    let app = Router::new()\n        // A dummy route that accepts some JSON but sometimes fails\n        .route(\"/users\", post(users_create))\n        .layer(\n            TraceLayer::new_for_http()\n                // Create our own span for the request and include the matched path. The matched\n                // path is useful for figuring out which handler the request was routed to.\n                .make_span_with(|req: &Request| {\n                    let method = req.method();\n                    let uri = req.uri();\n\n                    // axum automatically adds this extension.\n                    let matched_path = req\n                        .extensions()\n                        .get::<MatchedPath>()\n                        .map(|matched_path| matched_path.as_str());\n\n                    tracing::debug_span!(\"request\", %method, %uri, matched_path)\n                })\n                // By default `TraceLayer` will log 5xx responses but we're doing our specific\n                // logging of errors so disable that\n                .on_failure(()),\n        )\n        .layer(from_fn(log_app_errors))\n        .with_state(state);\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n#[derive(Default, Clone)]\nstruct AppState {\n    next_id: Arc<AtomicU64>,\n    users: Arc<Mutex<HashMap<u64, User>>>,\n}\n\n#[derive(Deserialize)]\nstruct UserParams {\n    name: String,\n}\n\n#[derive(Serialize, Clone)]\nstruct User {\n    id: u64,\n    name: String,\n    created_at: Timestamp,\n}\n\nasync fn users_create(\n    State(state): State<AppState>,\n    // Make sure to use our own JSON extractor so we get input errors formatted in a way that\n    // matches our application\n    AppJson(params): AppJson<UserParams>,\n) -> Result<AppJson<User>, AppError> {\n    let id = state.next_id.fetch_add(1, Ordering::SeqCst);\n\n    // We have implemented `From<time_library::Error> for AppError` which allows us to use `?` to\n    // automatically convert the error\n    let created_at = Timestamp::now()?;\n\n    let user = User {\n        id,\n        name: params.name,\n        created_at,\n    };\n\n    state.users.lock().unwrap().insert(id, user.clone());\n\n    Ok(AppJson(user))\n}\n\n// Create our own JSON extractor by wrapping `axum::Json`. This makes it easy to override the\n// rejection and provide our own which formats errors to match our application.\n//\n// `axum::Json` responds with plain text if the input is invalid.\n#[derive(FromRequest)]\n#[from_request(via(axum::Json), rejection(AppError))]\nstruct AppJson<T>(T);\n\nimpl<T> IntoResponse for AppJson<T>\nwhere\n    axum::Json<T>: IntoResponse,\n{\n    fn into_response(self) -> Response {\n        axum::Json(self.0).into_response()\n    }\n}\n\n// The kinds of errors we can hit in our application.\n#[derive(Debug)]\nenum AppError {\n    // The request body contained invalid JSON\n    JsonRejection(JsonRejection),\n    // Some error from a third party library we're using\n    TimeError(time_library::Error),\n}\n\n// Tell axum how `AppError` should be converted into a response.\nimpl IntoResponse for AppError {\n    fn into_response(self) -> Response {\n        // How we want errors responses to be serialized\n        #[derive(Serialize)]\n        struct ErrorResponse {\n            message: String,\n        }\n\n        let (status, message, err) = match &self {\n            AppError::JsonRejection(rejection) => {\n                // This error is caused by bad user input so don't log it\n                (rejection.status(), rejection.body_text(), None)\n            }\n            AppError::TimeError(_err) => {\n                // While we could simply log the error here we would introduce\n                // a side-effect to our conversion, instead add the AppError to\n                // the Response as an Extension\n                // Don't expose any details about the error to the client\n                (\n                    StatusCode::INTERNAL_SERVER_ERROR,\n                    \"Something went wrong\".to_owned(),\n                    Some(self),\n                )\n            }\n        };\n\n        let mut response = (status, AppJson(ErrorResponse { message })).into_response();\n        if let Some(err) = err {\n            // Insert our error into the response, our logging middleware will use this.\n            // By wrapping the error in an Arc we can use it as an Extension regardless of any inner types not deriving Clone.\n            response.extensions_mut().insert(Arc::new(err));\n        }\n        response\n    }\n}\n\nimpl From<JsonRejection> for AppError {\n    fn from(rejection: JsonRejection) -> Self {\n        Self::JsonRejection(rejection)\n    }\n}\n\nimpl From<time_library::Error> for AppError {\n    fn from(error: time_library::Error) -> Self {\n        Self::TimeError(error)\n    }\n}\n\n// Our middleware is responsible for logging error details internally\nasync fn log_app_errors(request: Request, next: Next) -> Response {\n    let response = next.run(request).await;\n    // If the response contains an AppError Extension, log it.\n    if let Some(err) = response.extensions().get::<Arc<AppError>>() {\n        tracing::error!(?err, \"an unexpected error occurred inside a handler\");\n    }\n    response\n}\n\n// Imagine this is some third party library that we're using. It sometimes returns errors which we\n// want to log.\nmod time_library {\n    use std::sync::atomic::{AtomicU64, Ordering};\n\n    use serde::Serialize;\n\n    #[derive(Serialize, Clone)]\n    pub struct Timestamp(u64);\n\n    impl Timestamp {\n        pub fn now() -> Result<Self, Error> {\n            static COUNTER: AtomicU64 = AtomicU64::new(0);\n\n            // Fail on every third call just to simulate errors\n            if COUNTER.fetch_add(1, Ordering::SeqCst).is_multiple_of(3) {\n                Err(Error::FailedToGetTime)\n            } else {\n                Ok(Self(1337))\n            }\n        }\n    }\n\n    #[derive(Debug, Clone)]\n    pub enum Error {\n        FailedToGetTime,\n    }\n\n    impl std::fmt::Display for Error {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            write!(f, \"failed to get time\")\n        }\n    }\n}\n"
  },
  {
    "path": "examples/form/Cargo.toml",
    "content": "[package]\nname = \"example-form\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\n[dev-dependencies]\nhttp-body-util = \"0.1.3\"\nmime = \"0.3.17\"\ntower = \"0.5.2\"\n"
  },
  {
    "path": "examples/form/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-form\n//! ```\n\nuse axum::{extract::Form, response::Html, routing::get, Router};\nuse serde::Deserialize;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with some routes\n    let app = app();\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nfn app() -> Router {\n    Router::new().route(\"/\", get(show_form).post(accept_form))\n}\n\nasync fn show_form() -> Html<&'static str> {\n    Html(\n        r#\"\n        <!doctype html>\n        <html>\n            <head></head>\n            <body>\n                <form action=\"/\" method=\"post\">\n                    <label for=\"name\">\n                        Enter your name:\n                        <input type=\"text\" name=\"name\">\n                    </label>\n\n                    <label>\n                        Enter your email:\n                        <input type=\"text\" name=\"email\">\n                    </label>\n\n                    <input type=\"submit\" value=\"Subscribe!\">\n                </form>\n            </body>\n        </html>\n        \"#,\n    )\n}\n\n#[derive(Deserialize, Debug)]\n#[allow(dead_code)]\nstruct Input {\n    name: String,\n    email: String,\n}\n\nasync fn accept_form(Form(input): Form<Input>) -> Html<String> {\n    dbg!(&input);\n    Html(format!(\n        \"email='{}'\\nname='{}'\\n\",\n        &input.email, &input.name\n    ))\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{\n        body::Body,\n        http::{self, Request, StatusCode},\n    };\n    use http_body_util::BodyExt;\n    use tower::ServiceExt; // for `call`, `oneshot`, and `ready` // for `collect`\n\n    #[tokio::test]\n    async fn test_get() {\n        let app = app();\n\n        let response = app\n            .oneshot(Request::get(\"/\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n\n        let body = response.into_body().collect().await.unwrap().to_bytes();\n        let body = std::str::from_utf8(&body).unwrap();\n\n        assert!(body.contains(r#\"<input type=\"submit\" value=\"Subscribe!\">\"#));\n    }\n\n    #[tokio::test]\n    async fn test_post() {\n        let app = app();\n\n        let response = app\n            .oneshot(\n                Request::post(\"/\")\n                    .header(\n                        http::header::CONTENT_TYPE,\n                        mime::APPLICATION_WWW_FORM_URLENCODED.as_ref(),\n                    )\n                    .body(Body::from(\"name=foo&email=bar@axum\"))\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n\n        let body = response.into_body().collect().await.unwrap().to_bytes();\n        let body = std::str::from_utf8(&body).unwrap();\n\n        assert_eq!(body, \"email='bar@axum'\\nname='foo'\\n\");\n    }\n}\n"
  },
  {
    "path": "examples/global-404-handler/Cargo.toml",
    "content": "[package]\nname = \"example-global-404-handler\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/global-404-handler/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-global-404-handler\n//! ```\n\nuse axum::{\n    http::StatusCode,\n    response::{Html, IntoResponse},\n    routing::get,\n    Router,\n};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with a route\n    let app = Router::new().route(\"/\", get(handler));\n\n    // add a fallback service for handling routes to unknown paths\n    let app = app.fallback(handler_404);\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler() -> Html<&'static str> {\n    Html(\"<h1>Hello, World!</h1>\")\n}\n\nasync fn handler_404() -> impl IntoResponse {\n    (StatusCode::NOT_FOUND, \"nothing to see here\")\n}\n"
  },
  {
    "path": "examples/graceful-shutdown/Cargo.toml",
    "content": "[package]\nname = \"example-graceful-shutdown\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"tracing\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower-http = { version = \"0.6\", features = [\"timeout\", \"trace\"] }\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/graceful-shutdown/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-graceful-shutdown\n//! kill or ctrl-c\n//! ```\n\nuse std::time::Duration;\n\nuse axum::{http::StatusCode, routing::get, Router};\nuse tokio::net::TcpListener;\nuse tokio::signal;\nuse tokio::time::sleep;\nuse tower_http::timeout::TimeoutLayer;\nuse tower_http::trace::TraceLayer;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    // Enable tracing.\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\n                    \"{}=debug,tower_http=debug,axum=trace\",\n                    env!(\"CARGO_CRATE_NAME\")\n                )\n                .into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer().without_time())\n        .init();\n\n    // Create a regular axum app.\n    let app = Router::new()\n        .route(\"/slow\", get(|| sleep(Duration::from_secs(5))))\n        .route(\"/forever\", get(std::future::pending::<()>))\n        .layer((\n            TraceLayer::new_for_http(),\n            // Graceful shutdown will wait for outstanding requests to complete. Add a timeout so\n            // requests don't hang forever.\n            TimeoutLayer::with_status_code(StatusCode::REQUEST_TIMEOUT, Duration::from_secs(10)),\n        ));\n\n    // Create a `TcpListener` using tokio.\n    let listener = TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n\n    // Run the server with graceful shutdown\n    axum::serve(listener, app)\n        .with_graceful_shutdown(shutdown_signal())\n        .await;\n}\n\nasync fn shutdown_signal() {\n    let ctrl_c = async {\n        signal::ctrl_c()\n            .await\n            .expect(\"failed to install Ctrl+C handler\");\n    };\n\n    #[cfg(unix)]\n    let terminate = async {\n        signal::unix::signal(signal::unix::SignalKind::terminate())\n            .expect(\"failed to install signal handler\")\n            .recv()\n            .await;\n    };\n\n    #[cfg(not(unix))]\n    let terminate = std::future::pending::<()>();\n\n    tokio::select! {\n        _ = ctrl_c => {},\n        _ = terminate => {},\n    }\n}\n"
  },
  {
    "path": "examples/handle-head-request/Cargo.toml",
    "content": "[package]\nname = \"example-handle-head-request\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\n\n[dev-dependencies]\nhttp-body-util = \"0.1.0\"\nhyper = { version = \"1.0.0\", features = [\"full\"] }\ntower = { version = \"0.5.2\", features = [\"util\"] }\n"
  },
  {
    "path": "examples/handle-head-request/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-handle-head-request\n//! ```\n\nuse axum::response::{IntoResponse, Response};\nuse axum::{http, routing::get, Router};\n\nfn app() -> Router {\n    Router::new().route(\"/get-head\", get(get_head_handler))\n}\n\n#[tokio::main]\nasync fn main() {\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app()).await;\n}\n\n// GET routes will also be called for HEAD requests but will have the response body removed.\n// You can handle the HEAD method explicitly by extracting `http::Method` from the request.\nasync fn get_head_handler(method: http::Method) -> Response {\n    // it usually only makes sense to special-case HEAD\n    // if computing the body has some relevant cost\n    if method == http::Method::HEAD {\n        return ([(\"x-some-header\", \"header from HEAD\")]).into_response();\n    }\n\n    // then do some computing task in GET\n    do_some_computing_task();\n\n    ([(\"x-some-header\", \"header from GET\")], \"body from GET\").into_response()\n}\n\nfn do_some_computing_task() {\n    // TODO\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::body::Body;\n    use axum::http::{Request, StatusCode};\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    #[tokio::test]\n    async fn test_get() {\n        let app = app();\n\n        let response = app\n            .oneshot(Request::get(\"/get-head\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n        assert_eq!(response.headers()[\"x-some-header\"], \"header from GET\");\n\n        let body = response.collect().await.unwrap().to_bytes();\n        assert_eq!(&body[..], b\"body from GET\");\n    }\n\n    #[tokio::test]\n    async fn test_implicit_head() {\n        let app = app();\n\n        let response = app\n            .oneshot(Request::head(\"/get-head\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n        assert_eq!(response.headers()[\"x-some-header\"], \"header from HEAD\");\n\n        let body = response.collect().await.unwrap().to_bytes();\n        assert!(body.is_empty());\n    }\n}\n"
  },
  {
    "path": "examples/hello-world/Cargo.toml",
    "content": "[package]\nname = \"example-hello-world\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\n"
  },
  {
    "path": "examples/hello-world/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-hello-world\n//! ```\n\nuse axum::{response::Html, routing::get, Router};\n\n#[tokio::main]\nasync fn main() {\n    // build our application with a route\n    let app = Router::new().route(\"/\", get(handler));\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler() -> Html<&'static str> {\n    Html(\"<h1>Hello, World!</h1>\")\n}\n"
  },
  {
    "path": "examples/http-proxy/Cargo.toml",
    "content": "[package]\nname = \"example-http-proxy\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhyper = { version = \"1\", features = [\"full\"] }\nhyper-util = \"0.1.1\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower = { version = \"0.5.2\", features = [\"make\", \"util\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/http-proxy/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! $ cargo run -p example-http-proxy\n//! ```\n//!\n//! In another terminal:\n//!\n//! ```not_rust\n//! $ curl -v -x \"127.0.0.1:3000\" https://tokio.rs\n//! ```\n//!\n//! Example is based on <https://github.com/hyperium/hyper/blob/master/examples/http_proxy.rs>\n\nuse axum::{\n    body::Body,\n    extract::Request,\n    http::{Method, StatusCode},\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\n\nuse hyper::body::Incoming;\nuse hyper::server::conn::http1;\nuse hyper::upgrade::Upgraded;\nuse std::net::SocketAddr;\nuse tokio::net::{TcpListener, TcpStream};\nuse tower::Service;\nuse tower::ServiceExt;\n\nuse hyper_util::rt::TokioIo;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=trace,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let router_svc = Router::new().route(\"/\", get(|| async { \"Hello, World!\" }));\n\n    let tower_service = tower::service_fn(move |req: Request<_>| {\n        let router_svc = router_svc.clone();\n        let req = req.map(Body::new);\n        async move {\n            if req.method() == Method::CONNECT {\n                proxy(req).await\n            } else {\n                router_svc.oneshot(req).await.map_err(|err| match err {})\n            }\n        }\n    });\n\n    let hyper_service = hyper::service::service_fn(move |request: Request<Incoming>| {\n        tower_service.clone().call(request)\n    });\n\n    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));\n    tracing::debug!(\"listening on {}\", addr);\n\n    let listener = TcpListener::bind(addr).await.unwrap();\n    loop {\n        let (stream, _) = listener.accept().await.unwrap();\n        let io = TokioIo::new(stream);\n        let hyper_service = hyper_service.clone();\n        tokio::task::spawn(async move {\n            if let Err(err) = http1::Builder::new()\n                .preserve_header_case(true)\n                .title_case_headers(true)\n                .serve_connection(io, hyper_service)\n                .with_upgrades()\n                .await\n            {\n                println!(\"Failed to serve connection: {err:?}\");\n            }\n        });\n    }\n}\n\nasync fn proxy(req: Request) -> Result<Response, hyper::Error> {\n    tracing::trace!(?req);\n\n    if let Some(host_addr) = req.uri().authority().map(|auth| auth.to_string()) {\n        tokio::task::spawn(async move {\n            match hyper::upgrade::on(req).await {\n                Ok(upgraded) => {\n                    if let Err(e) = tunnel(upgraded, host_addr).await {\n                        tracing::warn!(\"server io error: {}\", e);\n                    };\n                }\n                Err(e) => tracing::warn!(\"upgrade error: {}\", e),\n            }\n        });\n\n        Ok(Response::new(Body::empty()))\n    } else {\n        tracing::warn!(\"CONNECT host is not socket addr: {:?}\", req.uri());\n        Ok((\n            StatusCode::BAD_REQUEST,\n            \"CONNECT must be to a socket address\",\n        )\n            .into_response())\n    }\n}\n\nasync fn tunnel(upgraded: Upgraded, addr: String) -> std::io::Result<()> {\n    let mut server = TcpStream::connect(addr).await?;\n    let mut upgraded = TokioIo::new(upgraded);\n\n    let (from_client, from_server) =\n        tokio::io::copy_bidirectional(&mut upgraded, &mut server).await?;\n\n    tracing::debug!(\n        \"client wrote {} bytes and received {} bytes\",\n        from_client,\n        from_server\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/jwt/Cargo.toml",
    "content": "[package]\nname = \"example-jwt\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\naxum-extra = { path = \"../../axum-extra\", features = [\"typed-header\"] }\njsonwebtoken = { version = \"10\", features = [\"aws_lc_rs\"] }\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/jwt/src/main.rs",
    "content": "//! Example JWT authorization/authentication.\n//!\n//! Run with\n//!\n//! ```not_rust\n//! JWT_SECRET=secret cargo run -p example-jwt\n//! ```\n\nuse axum::{\n    extract::FromRequestParts,\n    http::{request::Parts, StatusCode},\n    response::{IntoResponse, Response},\n    routing::{get, post},\n    Json, RequestPartsExt, Router,\n};\nuse axum_extra::{\n    headers::{authorization::Bearer, Authorization},\n    TypedHeader,\n};\nuse jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};\nuse serde::{Deserialize, Serialize};\nuse serde_json::json;\nuse std::fmt::Display;\nuse std::sync::LazyLock;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n// Quick instructions\n//\n// - get an authorization token:\n//\n// curl -s \\\n//     -w '\\n' \\\n//     -H 'Content-Type: application/json' \\\n//     -d '{\"client_id\":\"foo\",\"client_secret\":\"bar\"}' \\\n//     http://localhost:3000/authorize\n//\n// - visit the protected area using the authorized token\n//\n// curl -s \\\n//     -w '\\n' \\\n//     -H 'Content-Type: application/json' \\\n//     -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJiQGIuY29tIiwiY29tcGFueSI6IkFDTUUiLCJleHAiOjEwMDAwMDAwMDAwfQ.M3LAZmrzUkXDC1q5mSzFAs_kJrwuKz3jOoDmjJ0G4gM' \\\n//     http://localhost:3000/protected\n//\n// - try to visit the protected area using an invalid token\n//\n// curl -s \\\n//     -w '\\n' \\\n//     -H 'Content-Type: application/json' \\\n//     -H 'Authorization: Bearer blahblahblah' \\\n//     http://localhost:3000/protected\n\nstatic KEYS: LazyLock<Keys> = LazyLock::new(|| {\n    let secret = std::env::var(\"JWT_SECRET\").expect(\"JWT_SECRET must be set\");\n    Keys::new(secret.as_bytes())\n});\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let app = Router::new()\n        .route(\"/protected\", get(protected))\n        .route(\"/authorize\", post(authorize));\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn protected(claims: Claims) -> Result<String, AuthError> {\n    // Send the protected data to the user\n    Ok(format!(\n        \"Welcome to the protected area :)\\nYour data:\\n{claims}\",\n    ))\n}\n\nasync fn authorize(Json(payload): Json<AuthPayload>) -> Result<Json<AuthBody>, AuthError> {\n    // Check if the user sent the credentials\n    if payload.client_id.is_empty() || payload.client_secret.is_empty() {\n        return Err(AuthError::MissingCredentials);\n    }\n    // Here you can check the user credentials from a database\n    if payload.client_id != \"foo\" || payload.client_secret != \"bar\" {\n        return Err(AuthError::WrongCredentials);\n    }\n    let claims = Claims {\n        sub: \"b@b.com\".to_owned(),\n        company: \"ACME\".to_owned(),\n        // Mandatory expiry time as UTC timestamp\n        exp: 2000000000, // May 2033\n    };\n    // Create the authorization token\n    let token = encode(&Header::default(), &claims, &KEYS.encoding)\n        .map_err(|_| AuthError::TokenCreation)?;\n\n    // Send the authorized token\n    Ok(Json(AuthBody::new(token)))\n}\n\nimpl Display for Claims {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"Email: {}\\nCompany: {}\", self.sub, self.company)\n    }\n}\n\nimpl AuthBody {\n    fn new(access_token: String) -> Self {\n        Self {\n            access_token,\n            token_type: \"Bearer\".to_string(),\n        }\n    }\n}\n\nimpl<S> FromRequestParts<S> for Claims\nwhere\n    S: Send + Sync,\n{\n    type Rejection = AuthError;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        // Extract the token from the authorization header\n        let TypedHeader(Authorization(bearer)) = parts\n            .extract::<TypedHeader<Authorization<Bearer>>>()\n            .await\n            .map_err(|_| AuthError::InvalidToken)?;\n        // Decode the user data\n        let token_data = decode::<Claims>(bearer.token(), &KEYS.decoding, &Validation::default())\n            .map_err(|_| AuthError::InvalidToken)?;\n\n        Ok(token_data.claims)\n    }\n}\n\nimpl IntoResponse for AuthError {\n    fn into_response(self) -> Response {\n        let (status, error_message) = match self {\n            AuthError::WrongCredentials => (StatusCode::UNAUTHORIZED, \"Wrong credentials\"),\n            AuthError::MissingCredentials => (StatusCode::BAD_REQUEST, \"Missing credentials\"),\n            AuthError::TokenCreation => (StatusCode::INTERNAL_SERVER_ERROR, \"Token creation error\"),\n            AuthError::InvalidToken => (StatusCode::BAD_REQUEST, \"Invalid token\"),\n        };\n        let body = Json(json!({\n            \"error\": error_message,\n        }));\n        (status, body).into_response()\n    }\n}\n\nstruct Keys {\n    encoding: EncodingKey,\n    decoding: DecodingKey,\n}\n\nimpl Keys {\n    fn new(secret: &[u8]) -> Self {\n        Self {\n            encoding: EncodingKey::from_secret(secret),\n            decoding: DecodingKey::from_secret(secret),\n        }\n    }\n}\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\nstruct Claims {\n    sub: String,\n    company: String,\n    exp: usize,\n}\n\n#[derive(Debug, Serialize)]\nstruct AuthBody {\n    access_token: String,\n    token_type: String,\n}\n\n#[derive(Debug, Deserialize)]\nstruct AuthPayload {\n    client_id: String,\n    client_secret: String,\n}\n\n#[derive(Debug)]\nenum AuthError {\n    WrongCredentials,\n    MissingCredentials,\n    TokenCreation,\n    InvalidToken,\n}\n"
  },
  {
    "path": "examples/key-value-store/Cargo.toml",
    "content": "[package]\nname = \"example-key-value-store\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower = { version = \"0.5.2\", features = [\"util\", \"timeout\", \"load-shed\", \"limit\"] }\ntower-http = { version = \"0.6.1\", features = [\n    \"add-extension\",\n    \"auth\",\n    \"compression-full\",\n    \"limit\",\n    \"trace\",\n] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/key-value-store/src/main.rs",
    "content": "//! Simple in-memory key/value store showing features of axum.\n//!\n//! Run with:\n//!\n//! ```not_rust\n//! cargo run -p example-key-value-store\n//! ```\n\nuse axum::{\n    body::Bytes,\n    error_handling::HandleErrorLayer,\n    extract::{DefaultBodyLimit, Path, State},\n    handler::Handler,\n    http::StatusCode,\n    response::IntoResponse,\n    routing::{delete, get},\n    Router,\n};\nuse std::{\n    borrow::Cow,\n    collections::HashMap,\n    sync::{Arc, RwLock},\n    time::Duration,\n};\nuse tower::{BoxError, ServiceBuilder};\nuse tower_http::{\n    compression::CompressionLayer, limit::RequestBodyLimitLayer, trace::TraceLayer,\n    validate_request::ValidateRequestHeaderLayer,\n};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let shared_state = SharedState::default();\n\n    // Build our application by composing routes\n    let app = Router::new()\n        .route(\n            \"/{key}\",\n            // Add compression to `kv_get`\n            get(kv_get.layer(CompressionLayer::new()))\n                // But don't compress `kv_set`\n                .post_service(\n                    kv_set\n                        .layer((\n                            DefaultBodyLimit::disable(),\n                            RequestBodyLimitLayer::new(1024 * 5_000 /* ~5mb */),\n                        ))\n                        .with_state(Arc::clone(&shared_state)),\n                ),\n        )\n        .route(\"/keys\", get(list_keys))\n        // Nest our admin routes under `/admin`\n        .nest(\"/admin\", admin_routes())\n        // Add middleware to all routes\n        .layer(\n            ServiceBuilder::new()\n                // Handle errors from middleware\n                .layer(HandleErrorLayer::new(handle_error))\n                .load_shed()\n                .concurrency_limit(1024)\n                .timeout(Duration::from_secs(10))\n                .layer(TraceLayer::new_for_http()),\n        )\n        .with_state(Arc::clone(&shared_state));\n\n    // Run our app with hyper\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\ntype SharedState = Arc<RwLock<AppState>>;\n\n#[derive(Default)]\nstruct AppState {\n    db: HashMap<String, Bytes>,\n}\n\nasync fn kv_get(\n    Path(key): Path<String>,\n    State(state): State<SharedState>,\n) -> Result<Bytes, StatusCode> {\n    let db = &state.read().unwrap().db;\n\n    if let Some(value) = db.get(&key) {\n        Ok(value.clone())\n    } else {\n        Err(StatusCode::NOT_FOUND)\n    }\n}\n\nasync fn kv_set(Path(key): Path<String>, State(state): State<SharedState>, bytes: Bytes) {\n    state.write().unwrap().db.insert(key, bytes);\n}\n\nasync fn list_keys(State(state): State<SharedState>) -> String {\n    let db = &state.read().unwrap().db;\n\n    db.keys()\n        .map(|key| key.to_string())\n        .collect::<Vec<String>>()\n        .join(\"\\n\")\n}\n\nfn admin_routes() -> Router<SharedState> {\n    async fn delete_all_keys(State(state): State<SharedState>) {\n        state.write().unwrap().db.clear();\n    }\n\n    async fn remove_key(Path(key): Path<String>, State(state): State<SharedState>) {\n        state.write().unwrap().db.remove(&key);\n    }\n\n    #[allow(deprecated)] // FIXME\n    Router::new()\n        .route(\"/keys\", delete(delete_all_keys))\n        .route(\"/key/{key}\", delete(remove_key))\n        // Require bearer auth for all admin routes\n        .layer(ValidateRequestHeaderLayer::bearer(\"secret-token\"))\n}\n\nasync fn handle_error(error: BoxError) -> impl IntoResponse {\n    if error.is::<tower::timeout::error::Elapsed>() {\n        return (StatusCode::REQUEST_TIMEOUT, Cow::from(\"request timed out\"));\n    }\n\n    if error.is::<tower::load_shed::error::Overloaded>() {\n        return (\n            StatusCode::SERVICE_UNAVAILABLE,\n            Cow::from(\"service is overloaded, try again later\"),\n        );\n    }\n\n    (\n        StatusCode::INTERNAL_SERVER_ERROR,\n        Cow::from(format!(\"Unhandled internal error: {error}\")),\n    )\n}\n"
  },
  {
    "path": "examples/low-level-native-tls/Cargo.toml",
    "content": "[package]\nname = \"example-low-level-native-tls\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhyper = { version = \"1.0.0\", features = [\"full\"] }\nhyper-util = { version = \"0.1\" }\ntokio = { version = \"1\", features = [\"full\"] }\ntokio-native-tls = \"0.3.1\"\ntower-service = \"0.3.2\"\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/low-level-native-tls/self_signed_certs/cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUXVYkRCrM/ge03DVymDtXCuybp7gwDQYJKoZIhvcNAQEL\nBQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\nGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X\nDTIxMDczMTE0MjIxMloXDTIyMDczMTE0MjIxMlowWTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\nIEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEA02V5ZjmqLB/VQwTarrz/35qsa83L+DbAoa0001+jVmmC+G9Nufi0\ndaroFWj/Uicv2fZWETU8JoZKUrX4BK9og5cg5rln/CtBRWCUYIwRgY9R/CdBGPn4\nkp+XkSJaCw74ZIyLy/Zfux6h8ES1m9YRnBza+s7U+ImRBRf4MRPtXQ3/mqJxAZYq\ndOnKnvssRyD2qutgVTAxwMUvJWIivRhRYDj7WOpS4CEEeQxP1iH1/T5P7FdtTGdT\nbVBABCA8JhL96uFGPpOYHcM/7R5EIA3yZ5FNg931QzoDITjtXGtQ6y9/l/IYkWm6\nJ67RWcN0IoTsZhz0WNU4gAeslVtJLofn8QIDAQABo1MwUTAdBgNVHQ4EFgQUzFnK\nNfS4LAYuKeWwHbzooER0yZ0wHwYDVR0jBBgwFoAUzFnKNfS4LAYuKeWwHbzooER0\nyZ0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAk4O+e9jia59W\nZwetN4GU7OWcYhmOgSizRSs6u7mTfp62LDMt96WKU3THksOnZ44HnqWQxsSfdFVU\nXJD12tjvVU8Z4FWzQajcHeemUYiDze8EAh6TnxnUcOrU8IcwiKGxCWRY/908jnWg\n+MMscfMCMYTRdeTPqD8fGzAlUCtmyzH6KLE3s4Oo/r5+NR+Uvrwpdvb7xe0MwwO9\nQ/zR4N8ep/HwHVEObcaBofE1ssZLksX7ZgCP9wMgXRWpNAtC5EWxMbxYjBfWFH24\nfDJlBMiGJWg8HHcxK7wQhFh+fuyNzE+xEWPsI9VL1zDftd9x8/QsOagyEOnY8Vxr\nAopvZ09uEQ==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/low-level-native-tls/self_signed_certs/key.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTZXlmOaosH9VD\nBNquvP/fmqxrzcv4NsChrTTTX6NWaYL4b025+LR1qugVaP9SJy/Z9lYRNTwmhkpS\ntfgEr2iDlyDmuWf8K0FFYJRgjBGBj1H8J0EY+fiSn5eRIloLDvhkjIvL9l+7HqHw\nRLWb1hGcHNr6ztT4iZEFF/gxE+1dDf+aonEBlip06cqe+yxHIPaq62BVMDHAxS8l\nYiK9GFFgOPtY6lLgIQR5DE/WIfX9Pk/sV21MZ1NtUEAEIDwmEv3q4UY+k5gdwz/t\nHkQgDfJnkU2D3fVDOgMhOO1ca1DrL3+X8hiRabonrtFZw3QihOxmHPRY1TiAB6yV\nW0kuh+fxAgMBAAECggEADltu8k1qTFLhJgsXWxTFAAe+PBgfCT2WuaRM2So+qqjB\n12Of0MieYPt5hbK63HaC3nfHgqWt7yPhulpXfOH45C8IcgMXl93MMg0MJr58leMI\n+2ojFrIrerHSFm5R1TxwDEwrVm/mMowzDWFtQCc6zPJ8wNn5RuP48HKfTZ3/2fjw\nzEjSwPO2wFMfo1EJNTjlI303lFbdFBs67NaX6puh30M7Tn+gznHKyO5a7F57wkIt\nfkgnEy/sgMedQlwX7bRpUoD6f0fZzV8Qz4cHFywtYErczZJh3VGitJoO/VCIDdty\nRPXOAqVDd7EpP1UUehZlKVWZ0OZMEfRgKbRCel5abQKBgQDwgwrIQ5+BiZv6a0VT\nETeXB+hRbvBinRykNo/RvLc3j1enRh9/zO/ShadZIXgOAiM1Jnr5Gp8KkNGca6K1\nmyhtad7xYPODYzNXXp6T1OPgZxHZLIYzVUj6ypXeV64Te5ZiDaJ1D49czsq+PqsQ\nXRcgBJSNpFtDFiXWpjXWfx8PxwKBgQDhAnLY5Sl2eeQo+ud0MvjwftB/mN2qCzJY\n5AlQpRI4ThWxJgGPuHTR29zVa5iWNYuA5LWrC1y/wx+t5HKUwq+5kxvs+npYpDJD\nZX/w0Glc6s0Jc/mFySkbw9B2LePedL7lRF5OiAyC6D106Sc9V2jlL4IflmOzt4CD\nZTNbLtC6hwKBgHfIzBXxl/9sCcMuqdg1Ovp9dbcZCaATn7ApfHd5BccmHQGyav27\nk7XF2xMJGEHhzqcqAxUNrSgV+E9vTBomrHvRvrd5Ec7eGTPqbBA0d0nMC5eeFTh7\nwV0miH20LX6Gjt9G6yJiHYSbeV5G1+vOcTYBEft5X/qJjU7aePXbWh0BAoGBAJlV\n5tgCCuhvFloK6fHYzqZtdT6O+PfpW20SMXrgkvMF22h2YvgDFrDwqKRUB47NfHzg\n3yBpxNH1ccA5/w97QO8w3gX3h6qicpJVOAPusu6cIBACFZfjRv1hyszOZwvw+Soa\nFj5kHkqTY1YpkREPYS9V2dIW1Wjic1SXgZDw7VM/AoGAP/cZ3ZHTSCDTFlItqy5C\nrIy2AiY0WJsx+K0qcvtosPOOwtnGjWHb1gdaVdfX/IRkSsX4PAOdnsyidNC5/l/m\ny8oa+5WEeGFclWFhr4dnTA766o8HrM2UjIgWWYBF2VKdptGnHxFeJWFUmeQC/xeW\nw37pCS7ykL+7gp7V0WShYsw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/low-level-native-tls/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-low-level-native-tls\n//! ```\n\nuse axum::{extract::Request, routing::get, Router};\nuse hyper::body::Incoming;\nuse hyper_util::rt::{TokioExecutor, TokioIo};\nuse std::path::PathBuf;\nuse tokio::net::TcpListener;\nuse tokio_native_tls::{\n    native_tls::{Identity, Protocol, TlsAcceptor as NativeTlsAcceptor},\n    TlsAcceptor,\n};\nuse tower_service::Service;\nuse tracing::{error, info, warn};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| \"example_low_level_rustls=debug\".into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let tls_acceptor = native_tls_acceptor(\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"key.pem\"),\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"cert.pem\"),\n    );\n\n    let tls_acceptor = TlsAcceptor::from(tls_acceptor);\n    let bind = \"[::1]:3000\";\n    let tcp_listener = TcpListener::bind(bind).await.unwrap();\n    info!(\"HTTPS server listening on {bind}. To contact curl -k https://localhost:3000\");\n    let app = Router::new().route(\"/\", get(handler));\n\n    loop {\n        let tower_service = app.clone();\n        let tls_acceptor = tls_acceptor.clone();\n\n        // Wait for new tcp connection\n        let (cnx, addr) = tcp_listener.accept().await.unwrap();\n\n        tokio::spawn(async move {\n            // Wait for tls handshake to happen\n            let Ok(stream) = tls_acceptor.accept(cnx).await else {\n                error!(\"error during tls handshake connection from {}\", addr);\n                return;\n            };\n\n            // Hyper has its own `AsyncRead` and `AsyncWrite` traits and doesn't use tokio.\n            // `TokioIo` converts between them.\n            let stream = TokioIo::new(stream);\n\n            // Hyper also has its own `Service` trait and doesn't use tower. We can use\n            // `hyper::service::service_fn` to create a hyper `Service` that calls our app through\n            // `tower::Service::call`.\n            let hyper_service = hyper::service::service_fn(move |request: Request<Incoming>| {\n                // We have to clone `tower_service` because hyper's `Service` uses `&self` whereas\n                // tower's `Service` requires `&mut self`.\n                //\n                // We don't need to call `poll_ready` since `Router` is always ready.\n                tower_service.clone().call(request)\n            });\n\n            let ret = hyper_util::server::conn::auto::Builder::new(TokioExecutor::new())\n                .serve_connection_with_upgrades(stream, hyper_service)\n                .await;\n\n            if let Err(err) = ret {\n                warn!(\"error serving connection from {addr}: {err}\");\n            }\n        });\n    }\n}\n\nasync fn handler() -> &'static str {\n    \"Hello, World!\"\n}\n\nfn native_tls_acceptor(key_file: PathBuf, cert_file: PathBuf) -> NativeTlsAcceptor {\n    let key_pem = std::fs::read_to_string(&key_file).unwrap();\n    let cert_pem = std::fs::read_to_string(&cert_file).unwrap();\n\n    let id = Identity::from_pkcs8(cert_pem.as_bytes(), key_pem.as_bytes()).unwrap();\n    NativeTlsAcceptor::builder(id)\n        // let's be modern\n        .min_protocol_version(Some(Protocol::Tlsv12))\n        .build()\n        .unwrap()\n}\n"
  },
  {
    "path": "examples/low-level-openssl/Cargo.toml",
    "content": "[package]\nname = \"example-low-level-openssl\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhyper = { version = \"1.0.0\", features = [\"full\"] }\nhyper-util = { version = \"0.1\" }\nopenssl = \"0.10\"\ntokio = { version = \"1\", features = [\"full\"] }\ntokio-openssl = \"0.6\"\ntower = { version = \"0.5.2\", features = [\"make\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/low-level-openssl/self_signed_certs/cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUXVYkRCrM/ge03DVymDtXCuybp7gwDQYJKoZIhvcNAQEL\nBQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\nGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X\nDTIxMDczMTE0MjIxMloXDTIyMDczMTE0MjIxMlowWTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\nIEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEA02V5ZjmqLB/VQwTarrz/35qsa83L+DbAoa0001+jVmmC+G9Nufi0\ndaroFWj/Uicv2fZWETU8JoZKUrX4BK9og5cg5rln/CtBRWCUYIwRgY9R/CdBGPn4\nkp+XkSJaCw74ZIyLy/Zfux6h8ES1m9YRnBza+s7U+ImRBRf4MRPtXQ3/mqJxAZYq\ndOnKnvssRyD2qutgVTAxwMUvJWIivRhRYDj7WOpS4CEEeQxP1iH1/T5P7FdtTGdT\nbVBABCA8JhL96uFGPpOYHcM/7R5EIA3yZ5FNg931QzoDITjtXGtQ6y9/l/IYkWm6\nJ67RWcN0IoTsZhz0WNU4gAeslVtJLofn8QIDAQABo1MwUTAdBgNVHQ4EFgQUzFnK\nNfS4LAYuKeWwHbzooER0yZ0wHwYDVR0jBBgwFoAUzFnKNfS4LAYuKeWwHbzooER0\nyZ0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAk4O+e9jia59W\nZwetN4GU7OWcYhmOgSizRSs6u7mTfp62LDMt96WKU3THksOnZ44HnqWQxsSfdFVU\nXJD12tjvVU8Z4FWzQajcHeemUYiDze8EAh6TnxnUcOrU8IcwiKGxCWRY/908jnWg\n+MMscfMCMYTRdeTPqD8fGzAlUCtmyzH6KLE3s4Oo/r5+NR+Uvrwpdvb7xe0MwwO9\nQ/zR4N8ep/HwHVEObcaBofE1ssZLksX7ZgCP9wMgXRWpNAtC5EWxMbxYjBfWFH24\nfDJlBMiGJWg8HHcxK7wQhFh+fuyNzE+xEWPsI9VL1zDftd9x8/QsOagyEOnY8Vxr\nAopvZ09uEQ==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/low-level-openssl/self_signed_certs/key.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTZXlmOaosH9VD\nBNquvP/fmqxrzcv4NsChrTTTX6NWaYL4b025+LR1qugVaP9SJy/Z9lYRNTwmhkpS\ntfgEr2iDlyDmuWf8K0FFYJRgjBGBj1H8J0EY+fiSn5eRIloLDvhkjIvL9l+7HqHw\nRLWb1hGcHNr6ztT4iZEFF/gxE+1dDf+aonEBlip06cqe+yxHIPaq62BVMDHAxS8l\nYiK9GFFgOPtY6lLgIQR5DE/WIfX9Pk/sV21MZ1NtUEAEIDwmEv3q4UY+k5gdwz/t\nHkQgDfJnkU2D3fVDOgMhOO1ca1DrL3+X8hiRabonrtFZw3QihOxmHPRY1TiAB6yV\nW0kuh+fxAgMBAAECggEADltu8k1qTFLhJgsXWxTFAAe+PBgfCT2WuaRM2So+qqjB\n12Of0MieYPt5hbK63HaC3nfHgqWt7yPhulpXfOH45C8IcgMXl93MMg0MJr58leMI\n+2ojFrIrerHSFm5R1TxwDEwrVm/mMowzDWFtQCc6zPJ8wNn5RuP48HKfTZ3/2fjw\nzEjSwPO2wFMfo1EJNTjlI303lFbdFBs67NaX6puh30M7Tn+gznHKyO5a7F57wkIt\nfkgnEy/sgMedQlwX7bRpUoD6f0fZzV8Qz4cHFywtYErczZJh3VGitJoO/VCIDdty\nRPXOAqVDd7EpP1UUehZlKVWZ0OZMEfRgKbRCel5abQKBgQDwgwrIQ5+BiZv6a0VT\nETeXB+hRbvBinRykNo/RvLc3j1enRh9/zO/ShadZIXgOAiM1Jnr5Gp8KkNGca6K1\nmyhtad7xYPODYzNXXp6T1OPgZxHZLIYzVUj6ypXeV64Te5ZiDaJ1D49czsq+PqsQ\nXRcgBJSNpFtDFiXWpjXWfx8PxwKBgQDhAnLY5Sl2eeQo+ud0MvjwftB/mN2qCzJY\n5AlQpRI4ThWxJgGPuHTR29zVa5iWNYuA5LWrC1y/wx+t5HKUwq+5kxvs+npYpDJD\nZX/w0Glc6s0Jc/mFySkbw9B2LePedL7lRF5OiAyC6D106Sc9V2jlL4IflmOzt4CD\nZTNbLtC6hwKBgHfIzBXxl/9sCcMuqdg1Ovp9dbcZCaATn7ApfHd5BccmHQGyav27\nk7XF2xMJGEHhzqcqAxUNrSgV+E9vTBomrHvRvrd5Ec7eGTPqbBA0d0nMC5eeFTh7\nwV0miH20LX6Gjt9G6yJiHYSbeV5G1+vOcTYBEft5X/qJjU7aePXbWh0BAoGBAJlV\n5tgCCuhvFloK6fHYzqZtdT6O+PfpW20SMXrgkvMF22h2YvgDFrDwqKRUB47NfHzg\n3yBpxNH1ccA5/w97QO8w3gX3h6qicpJVOAPusu6cIBACFZfjRv1hyszOZwvw+Soa\nFj5kHkqTY1YpkREPYS9V2dIW1Wjic1SXgZDw7VM/AoGAP/cZ3ZHTSCDTFlItqy5C\nrIy2AiY0WJsx+K0qcvtosPOOwtnGjWHb1gdaVdfX/IRkSsX4PAOdnsyidNC5/l/m\ny8oa+5WEeGFclWFhr4dnTA766o8HrM2UjIgWWYBF2VKdptGnHxFeJWFUmeQC/xeW\nw37pCS7ykL+7gp7V0WShYsw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/low-level-openssl/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-low-level-openssl\n//! ```\n\nuse axum::{http::Request, routing::get, Router};\nuse hyper::body::Incoming;\nuse hyper_util::rt::{TokioExecutor, TokioIo};\nuse openssl::ssl::{Ssl, SslAcceptor, SslFiletype, SslMethod};\nuse std::{path::PathBuf, pin::Pin};\nuse tokio::net::TcpListener;\nuse tokio_openssl::SslStream;\nuse tower::Service;\nuse tracing::{error, info, warn};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let mut tls_builder = SslAcceptor::mozilla_modern_v5(SslMethod::tls()).unwrap();\n\n    tls_builder\n        .set_certificate_file(\n            PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n                .join(\"self_signed_certs\")\n                .join(\"cert.pem\"),\n            SslFiletype::PEM,\n        )\n        .unwrap();\n\n    tls_builder\n        .set_private_key_file(\n            PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n                .join(\"self_signed_certs\")\n                .join(\"key.pem\"),\n            SslFiletype::PEM,\n        )\n        .unwrap();\n\n    tls_builder.check_private_key().unwrap();\n\n    let tls_acceptor = tls_builder.build();\n\n    let bind = \"[::1]:3000\";\n    let tcp_listener = TcpListener::bind(bind).await.unwrap();\n    info!(\"HTTPS server listening on {bind}. To contact curl -k https://localhost:3000\");\n    let app = Router::new().route(\"/\", get(handler));\n\n    loop {\n        let tower_service = app.clone();\n        let tls_acceptor = tls_acceptor.clone();\n\n        // Wait for new tcp connection\n        let (cnx, addr) = tcp_listener.accept().await.unwrap();\n\n        tokio::spawn(async move {\n            let ssl = Ssl::new(tls_acceptor.context()).unwrap();\n            let mut tls_stream = SslStream::new(ssl, cnx).unwrap();\n            if let Err(err) = SslStream::accept(Pin::new(&mut tls_stream)).await {\n                error!(\n                    \"error during tls handshake connection from {}: {}\",\n                    addr, err\n                );\n                return;\n            }\n\n            // Hyper has its own `AsyncRead` and `AsyncWrite` traits and doesn't use tokio.\n            // `TokioIo` converts between them.\n            let stream = TokioIo::new(tls_stream);\n\n            // Hyper also has its own `Service` trait and doesn't use tower. We can use\n            // `hyper::service::service_fn` to create a hyper `Service` that calls our app through\n            // `tower::Service::call`.\n            let hyper_service = hyper::service::service_fn(move |request: Request<Incoming>| {\n                // We have to clone `tower_service` because hyper's `Service` uses `&self` whereas\n                // tower's `Service` requires `&mut self`.\n                //\n                // We don't need to call `poll_ready` since `Router` is always ready.\n                tower_service.clone().call(request)\n            });\n\n            let ret = hyper_util::server::conn::auto::Builder::new(TokioExecutor::new())\n                .serve_connection_with_upgrades(stream, hyper_service)\n                .await;\n\n            if let Err(err) = ret {\n                warn!(\"error serving connection from {}: {}\", addr, err);\n            }\n        });\n    }\n}\n\nasync fn handler() -> &'static str {\n    \"Hello, World!\"\n}\n"
  },
  {
    "path": "examples/low-level-rustls/Cargo.toml",
    "content": "[package]\nname = \"example-low-level-rustls\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhyper = { version = \"1.0.0\", features = [\"full\"] }\nhyper-util = { version = \"0.1\", features = [\"http2\"] }\ntokio = { version = \"1\", features = [\"full\"] }\ntokio-rustls = \"0.26\"\ntower-service = \"0.3.2\"\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/low-level-rustls/self_signed_certs/cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUXVYkRCrM/ge03DVymDtXCuybp7gwDQYJKoZIhvcNAQEL\nBQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\nGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X\nDTIxMDczMTE0MjIxMloXDTIyMDczMTE0MjIxMlowWTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\nIEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEA02V5ZjmqLB/VQwTarrz/35qsa83L+DbAoa0001+jVmmC+G9Nufi0\ndaroFWj/Uicv2fZWETU8JoZKUrX4BK9og5cg5rln/CtBRWCUYIwRgY9R/CdBGPn4\nkp+XkSJaCw74ZIyLy/Zfux6h8ES1m9YRnBza+s7U+ImRBRf4MRPtXQ3/mqJxAZYq\ndOnKnvssRyD2qutgVTAxwMUvJWIivRhRYDj7WOpS4CEEeQxP1iH1/T5P7FdtTGdT\nbVBABCA8JhL96uFGPpOYHcM/7R5EIA3yZ5FNg931QzoDITjtXGtQ6y9/l/IYkWm6\nJ67RWcN0IoTsZhz0WNU4gAeslVtJLofn8QIDAQABo1MwUTAdBgNVHQ4EFgQUzFnK\nNfS4LAYuKeWwHbzooER0yZ0wHwYDVR0jBBgwFoAUzFnKNfS4LAYuKeWwHbzooER0\nyZ0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAk4O+e9jia59W\nZwetN4GU7OWcYhmOgSizRSs6u7mTfp62LDMt96WKU3THksOnZ44HnqWQxsSfdFVU\nXJD12tjvVU8Z4FWzQajcHeemUYiDze8EAh6TnxnUcOrU8IcwiKGxCWRY/908jnWg\n+MMscfMCMYTRdeTPqD8fGzAlUCtmyzH6KLE3s4Oo/r5+NR+Uvrwpdvb7xe0MwwO9\nQ/zR4N8ep/HwHVEObcaBofE1ssZLksX7ZgCP9wMgXRWpNAtC5EWxMbxYjBfWFH24\nfDJlBMiGJWg8HHcxK7wQhFh+fuyNzE+xEWPsI9VL1zDftd9x8/QsOagyEOnY8Vxr\nAopvZ09uEQ==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/low-level-rustls/self_signed_certs/key.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTZXlmOaosH9VD\nBNquvP/fmqxrzcv4NsChrTTTX6NWaYL4b025+LR1qugVaP9SJy/Z9lYRNTwmhkpS\ntfgEr2iDlyDmuWf8K0FFYJRgjBGBj1H8J0EY+fiSn5eRIloLDvhkjIvL9l+7HqHw\nRLWb1hGcHNr6ztT4iZEFF/gxE+1dDf+aonEBlip06cqe+yxHIPaq62BVMDHAxS8l\nYiK9GFFgOPtY6lLgIQR5DE/WIfX9Pk/sV21MZ1NtUEAEIDwmEv3q4UY+k5gdwz/t\nHkQgDfJnkU2D3fVDOgMhOO1ca1DrL3+X8hiRabonrtFZw3QihOxmHPRY1TiAB6yV\nW0kuh+fxAgMBAAECggEADltu8k1qTFLhJgsXWxTFAAe+PBgfCT2WuaRM2So+qqjB\n12Of0MieYPt5hbK63HaC3nfHgqWt7yPhulpXfOH45C8IcgMXl93MMg0MJr58leMI\n+2ojFrIrerHSFm5R1TxwDEwrVm/mMowzDWFtQCc6zPJ8wNn5RuP48HKfTZ3/2fjw\nzEjSwPO2wFMfo1EJNTjlI303lFbdFBs67NaX6puh30M7Tn+gznHKyO5a7F57wkIt\nfkgnEy/sgMedQlwX7bRpUoD6f0fZzV8Qz4cHFywtYErczZJh3VGitJoO/VCIDdty\nRPXOAqVDd7EpP1UUehZlKVWZ0OZMEfRgKbRCel5abQKBgQDwgwrIQ5+BiZv6a0VT\nETeXB+hRbvBinRykNo/RvLc3j1enRh9/zO/ShadZIXgOAiM1Jnr5Gp8KkNGca6K1\nmyhtad7xYPODYzNXXp6T1OPgZxHZLIYzVUj6ypXeV64Te5ZiDaJ1D49czsq+PqsQ\nXRcgBJSNpFtDFiXWpjXWfx8PxwKBgQDhAnLY5Sl2eeQo+ud0MvjwftB/mN2qCzJY\n5AlQpRI4ThWxJgGPuHTR29zVa5iWNYuA5LWrC1y/wx+t5HKUwq+5kxvs+npYpDJD\nZX/w0Glc6s0Jc/mFySkbw9B2LePedL7lRF5OiAyC6D106Sc9V2jlL4IflmOzt4CD\nZTNbLtC6hwKBgHfIzBXxl/9sCcMuqdg1Ovp9dbcZCaATn7ApfHd5BccmHQGyav27\nk7XF2xMJGEHhzqcqAxUNrSgV+E9vTBomrHvRvrd5Ec7eGTPqbBA0d0nMC5eeFTh7\nwV0miH20LX6Gjt9G6yJiHYSbeV5G1+vOcTYBEft5X/qJjU7aePXbWh0BAoGBAJlV\n5tgCCuhvFloK6fHYzqZtdT6O+PfpW20SMXrgkvMF22h2YvgDFrDwqKRUB47NfHzg\n3yBpxNH1ccA5/w97QO8w3gX3h6qicpJVOAPusu6cIBACFZfjRv1hyszOZwvw+Soa\nFj5kHkqTY1YpkREPYS9V2dIW1Wjic1SXgZDw7VM/AoGAP/cZ3ZHTSCDTFlItqy5C\nrIy2AiY0WJsx+K0qcvtosPOOwtnGjWHb1gdaVdfX/IRkSsX4PAOdnsyidNC5/l/m\ny8oa+5WEeGFclWFhr4dnTA766o8HrM2UjIgWWYBF2VKdptGnHxFeJWFUmeQC/xeW\nw37pCS7ykL+7gp7V0WShYsw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/low-level-rustls/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-low-level-rustls\n//! ```\n\nuse axum::{extract::Request, routing::get, Router};\nuse hyper::body::Incoming;\nuse hyper_util::rt::{TokioExecutor, TokioIo};\nuse std::{\n    path::{Path, PathBuf},\n    sync::Arc,\n};\nuse tokio::net::TcpListener;\nuse tokio_rustls::{\n    rustls::pki_types::{pem::PemObject, CertificateDer, PrivateKeyDer},\n    rustls::ServerConfig,\n    TlsAcceptor,\n};\nuse tower_service::Service;\nuse tracing::{error, info, warn};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let rustls_config = rustls_server_config(\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"key.pem\"),\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"cert.pem\"),\n    );\n\n    let tls_acceptor = TlsAcceptor::from(rustls_config);\n    let bind = \"[::1]:3000\";\n    let tcp_listener = TcpListener::bind(bind).await.unwrap();\n    info!(\"HTTPS server listening on {bind}. To contact curl -k https://localhost:3000\");\n    let app = Router::new().route(\"/\", get(handler));\n\n    loop {\n        let tower_service = app.clone();\n        let tls_acceptor = tls_acceptor.clone();\n\n        // Wait for new tcp connection\n        let (cnx, addr) = tcp_listener.accept().await.unwrap();\n\n        tokio::spawn(async move {\n            // Wait for tls handshake to happen\n            let Ok(stream) = tls_acceptor.accept(cnx).await else {\n                error!(\"error during tls handshake connection from {}\", addr);\n                return;\n            };\n\n            // Hyper has its own `AsyncRead` and `AsyncWrite` traits and doesn't use tokio.\n            // `TokioIo` converts between them.\n            let stream = TokioIo::new(stream);\n\n            // Hyper also has its own `Service` trait and doesn't use tower. We can use\n            // `hyper::service::service_fn` to create a hyper `Service` that calls our app through\n            // `tower::Service::call`.\n            let hyper_service = hyper::service::service_fn(move |request: Request<Incoming>| {\n                // We have to clone `tower_service` because hyper's `Service` uses `&self` whereas\n                // tower's `Service` requires `&mut self`.\n                //\n                // We don't need to call `poll_ready` since `Router` is always ready.\n                tower_service.clone().call(request)\n            });\n\n            let ret = hyper_util::server::conn::auto::Builder::new(TokioExecutor::new())\n                .serve_connection_with_upgrades(stream, hyper_service)\n                .await;\n\n            if let Err(err) = ret {\n                warn!(\"error serving connection from {}: {}\", addr, err);\n            }\n        });\n    }\n}\n\nasync fn handler() -> &'static str {\n    \"Hello, World!\"\n}\n\nfn rustls_server_config(key: impl AsRef<Path>, cert: impl AsRef<Path>) -> Arc<ServerConfig> {\n    let key = PrivateKeyDer::from_pem_file(key).unwrap();\n\n    let certs = CertificateDer::pem_file_iter(cert)\n        .unwrap()\n        .map(|cert| cert.unwrap())\n        .collect();\n\n    let mut config = ServerConfig::builder()\n        .with_no_client_auth()\n        .with_single_cert(certs, key)\n        .expect(\"bad certificate/key\");\n\n    config.alpn_protocols = vec![b\"h2\".to_vec(), b\"http/1.1\".to_vec()];\n\n    Arc::new(config)\n}\n"
  },
  {
    "path": "examples/mongodb/Cargo.toml",
    "content": "[package]\nname = \"example-mongodb\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nmongodb = { version = \"3.3.0\", default-features = false, features = [\"bson-3\", \"compat-3-3-0\", \"rustls-tls\"] }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower-http = { version = \"0.6.1\", features = [\"add-extension\", \"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/mongodb/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-mongodb\n//! ```\n\nuse axum::{\n    extract::{Path, State},\n    http::StatusCode,\n    routing::{delete, get, post, put},\n    Json, Router,\n};\nuse mongodb::{\n    bson::doc,\n    results::{DeleteResult, InsertOneResult, UpdateResult},\n    Client, Collection,\n};\nuse serde::{Deserialize, Serialize};\nuse tower_http::trace::TraceLayer;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    // connecting to mongodb\n    let db_connection_str = std::env::var(\"DATABASE_URL\").unwrap_or_else(|_| {\n        \"mongodb://admin:password@127.0.0.1:27017/?authSource=admin\".to_string()\n    });\n    let client = Client::with_uri_str(db_connection_str).await.unwrap();\n\n    // pinging the database\n    client\n        .database(\"axum-mongo\")\n        .run_command(doc! { \"ping\": 1 })\n        .await\n        .unwrap();\n    println!(\"Pinged your database. Successfully connected to MongoDB!\");\n\n    // logging middleware\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"Listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app(client)).await;\n}\n\n// defining routes and state\nfn app(client: Client) -> Router {\n    let collection: Collection<Member> = client.database(\"axum-mongo\").collection(\"members\");\n\n    Router::new()\n        .route(\"/create\", post(create_member))\n        .route(\"/read/{id}\", get(read_member))\n        .route(\"/update\", put(update_member))\n        .route(\"/delete/{id}\", delete(delete_member))\n        .layer(TraceLayer::new_for_http())\n        .with_state(collection)\n}\n\n// handler to create a new member\nasync fn create_member(\n    State(db): State<Collection<Member>>,\n    Json(input): Json<Member>,\n) -> Result<Json<InsertOneResult>, (StatusCode, String)> {\n    let result = db.insert_one(input).await.map_err(internal_error)?;\n\n    Ok(Json(result))\n}\n\n// handler to read an existing member\nasync fn read_member(\n    State(db): State<Collection<Member>>,\n    Path(id): Path<u32>,\n) -> Result<Json<Option<Member>>, (StatusCode, String)> {\n    let result = db\n        .find_one(doc! { \"_id\": id })\n        .await\n        .map_err(internal_error)?;\n\n    Ok(Json(result))\n}\n\n// handler to update an existing member\nasync fn update_member(\n    State(db): State<Collection<Member>>,\n    Json(input): Json<Member>,\n) -> Result<Json<UpdateResult>, (StatusCode, String)> {\n    let result = db\n        .replace_one(doc! { \"_id\": input.id }, input)\n        .await\n        .map_err(internal_error)?;\n\n    Ok(Json(result))\n}\n\n// handler to delete an existing member\nasync fn delete_member(\n    State(db): State<Collection<Member>>,\n    Path(id): Path<u32>,\n) -> Result<Json<DeleteResult>, (StatusCode, String)> {\n    let result = db\n        .delete_one(doc! { \"_id\": id })\n        .await\n        .map_err(internal_error)?;\n\n    Ok(Json(result))\n}\n\nfn internal_error<E>(err: E) -> (StatusCode, String)\nwhere\n    E: std::error::Error,\n{\n    (StatusCode::INTERNAL_SERVER_ERROR, err.to_string())\n}\n\n// defining Member type\n#[derive(Debug, Deserialize, Serialize)]\nstruct Member {\n    #[serde(rename = \"_id\")]\n    id: u32,\n    name: String,\n    active: bool,\n}\n"
  },
  {
    "path": "examples/multipart-form/Cargo.toml",
    "content": "[package]\nname = \"example-multipart-form\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"multipart\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower-http = { version = \"0.6.1\", features = [\"limit\", \"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/multipart-form/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-multipart-form\n//! ```\n\nuse axum::{\n    extract::{DefaultBodyLimit, Multipart},\n    response::Html,\n    routing::get,\n    Router,\n};\nuse tower_http::limit::RequestBodyLimitLayer;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with some routes\n    let app = Router::new()\n        .route(\"/\", get(show_form).post(accept_form))\n        .layer(DefaultBodyLimit::disable())\n        .layer(RequestBodyLimitLayer::new(\n            250 * 1024 * 1024, /* 250mb */\n        ))\n        .layer(tower_http::trace::TraceLayer::new_for_http());\n\n    // run it with hyper\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn show_form() -> Html<&'static str> {\n    Html(\n        r#\"\n        <!doctype html>\n        <html>\n            <head></head>\n            <body>\n                <form action=\"/\" method=\"post\" enctype=\"multipart/form-data\">\n                    <label>\n                        Upload file:\n                        <input type=\"file\" name=\"file\" multiple>\n                    </label>\n\n                    <input type=\"submit\" value=\"Upload files\">\n                </form>\n            </body>\n        </html>\n        \"#,\n    )\n}\n\nasync fn accept_form(mut multipart: Multipart) {\n    while let Some(field) = multipart.next_field().await.unwrap() {\n        let name = field.name().unwrap().to_string();\n        let file_name = field.file_name().unwrap().to_string();\n        let content_type = field.content_type().unwrap().to_string();\n        let data = field.bytes().await.unwrap();\n\n        println!(\n            \"Length of `{name}` (`{file_name}`: `{content_type}`) is {} bytes\",\n            data.len()\n        );\n    }\n}\n"
  },
  {
    "path": "examples/oauth/Cargo.toml",
    "content": "[package]\nname = \"example-oauth\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\nanyhow = \"1\"\nasync-session = \"3.0.0\"\naxum = { path = \"../../axum\" }\naxum-extra = { path = \"../../axum-extra\", features = [\"typed-header\"] }\nhttp = \"1.0.0\"\noauth2 = \"5\"\n# Use Rustls because it makes it easier to cross-compile on CI\nreqwest = { version = \"0.12\", default-features = false, features = [\"rustls-tls\", \"json\"] }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/oauth/src/main.rs",
    "content": "//! Example OAuth (Discord) implementation.\n//!\n//! 1) Create a new application at <https://discord.com/developers/applications>\n//! 2) Visit the OAuth2 tab to get your CLIENT_ID and CLIENT_SECRET\n//! 3) Add a new redirect URI (for this example: `http://127.0.0.1:3000/auth/authorized`)\n//! 4) Run with the following (replacing values appropriately):\n//! ```not_rust\n//! CLIENT_ID=REPLACE_ME CLIENT_SECRET=REPLACE_ME cargo run -p example-oauth\n//! ```\n\nuse anyhow::{anyhow, Context, Result};\nuse async_session::{MemoryStore, Session, SessionStore};\nuse axum::{\n    extract::{FromRef, FromRequestParts, OptionalFromRequestParts, Query, State},\n    http::{header::SET_COOKIE, HeaderMap},\n    response::{IntoResponse, Redirect, Response},\n    routing::get,\n    RequestPartsExt, Router,\n};\nuse axum_extra::{headers, typed_header::TypedHeaderRejectionReason, TypedHeader};\nuse http::{header, request::Parts, StatusCode};\nuse oauth2::{\n    AuthUrl, AuthorizationCode, ClientId, ClientSecret, CsrfToken, EndpointNotSet, EndpointSet,\n    RedirectUrl, Scope, TokenResponse, TokenUrl,\n};\nuse serde::{Deserialize, Serialize};\nuse std::{convert::Infallible, env};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\nstatic COOKIE_NAME: &str = \"SESSION\";\nstatic CSRF_TOKEN: &str = \"csrf_token\";\n\ntype BasicClient = oauth2::basic::BasicClient<\n    EndpointSet,\n    EndpointNotSet,\n    EndpointNotSet,\n    EndpointNotSet,\n    EndpointSet,\n>;\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // `MemoryStore` is just used as an example. Don't use this in production.\n    let store = MemoryStore::new();\n    let oauth_client = oauth_client().unwrap();\n    let app_state = AppState {\n        store,\n        oauth_client,\n    };\n\n    let app = Router::new()\n        .route(\"/\", get(index))\n        .route(\"/auth/discord\", get(discord_auth))\n        .route(\"/auth/authorized\", get(login_authorized))\n        .route(\"/protected\", get(protected))\n        .route(\"/logout\", get(logout))\n        .with_state(app_state);\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .context(\"failed to bind TcpListener\")\n        .unwrap();\n\n    tracing::debug!(\n        \"listening on {}\",\n        listener\n            .local_addr()\n            .context(\"failed to return local address\")\n            .unwrap()\n    );\n\n    axum::serve(listener, app).await;\n}\n\n#[derive(Clone)]\nstruct AppState {\n    store: MemoryStore,\n    oauth_client: BasicClient,\n}\n\nimpl FromRef<AppState> for MemoryStore {\n    fn from_ref(state: &AppState) -> Self {\n        state.store.clone()\n    }\n}\n\nimpl FromRef<AppState> for BasicClient {\n    fn from_ref(state: &AppState) -> Self {\n        state.oauth_client.clone()\n    }\n}\n\nfn oauth_client() -> Result<BasicClient, AppError> {\n    // Environment variables (* = required):\n    // *\"CLIENT_ID\"     \"REPLACE_ME\";\n    // *\"CLIENT_SECRET\" \"REPLACE_ME\";\n    //  \"REDIRECT_URL\"  \"http://127.0.0.1:3000/auth/authorized\";\n    //  \"AUTH_URL\"      \"https://discord.com/api/oauth2/authorize?response_type=code\";\n    //  \"TOKEN_URL\"     \"https://discord.com/api/oauth2/token\";\n\n    let client_id = env::var(\"CLIENT_ID\").context(\"Missing CLIENT_ID!\")?;\n    let client_secret = env::var(\"CLIENT_SECRET\").context(\"Missing CLIENT_SECRET!\")?;\n    let redirect_url = env::var(\"REDIRECT_URL\")\n        .unwrap_or_else(|_| \"http://127.0.0.1:3000/auth/authorized\".to_string());\n\n    let auth_url = env::var(\"AUTH_URL\").unwrap_or_else(|_| {\n        \"https://discord.com/api/oauth2/authorize?response_type=code\".to_string()\n    });\n\n    let token_url = env::var(\"TOKEN_URL\")\n        .unwrap_or_else(|_| \"https://discord.com/api/oauth2/token\".to_string());\n\n    Ok(oauth2::basic::BasicClient::new(ClientId::new(client_id))\n        .set_client_secret(ClientSecret::new(client_secret))\n        .set_auth_uri(\n            AuthUrl::new(auth_url).context(\"failed to create new authorization server URL\")?,\n        )\n        .set_token_uri(TokenUrl::new(token_url).context(\"failed to create new token endpoint URL\")?)\n        .set_redirect_uri(\n            RedirectUrl::new(redirect_url).context(\"failed to create new redirection URL\")?,\n        ))\n}\n\n// The user data we'll get back from Discord.\n// https://discord.com/developers/docs/resources/user#user-object-user-structure\n#[derive(Debug, Serialize, Deserialize)]\nstruct User {\n    id: String,\n    avatar: Option<String>,\n    username: String,\n    discriminator: String,\n}\n\n// Session is optional\nasync fn index(user: Option<User>) -> impl IntoResponse {\n    match user {\n        Some(u) => format!(\n            \"Hey {}! You're logged in!\\nYou may now access `/protected`.\\nLog out with `/logout`.\",\n            u.username\n        ),\n        None => \"You're not logged in.\\nVisit `/auth/discord` to do so.\".to_string(),\n    }\n}\n\nasync fn discord_auth(\n    State(client): State<BasicClient>,\n    State(store): State<MemoryStore>,\n) -> Result<impl IntoResponse, AppError> {\n    let (auth_url, csrf_token) = client\n        .authorize_url(CsrfToken::new_random)\n        .add_scope(Scope::new(\"identify\".to_string()))\n        .url();\n\n    // Create session to store csrf_token\n    let mut session = Session::new();\n    session\n        .insert(CSRF_TOKEN, &csrf_token)\n        .context(\"failed in inserting CSRF token into session\")?;\n\n    // Store the session in MemoryStore and retrieve the session cookie\n    let cookie = store\n        .store_session(session)\n        .await\n        .context(\"failed to store CSRF token session\")?\n        .context(\"unexpected error retrieving CSRF cookie value\")?;\n\n    // Attach the session cookie to the response header\n    let cookie = format!(\"{COOKIE_NAME}={cookie}; SameSite=Lax; HttpOnly; Secure; Path=/\");\n    let mut headers = HeaderMap::new();\n    headers.insert(\n        SET_COOKIE,\n        cookie.parse().context(\"failed to parse cookie\")?,\n    );\n\n    Ok((headers, Redirect::to(auth_url.as_ref())))\n}\n\n// Valid user session required. If there is none, redirect to the auth page\nasync fn protected(user: User) -> impl IntoResponse {\n    format!(\"Welcome to the protected area :)\\nHere's your info:\\n{user:?}\")\n}\n\nasync fn logout(\n    State(store): State<MemoryStore>,\n    TypedHeader(cookies): TypedHeader<headers::Cookie>,\n) -> Result<impl IntoResponse, AppError> {\n    let cookie = cookies\n        .get(COOKIE_NAME)\n        .context(\"unexpected error getting cookie name\")?;\n\n    let session = match store\n        .load_session(cookie.to_string())\n        .await\n        .context(\"failed to load session\")?\n    {\n        Some(s) => s,\n        // No session active, just redirect\n        None => return Ok(Redirect::to(\"/\")),\n    };\n\n    store\n        .destroy_session(session)\n        .await\n        .context(\"failed to destroy session\")?;\n\n    Ok(Redirect::to(\"/\"))\n}\n\n#[derive(Debug, Deserialize)]\n#[allow(dead_code)]\nstruct AuthRequest {\n    code: String,\n    state: String,\n}\n\nasync fn csrf_token_validation_workflow(\n    auth_request: &AuthRequest,\n    cookies: &headers::Cookie,\n    store: &MemoryStore,\n) -> Result<(), AppError> {\n    // Extract the cookie from the request\n    let cookie = cookies\n        .get(COOKIE_NAME)\n        .context(\"unexpected error getting cookie name\")?\n        .to_string();\n\n    // Load the session\n    let session = match store\n        .load_session(cookie)\n        .await\n        .context(\"failed to load session\")?\n    {\n        Some(session) => session,\n        None => return Err(anyhow!(\"Session not found\").into()),\n    };\n\n    // Extract the CSRF token from the session\n    let stored_csrf_token = session\n        .get::<CsrfToken>(CSRF_TOKEN)\n        .context(\"CSRF token not found in session\")?\n        .to_owned();\n\n    // Cleanup the CSRF token session\n    store\n        .destroy_session(session)\n        .await\n        .context(\"Failed to destroy old session\")?;\n\n    // Validate CSRF token is the same as the one in the auth request\n    if *stored_csrf_token.secret() != auth_request.state {\n        return Err(anyhow!(\"CSRF token mismatch\").into());\n    }\n\n    Ok(())\n}\n\nasync fn login_authorized(\n    Query(query): Query<AuthRequest>,\n    State(store): State<MemoryStore>,\n    State(oauth_client): State<BasicClient>,\n    TypedHeader(cookies): TypedHeader<headers::Cookie>,\n) -> Result<impl IntoResponse, AppError> {\n    csrf_token_validation_workflow(&query, &cookies, &store).await?;\n\n    let client = reqwest::Client::new();\n\n    // Get an auth token\n    let token = oauth_client\n        .exchange_code(AuthorizationCode::new(query.code.clone()))\n        .request_async(&client)\n        .await\n        .context(\"failed in sending request request to authorization server\")?;\n\n    // Fetch user data from discord\n    let user_data: User = client\n        // https://discord.com/developers/docs/resources/user#get-current-user\n        .get(\"https://discordapp.com/api/users/@me\")\n        .bearer_auth(token.access_token().secret())\n        .send()\n        .await\n        .context(\"failed in sending request to target Url\")?\n        .json::<User>()\n        .await\n        .context(\"failed to deserialize response as JSON\")?;\n\n    // Create a new session filled with user data\n    let mut session = Session::new();\n    session\n        .insert(\"user\", &user_data)\n        .context(\"failed in inserting serialized value into session\")?;\n\n    // Store session and get corresponding cookie\n    let cookie = store\n        .store_session(session)\n        .await\n        .context(\"failed to store session\")?\n        .context(\"unexpected error retrieving cookie value\")?;\n\n    // Build the cookie\n    let cookie = format!(\"{COOKIE_NAME}={cookie}; SameSite=Lax; HttpOnly; Secure; Path=/\");\n\n    // Set cookie\n    let mut headers = HeaderMap::new();\n    headers.insert(\n        SET_COOKIE,\n        cookie.parse().context(\"failed to parse cookie\")?,\n    );\n\n    Ok((headers, Redirect::to(\"/\")))\n}\n\nstruct AuthRedirect;\n\nimpl IntoResponse for AuthRedirect {\n    fn into_response(self) -> Response {\n        Redirect::temporary(\"/auth/discord\").into_response()\n    }\n}\n\nimpl<S> FromRequestParts<S> for User\nwhere\n    MemoryStore: FromRef<S>,\n    S: Send + Sync,\n{\n    // If anything goes wrong or no session is found, redirect to the auth page\n    type Rejection = AuthRedirect;\n\n    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let store = MemoryStore::from_ref(state);\n\n        let cookies = parts\n            .extract::<TypedHeader<headers::Cookie>>()\n            .await\n            .map_err(|e| match *e.name() {\n                header::COOKIE => match e.reason() {\n                    TypedHeaderRejectionReason::Missing => AuthRedirect,\n                    _ => panic!(\"unexpected error getting Cookie header(s): {e}\"),\n                },\n                _ => panic!(\"unexpected error getting cookies: {e}\"),\n            })?;\n        let session_cookie = cookies.get(COOKIE_NAME).ok_or(AuthRedirect)?;\n\n        let session = store\n            .load_session(session_cookie.to_string())\n            .await\n            .unwrap()\n            .ok_or(AuthRedirect)?;\n\n        let user = session.get::<User>(\"user\").ok_or(AuthRedirect)?;\n\n        Ok(user)\n    }\n}\n\nimpl<S> OptionalFromRequestParts<S> for User\nwhere\n    MemoryStore: FromRef<S>,\n    S: Send + Sync,\n{\n    type Rejection = Infallible;\n\n    async fn from_request_parts(\n        parts: &mut Parts,\n        state: &S,\n    ) -> Result<Option<Self>, Self::Rejection> {\n        match <User as FromRequestParts<S>>::from_request_parts(parts, state).await {\n            Ok(res) => Ok(Some(res)),\n            Err(AuthRedirect) => Ok(None),\n        }\n    }\n}\n\n// Use anyhow, define error and enable '?'\n// For a simplified example of using anyhow in axum check /examples/anyhow-error-response\n#[derive(Debug)]\nstruct AppError(anyhow::Error);\n\n// Tell axum how to convert `AppError` into a response.\nimpl IntoResponse for AppError {\n    fn into_response(self) -> Response {\n        tracing::error!(\"Application error: {:#}\", self.0);\n\n        (StatusCode::INTERNAL_SERVER_ERROR, \"Something went wrong\").into_response()\n    }\n}\n\n// This enables using `?` on functions that return `Result<_, anyhow::Error>` to turn them into\n// `Result<_, AppError>`. That way you don't need to do that manually.\nimpl<E> From<E> for AppError\nwhere\n    E: Into<anyhow::Error>,\n{\n    fn from(err: E) -> Self {\n        Self(err.into())\n    }\n}\n"
  },
  {
    "path": "examples/parse-body-based-on-content-type/Cargo.toml",
    "content": "[package]\nname = \"example-parse-body-based-on-content-type\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/parse-body-based-on-content-type/src/main.rs",
    "content": "//! Provides a RESTful web server managing some Todos.\n//!\n//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-parse-body-based-on-content-type\n//! ```\n\nuse axum::{\n    extract::{FromRequest, Request},\n    http::{header::CONTENT_TYPE, StatusCode},\n    response::{IntoResponse, Response},\n    routing::post,\n    Form, Json, RequestExt, Router,\n};\nuse serde::{Deserialize, Serialize};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let app = Router::new().route(\"/\", post(handler));\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n#[derive(Debug, Serialize, Deserialize)]\nstruct Payload {\n    foo: String,\n}\n\nasync fn handler(JsonOrForm(payload): JsonOrForm<Payload>) {\n    dbg!(payload);\n}\n\nstruct JsonOrForm<T>(T);\n\nimpl<S, T> FromRequest<S> for JsonOrForm<T>\nwhere\n    S: Send + Sync,\n    Json<T>: FromRequest<()>,\n    Form<T>: FromRequest<()>,\n    T: 'static,\n{\n    type Rejection = Response;\n\n    async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {\n        let content_type_header = req.headers().get(CONTENT_TYPE);\n        let content_type = content_type_header.and_then(|value| value.to_str().ok());\n\n        if let Some(content_type) = content_type {\n            if content_type.starts_with(\"application/json\") {\n                let Json(payload) = req.extract().await.map_err(IntoResponse::into_response)?;\n                return Ok(Self(payload));\n            }\n\n            if content_type.starts_with(\"application/x-www-form-urlencoded\") {\n                let Form(payload) = req.extract().await.map_err(IntoResponse::into_response)?;\n                return Ok(Self(payload));\n            }\n        }\n\n        Err(StatusCode::UNSUPPORTED_MEDIA_TYPE.into_response())\n    }\n}\n"
  },
  {
    "path": "examples/print-request-response/Cargo.toml",
    "content": "[package]\nname = \"example-print-request-response\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhttp-body-util = \"0.1.0\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/print-request-response/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-print-request-response\n//! ```\n\nuse axum::{\n    body::{Body, Bytes},\n    extract::Request,\n    http::StatusCode,\n    middleware::{self, Next},\n    response::{IntoResponse, Response},\n    routing::post,\n    Router,\n};\nuse http_body_util::BodyExt;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let app = Router::new()\n        .route(\"/\", post(|| async move { \"Hello from `POST /`\" }))\n        .layer(middleware::from_fn(print_request_response));\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn print_request_response(\n    req: Request,\n    next: Next,\n) -> Result<impl IntoResponse, (StatusCode, String)> {\n    let (parts, body) = req.into_parts();\n    let bytes = buffer_and_print(\"request\", body).await?;\n    let req = Request::from_parts(parts, Body::from(bytes));\n\n    let res = next.run(req).await;\n\n    let (parts, body) = res.into_parts();\n    let bytes = buffer_and_print(\"response\", body).await?;\n    let res = Response::from_parts(parts, Body::from(bytes));\n\n    Ok(res)\n}\n\nasync fn buffer_and_print<B>(direction: &str, body: B) -> Result<Bytes, (StatusCode, String)>\nwhere\n    B: axum::body::HttpBody<Data = Bytes>,\n    B::Error: std::fmt::Display,\n{\n    let bytes = match body.collect().await {\n        Ok(collected) => collected.to_bytes(),\n        Err(err) => {\n            return Err((\n                StatusCode::BAD_REQUEST,\n                format!(\"failed to read {direction} body: {err}\"),\n            ));\n        }\n    };\n\n    if let Ok(body) = std::str::from_utf8(&bytes) {\n        tracing::debug!(\"{direction} body = {body:?}\");\n    }\n\n    Ok(bytes)\n}\n"
  },
  {
    "path": "examples/prometheus-metrics/Cargo.toml",
    "content": "[package]\nname = \"example-prometheus-metrics\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nmetrics = { version = \"0.24\", default-features = false }\nmetrics-exporter-prometheus = { version = \"0.18\", default-features = false }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/prometheus-metrics/src/main.rs",
    "content": "//! Someday tower-http will hopefully have a metrics middleware, until then you can track\n//! metrics like this.\n//!\n//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-prometheus-metrics\n//! ```\n\nuse axum::{\n    extract::{MatchedPath, Request},\n    middleware::{self, Next},\n    response::IntoResponse,\n    routing::get,\n    Router,\n};\nuse metrics_exporter_prometheus::{Matcher, PrometheusBuilder, PrometheusHandle};\nuse std::{\n    future::ready,\n    time::{Duration, Instant},\n};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\nfn metrics_app() -> Router {\n    let recorder_handle = setup_metrics_recorder();\n    Router::new().route(\"/metrics\", get(move || ready(recorder_handle.render())))\n}\n\nfn main_app() -> Router {\n    Router::new()\n        .route(\"/fast\", get(|| async {}))\n        .route(\n            \"/slow\",\n            get(|| async {\n                tokio::time::sleep(Duration::from_secs(1)).await;\n            }),\n        )\n        .route_layer(middleware::from_fn(track_metrics))\n}\n\nasync fn start_main_server() {\n    let app = main_app();\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn start_metrics_server() {\n    let app = metrics_app();\n\n    // NOTE: expose metrics endpoint on a different port\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3001\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // The `/metrics` endpoint should not be publicly available. If behind a reverse proxy, this\n    // can be achieved by rejecting requests to `/metrics`. In this example, a second server is\n    // started on another port to expose `/metrics`.\n    let (_main_server, _metrics_server) = tokio::join!(start_main_server(), start_metrics_server());\n}\n\nfn setup_metrics_recorder() -> PrometheusHandle {\n    const EXPONENTIAL_SECONDS: &[f64] = &[\n        0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0,\n    ];\n\n    let recorder_handle = PrometheusBuilder::new()\n        .set_buckets_for_metric(\n            Matcher::Full(\"http_requests_duration_seconds\".to_string()),\n            EXPONENTIAL_SECONDS,\n        )\n        .unwrap()\n        .install_recorder()\n        .unwrap();\n\n    let upkeep_handle = recorder_handle.clone();\n    tokio::spawn(async move {\n        loop {\n            tokio::time::sleep(Duration::from_secs(5)).await;\n            upkeep_handle.run_upkeep();\n        }\n    });\n\n    recorder_handle\n}\n\nasync fn track_metrics(req: Request, next: Next) -> impl IntoResponse {\n    let start = Instant::now();\n    let path = if let Some(matched_path) = req.extensions().get::<MatchedPath>() {\n        matched_path.as_str().to_owned()\n    } else {\n        req.uri().path().to_owned()\n    };\n    let method = req.method().clone();\n\n    let response = next.run(req).await;\n\n    let latency = start.elapsed().as_secs_f64();\n    let status = response.status().as_u16().to_string();\n\n    let labels = [\n        (\"method\", method.to_string()),\n        (\"path\", path),\n        (\"status\", status),\n    ];\n\n    metrics::counter!(\"http_requests_total\", &labels).increment(1);\n    metrics::histogram!(\"http_requests_duration_seconds\", &labels).record(latency);\n\n    response\n}\n"
  },
  {
    "path": "examples/readme/Cargo.toml",
    "content": "[package]\nname = \"example-readme\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/readme/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-readme\n//! ```\n\nuse axum::{\n    http::StatusCode,\n    response::IntoResponse,\n    routing::{get, post},\n    Json, Router,\n};\nuse serde::{Deserialize, Serialize};\n\n#[tokio::main]\nasync fn main() {\n    // initialize tracing\n    tracing_subscriber::fmt::init();\n\n    // build our application with a route\n    let app = Router::new()\n        // `GET /` goes to `root`\n        .route(\"/\", get(root))\n        // `POST /users` goes to `create_user`\n        .route(\"/users\", post(create_user));\n\n    // run our app with hyper\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n// basic handler that responds with a static string\nasync fn root() -> &'static str {\n    \"Hello, World!\"\n}\n\nasync fn create_user(\n    // this argument tells axum to parse the request body\n    // as JSON into a `CreateUser` type\n    Json(payload): Json<CreateUser>,\n) -> impl IntoResponse {\n    // insert your application logic here\n    let user = User {\n        id: 1337,\n        username: payload.username,\n    };\n\n    // this will be converted into a JSON response\n    // with a status code of `201 Created`\n    (StatusCode::CREATED, Json(user))\n}\n\n// the input to our `create_user` handler\n#[derive(Deserialize)]\nstruct CreateUser {\n    username: String,\n}\n\n// the output to our `create_user` handler\n#[derive(Serialize)]\nstruct User {\n    id: u64,\n    username: String,\n}\n"
  },
  {
    "path": "examples/request-id/Cargo.toml",
    "content": "[package]\nname = \"example-request-id\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower = \"0.5.2\"\ntower-http = { version = \"0.6\", features = [\"request-id\", \"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/request-id/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-request-id\n//! ```\n\nuse axum::{\n    http::{HeaderName, Request},\n    response::Html,\n    routing::get,\n    Router,\n};\nuse tower::ServiceBuilder;\nuse tower_http::{\n    request_id::{MakeRequestUuid, PropagateRequestIdLayer, SetRequestIdLayer},\n    trace::TraceLayer,\n};\nuse tracing::{error, info, info_span};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\nconst REQUEST_ID_HEADER: &str = \"x-request-id\";\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                // axum logs rejections from built-in extractors with the `axum::rejection`\n                // target, at `TRACE` level. `axum::rejection=trace` enables showing those events\n                format!(\n                    \"{}=debug,tower_http=debug,axum::rejection=trace\",\n                    env!(\"CARGO_CRATE_NAME\")\n                )\n                .into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let x_request_id = HeaderName::from_static(REQUEST_ID_HEADER);\n\n    let middleware = ServiceBuilder::new()\n        .layer(SetRequestIdLayer::new(\n            x_request_id.clone(),\n            MakeRequestUuid,\n        ))\n        .layer(\n            TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {\n                // Log the request id as generated.\n                let request_id = request.headers().get(REQUEST_ID_HEADER);\n\n                match request_id {\n                    Some(request_id) => info_span!(\n                        \"http_request\",\n                        request_id = ?request_id,\n                    ),\n                    None => {\n                        error!(\"could not extract request_id\");\n                        info_span!(\"http_request\")\n                    }\n                }\n            }),\n        )\n        // send headers from request to response headers\n        .layer(PropagateRequestIdLayer::new(x_request_id));\n\n    // build our application with a route\n    let app = Router::new().route(\"/\", get(handler)).layer(middleware);\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler() -> Html<&'static str> {\n    info!(\"Hello world!\");\n    Html(\"<h1>Hello, World!</h1>\")\n}\n"
  },
  {
    "path": "examples/reqwest-response/Cargo.toml",
    "content": "[package]\nname = \"example-reqwest-response\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nreqwest = { version = \"0.12\", default-features = false, features = [\"stream\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntokio-stream = \"0.1\"\ntower-http = { version = \"0.6.1\", features = [\"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/reqwest-response/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-reqwest-response\n//! ```\n\nuse axum::{\n    body::{Body, Bytes},\n    extract::State,\n    http::StatusCode,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse reqwest::Client;\nuse std::{convert::Infallible, time::Duration};\nuse tokio_stream::StreamExt;\nuse tower_http::trace::TraceLayer;\nuse tracing::Span;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let client = Client::new();\n\n    let app = Router::new()\n        .route(\"/\", get(stream_reqwest_response))\n        .route(\"/stream\", get(stream_some_data))\n        // Add some logging so we can see the streams going through\n        .layer(TraceLayer::new_for_http().on_body_chunk(\n            |chunk: &Bytes, _latency: Duration, _span: &Span| {\n                tracing::debug!(\"streaming {} bytes\", chunk.len());\n            },\n        ))\n        .with_state(client);\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn stream_reqwest_response(State(client): State<Client>) -> Response {\n    let reqwest_response = match client.get(\"http://127.0.0.1:3000/stream\").send().await {\n        Ok(res) => res,\n        Err(err) => {\n            tracing::error!(%err, \"request failed\");\n            return (StatusCode::BAD_REQUEST, Body::empty()).into_response();\n        }\n    };\n\n    let mut response_builder = Response::builder().status(reqwest_response.status());\n    *response_builder.headers_mut().unwrap() = reqwest_response.headers().clone();\n    response_builder\n        .body(Body::from_stream(reqwest_response.bytes_stream()))\n        // This unwrap is fine because the body is empty here\n        .unwrap()\n}\n\nasync fn stream_some_data() -> Body {\n    let stream = tokio_stream::iter(0..5)\n        .throttle(Duration::from_secs(1))\n        .map(|n| n.to_string())\n        .map(Ok::<_, Infallible>);\n    Body::from_stream(stream)\n}\n"
  },
  {
    "path": "examples/reverse-proxy/Cargo.toml",
    "content": "[package]\nname = \"example-reverse-proxy\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhyper = { version = \"1.0.0\", features = [\"full\"] }\nhyper-util = { version = \"0.1.1\", features = [\"client-legacy\"] }\ntokio = { version = \"1\", features = [\"full\"] }\n"
  },
  {
    "path": "examples/reverse-proxy/src/main.rs",
    "content": "//! Reverse proxy listening in \"localhost:4000\" will proxy all requests to \"localhost:3000\"\n//! endpoint.\n//!\n//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-reverse-proxy\n//! ```\n\nuse axum::{\n    body::Body,\n    extract::{Request, State},\n    http::uri::Uri,\n    response::{IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse hyper::StatusCode;\nuse hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor};\n\ntype Client = hyper_util::client::legacy::Client<HttpConnector, Body>;\n\n#[tokio::main]\nasync fn main() {\n    tokio::spawn(server());\n\n    let client: Client =\n        hyper_util::client::legacy::Client::<(), ()>::builder(TokioExecutor::new())\n            .build(HttpConnector::new());\n\n    let app = Router::new().route(\"/\", get(handler)).with_state(client);\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:4000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler(State(client): State<Client>, mut req: Request) -> Result<Response, StatusCode> {\n    let path = req.uri().path();\n    let path_query = req\n        .uri()\n        .path_and_query()\n        .map(|v| v.as_str())\n        .unwrap_or(path);\n\n    let uri = format!(\"http://127.0.0.1:3000{path_query}\");\n\n    *req.uri_mut() = Uri::try_from(uri).unwrap();\n\n    Ok(client\n        .request(req)\n        .await\n        .map_err(|_| StatusCode::BAD_REQUEST)?\n        .into_response())\n}\n\nasync fn server() {\n    let app = Router::new().route(\"/\", get(|| async { \"Hello, world!\" }));\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n"
  },
  {
    "path": "examples/routes-and-handlers-close-together/Cargo.toml",
    "content": "[package]\nname = \"example-routes-and-handlers-close-together\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\n"
  },
  {
    "path": "examples/routes-and-handlers-close-together/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-routes-and-handlers-close-together\n//! ```\n\nuse axum::{\n    routing::{get, post, MethodRouter},\n    Router,\n};\n\n#[tokio::main]\nasync fn main() {\n    let app = Router::new()\n        .merge(root())\n        .merge(get_foo())\n        .merge(post_foo());\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nfn root() -> Router {\n    async fn handler() -> &'static str {\n        \"Hello, World!\"\n    }\n\n    route(\"/\", get(handler))\n}\n\nfn get_foo() -> Router {\n    async fn handler() -> &'static str {\n        \"Hi from `GET /foo`\"\n    }\n\n    route(\"/foo\", get(handler))\n}\n\nfn post_foo() -> Router {\n    async fn handler() -> &'static str {\n        \"Hi from `POST /foo`\"\n    }\n\n    route(\"/foo\", post(handler))\n}\n\nfn route(path: &str, method_router: MethodRouter<()>) -> Router {\n    Router::new().route(path, method_router)\n}\n"
  },
  {
    "path": "examples/serve-with-hyper/Cargo.toml",
    "content": "[package]\nname = \"example-serve-with-hyper\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhyper = { version = \"1.0\", features = [] }\nhyper-util = { version = \"0.1\", features = [\"tokio\", \"server-auto\", \"http1\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower = { version = \"0.5.2\", features = [\"util\"] }\n"
  },
  {
    "path": "examples/serve-with-hyper/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-serve-with-hyper\n//! ```\n//!\n//! This example shows how to run axum using hyper's low level API.\n//!\n//! The [hyper-util] crate exists to provide high level utilities but it's still in early stages of\n//! development.\n//!\n//! [hyper-util]: https://crates.io/crates/hyper-util\n\nuse std::convert::Infallible;\nuse std::net::SocketAddr;\n\nuse axum::extract::ConnectInfo;\nuse axum::{extract::Request, routing::get, Router};\nuse hyper::body::Incoming;\nuse hyper_util::rt::{TokioExecutor, TokioIo};\nuse hyper_util::server;\nuse tokio::net::TcpListener;\nuse tower::{Service, ServiceExt};\n\n#[tokio::main]\nasync fn main() {\n    tokio::join!(serve_plain(), serve_with_connect_info());\n}\n\nasync fn serve_plain() {\n    // Create a regular axum app.\n    let app = Router::new().route(\"/\", get(|| async { \"Hello!\" }));\n\n    // Create a `TcpListener` using tokio.\n    let listener = TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n\n    // Continuously accept new connections.\n    loop {\n        // In this example we discard the remote address. See `fn serve_with_connect_info` for how\n        // to expose that.\n        let (socket, _remote_addr) = listener.accept().await.unwrap();\n\n        // We don't need to call `poll_ready` because `Router` is always ready.\n        let tower_service = app.clone();\n\n        // Spawn a task to handle the connection. That way we can handle multiple connections\n        // concurrently.\n        tokio::spawn(async move {\n            // Hyper has its own `AsyncRead` and `AsyncWrite` traits and doesn't use tokio.\n            // `TokioIo` converts between them.\n            let socket = TokioIo::new(socket);\n\n            // Hyper also has its own `Service` trait and doesn't use tower. We can use\n            // `hyper::service::service_fn` to create a hyper `Service` that calls our app through\n            // `tower::Service::call`.\n            let hyper_service = hyper::service::service_fn(move |request: Request<Incoming>| {\n                // We have to clone `tower_service` because hyper's `Service` uses `&self` whereas\n                // tower's `Service` requires `&mut self`.\n                //\n                // We don't need to call `poll_ready` since `Router` is always ready.\n                tower_service.clone().call(request)\n            });\n\n            // `server::conn::auto::Builder` supports both http1 and http2.\n            //\n            // `TokioExecutor` tells hyper to use `tokio::spawn` to spawn tasks.\n            if let Err(err) = server::conn::auto::Builder::new(TokioExecutor::new())\n                // `serve_connection_with_upgrades` is required for websockets. If you don't need\n                // that you can use `serve_connection` instead.\n                .serve_connection_with_upgrades(socket, hyper_service)\n                .await\n            {\n                eprintln!(\"failed to serve connection: {err:#}\");\n            }\n        });\n    }\n}\n\n// Similar setup to `serve_plain` but captures the remote address and exposes it through the\n// `ConnectInfo` extractor\nasync fn serve_with_connect_info() {\n    let app = Router::new().route(\n        \"/\",\n        get(\n            |ConnectInfo(remote_addr): ConnectInfo<SocketAddr>| async move {\n                format!(\"Hello {remote_addr}\")\n            },\n        ),\n    );\n\n    let mut make_service = app.into_make_service_with_connect_info::<SocketAddr>();\n\n    let listener = TcpListener::bind(\"0.0.0.0:3001\").await.unwrap();\n\n    loop {\n        let (socket, remote_addr) = listener.accept().await.unwrap();\n\n        // We don't need to call `poll_ready` because `IntoMakeServiceWithConnectInfo` is always\n        // ready.\n        let tower_service = unwrap_infallible(make_service.call(remote_addr).await);\n\n        tokio::spawn(async move {\n            let socket = TokioIo::new(socket);\n\n            let hyper_service = hyper::service::service_fn(move |request: Request<Incoming>| {\n                tower_service.clone().oneshot(request)\n            });\n\n            if let Err(err) = server::conn::auto::Builder::new(TokioExecutor::new())\n                .serve_connection_with_upgrades(socket, hyper_service)\n                .await\n            {\n                eprintln!(\"failed to serve connection: {err:#}\");\n            }\n        });\n    }\n}\n\nfn unwrap_infallible<T>(result: Result<T, Infallible>) -> T {\n    match result {\n        Ok(value) => value,\n        Err(err) => match err {},\n    }\n}\n"
  },
  {
    "path": "examples/simple-router-wasm/Cargo.toml",
    "content": "[package]\nname = \"example-simple-router-wasm\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n[package.metadata.cargo-machete]\nignored = [\"axum-extra\"]\n\n[dependencies]\n# `default-features = false` to not depend on tokio features which don't support wasm\n# you can still pull in tokio manually and only add features that tokio supports for wasm\naxum = { path = \"../../axum\", default-features = false }\n# we don't strictly use axum-extra in this example but wanna make sure that\n# works in wasm as well\naxum-extra = { path = \"../../axum-extra\", default-features = false }\nfutures-executor = \"0.3.21\"\nhttp = \"1.0.0\"\ntower-service = \"0.3.1\"\n"
  },
  {
    "path": "examples/simple-router-wasm/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-simple-router-wasm\n//! ```\n//!\n//! This example shows what using axum in a wasm context might look like. This example should\n//! always compile with `--target wasm32-unknown-unknown`.\n//!\n//! [`mio`](https://docs.rs/mio/latest/mio/index.html), tokio's IO layer, does not support the\n//! `wasm32-unknown-unknown` target which is why this crate requires `default-features = false`\n//! for axum.\n//!\n//! Most serverless runtimes expect an exported function that takes in a single request and returns\n//! a single response, much like axum's `Handler` trait. In this example, the handler function is\n//! `app` with `main` acting as the serverless runtime which originally receives the request and\n//! calls the app function.\n//!\n//! We can use axum's routing, extractors, tower services, and everything else to implement\n//! our serverless function, even though we are running axum in a wasm context.\n\nuse axum::{\n    response::{Html, Response},\n    routing::get,\n    Router,\n};\nuse futures_executor::block_on;\nuse http::Request;\nuse tower_service::Service;\n\nfn main() {\n    let request: Request<String> = Request::get(\"https://serverless.example/api/\")\n        .body(\"Some Body Data\".into())\n        .unwrap();\n\n    let response: Response = block_on(app(request));\n    assert_eq!(200, response.status());\n}\n\n#[allow(clippy::let_and_return)]\nasync fn app(request: Request<String>) -> Response {\n    let mut router = Router::new().route(\"/api/\", get(index));\n    let response = router.call(request).await.unwrap();\n    response\n}\n\nasync fn index() -> Html<&'static str> {\n    Html(\"<h1>Hello, World!</h1>\")\n}\n"
  },
  {
    "path": "examples/sqlx-postgres/Cargo.toml",
    "content": "[package]\nname = \"example-sqlx-postgres\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\nsqlx = { version = \"0.8\", features = [\"runtime-tokio-rustls\", \"any\", \"postgres\"] }\n"
  },
  {
    "path": "examples/sqlx-postgres/src/main.rs",
    "content": "//! Example of application using <https://github.com/launchbadge/sqlx>\n//!\n//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-sqlx-postgres\n//! ```\n//!\n//! Test with curl:\n//!\n//! ```not_rust\n//! curl 127.0.0.1:3000\n//! curl -X POST 127.0.0.1:3000\n//! ```\n\nuse axum::{\n    extract::{FromRef, FromRequestParts, State},\n    http::{request::Parts, StatusCode},\n    routing::get,\n    Router,\n};\nuse sqlx::postgres::{PgPool, PgPoolOptions};\nuse tokio::net::TcpListener;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\nuse std::time::Duration;\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let db_connection_str = std::env::var(\"DATABASE_URL\")\n        .unwrap_or_else(|_| \"postgres://postgres:password@localhost\".to_string());\n\n    // set up connection pool\n    let pool = PgPoolOptions::new()\n        .max_connections(5)\n        .acquire_timeout(Duration::from_secs(3))\n        .connect(&db_connection_str)\n        .await\n        .expect(\"can't connect to database\");\n\n    // build our application with some routes\n    let app = Router::new()\n        .route(\n            \"/\",\n            get(using_connection_pool_extractor).post(using_connection_extractor),\n        )\n        .with_state(pool);\n\n    // run it with hyper\n    let listener = TcpListener::bind(\"127.0.0.1:3000\").await.unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n// we can extract the connection pool with `State`\nasync fn using_connection_pool_extractor(\n    State(pool): State<PgPool>,\n) -> Result<String, (StatusCode, String)> {\n    sqlx::query_scalar(\"select 'hello world from pg'\")\n        .fetch_one(&pool)\n        .await\n        .map_err(internal_error)\n}\n\n// we can also write a custom extractor that grabs a connection from the pool\n// which setup is appropriate depends on your application\nstruct DatabaseConnection(sqlx::pool::PoolConnection<sqlx::Postgres>);\n\nimpl<S> FromRequestParts<S> for DatabaseConnection\nwhere\n    PgPool: FromRef<S>,\n    S: Send + Sync,\n{\n    type Rejection = (StatusCode, String);\n\n    async fn from_request_parts(_parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let pool = PgPool::from_ref(state);\n\n        let conn = pool.acquire().await.map_err(internal_error)?;\n\n        Ok(Self(conn))\n    }\n}\n\nasync fn using_connection_extractor(\n    DatabaseConnection(mut conn): DatabaseConnection,\n) -> Result<String, (StatusCode, String)> {\n    sqlx::query_scalar(\"select 'hello world from pg'\")\n        .fetch_one(&mut *conn)\n        .await\n        .map_err(internal_error)\n}\n\n/// Utility function for mapping any error into a `500 Internal Server Error`\n/// response.\nfn internal_error<E>(err: E) -> (StatusCode, String)\nwhere\n    E: std::error::Error,\n{\n    (StatusCode::INTERNAL_SERVER_ERROR, err.to_string())\n}\n"
  },
  {
    "path": "examples/sse/Cargo.toml",
    "content": "[package]\nname = \"example-sse\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\naxum-extra = { path = \"../../axum-extra\", features = [\"typed-header\"] }\nfutures-util = { version = \"0.3\", default-features = false, features = [\"sink\", \"std\"] }\nheaders = \"0.4\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntokio-stream = \"0.1\"\ntower-http = { version = \"0.6.1\", features = [\"fs\", \"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\n[dev-dependencies]\neventsource-stream = \"0.2\"\nreqwest = { version = \"0.12\", default-features = false, features = [\"stream\"] }\n"
  },
  {
    "path": "examples/sse/assets/index.html",
    "content": "<script src='script.js'></script>\n"
  },
  {
    "path": "examples/sse/assets/script.js",
    "content": "var eventSource = new EventSource('sse');\n\neventSource.onmessage = function(event) {\n    console.log('Message from server ', event.data);\n}\n"
  },
  {
    "path": "examples/sse/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-sse\n//! ```\n//! Test with\n//! ```not_rust\n//! cargo test -p example-sse\n//! ```\n\nuse axum::{\n    response::sse::{Event, Sse},\n    routing::get,\n    Router,\n};\nuse axum_extra::TypedHeader;\nuse futures_util::stream::{self, Stream};\nuse std::{convert::Infallible, path::PathBuf, time::Duration};\nuse tokio_stream::StreamExt as _;\nuse tower_http::{services::ServeDir, trace::TraceLayer};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application\n    let app = app();\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nfn app() -> Router {\n    let assets_dir = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\")).join(\"assets\");\n    let static_files_service = ServeDir::new(assets_dir).append_index_html_on_directories(true);\n    // build our application with a route\n    Router::new()\n        .fallback_service(static_files_service)\n        .route(\"/sse\", get(sse_handler))\n        .layer(TraceLayer::new_for_http())\n}\n\nasync fn sse_handler(\n    TypedHeader(user_agent): TypedHeader<headers::UserAgent>,\n) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {\n    println!(\"`{}` connected\", user_agent.as_str());\n\n    // A `Stream` that repeats an event every second\n    //\n    // You can also create streams from tokio channels using the wrappers in\n    // https://docs.rs/tokio-stream\n    let stream = stream::repeat_with(|| Event::default().data(\"hi!\"))\n        .map(Ok)\n        .throttle(Duration::from_secs(1));\n\n    Sse::new(stream).keep_alive(\n        axum::response::sse::KeepAlive::new()\n            .interval(Duration::from_secs(1))\n            .text(\"keep-alive-text\"),\n    )\n}\n\n#[cfg(test)]\nmod tests {\n    use eventsource_stream::Eventsource;\n    use tokio::net::TcpListener;\n\n    use super::*;\n\n    #[tokio::test]\n    async fn integration_test() {\n        // A helper function that spawns our application in the background\n        async fn spawn_app(host: impl Into<String>) -> String {\n            let host = host.into();\n            // Bind to localhost at the port 0, which will let the OS assign an available port to us\n            let listener = TcpListener::bind(format!(\"{host}:0\")).await.unwrap();\n            // Retrieve the port assigned to us by the OS\n            let port = listener.local_addr().unwrap().port();\n            tokio::spawn(async {\n                axum::serve(listener, app()).await;\n            });\n            // Returns address (e.g. http://127.0.0.1{random_port})\n            format!(\"http://{host}:{port}\")\n        }\n        let listening_url = spawn_app(\"127.0.0.1\").await;\n\n        let mut event_stream = reqwest::Client::new()\n            .get(format!(\"{listening_url}/sse\"))\n            .header(\"User-Agent\", \"integration_test\")\n            .send()\n            .await\n            .unwrap()\n            .bytes_stream()\n            .eventsource()\n            .take(1);\n\n        let mut event_data: Vec<String> = vec![];\n        while let Some(event) = event_stream.next().await {\n            match event {\n                Ok(event) => {\n                    // break the loop at the end of SSE stream\n                    if event.data == \"[DONE]\" {\n                        break;\n                    }\n\n                    event_data.push(event.data);\n                }\n                Err(_) => {\n                    panic!(\"Error in event stream\");\n                }\n            }\n        }\n\n        assert!(event_data[0] == \"hi!\");\n    }\n}\n"
  },
  {
    "path": "examples/static-file-server/Cargo.toml",
    "content": "[package]\nname = \"example-static-file-server\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower = { version = \"0.5.2\", features = [\"util\"] }\ntower-http = { version = \"0.6.1\", features = [\"fs\", \"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/static-file-server/assets/index.html",
    "content": "Hi from index.html\n"
  },
  {
    "path": "examples/static-file-server/assets/script.js",
    "content": "console.log(\"Hello, World!\");\n"
  },
  {
    "path": "examples/static-file-server/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-static-file-server\n//! ```\n\nuse axum::{\n    extract::Request, handler::HandlerWithoutStateExt, http::StatusCode, routing::get, Router,\n};\nuse std::net::SocketAddr;\nuse tower::ServiceExt;\nuse tower_http::{\n    services::{ServeDir, ServeFile},\n    trace::TraceLayer,\n};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    tokio::join!(\n        serve(using_serve_dir(), 3001),\n        serve(using_serve_dir_with_assets_fallback(), 3002),\n        serve(using_serve_dir_only_from_root_via_fallback(), 3003),\n        serve(using_serve_dir_with_handler_as_service(), 3004),\n        serve(two_serve_dirs(), 3005),\n        serve(calling_serve_dir_from_a_handler(), 3006),\n        serve(using_serve_file_from_a_route(), 3307),\n    );\n}\n\nfn using_serve_dir() -> Router {\n    // serve the file in the \"assets\" directory under `/assets`\n    Router::new().nest_service(\"/assets\", ServeDir::new(\"assets\"))\n}\n\nfn using_serve_dir_with_assets_fallback() -> Router {\n    // `ServeDir` allows setting a fallback if an asset is not found\n    // so with this `GET /assets/doesnt-exist.jpg` will return `index.html`\n    // rather than a 404\n    let serve_dir = ServeDir::new(\"assets\").not_found_service(ServeFile::new(\"assets/index.html\"));\n\n    Router::new()\n        .route(\"/foo\", get(|| async { \"Hi from /foo\" }))\n        .nest_service(\"/assets\", serve_dir.clone())\n        .fallback_service(serve_dir)\n}\n\nfn using_serve_dir_only_from_root_via_fallback() -> Router {\n    // you can also serve the assets directly from the root (not nested under `/assets`)\n    // by only setting a `ServeDir` as the fallback\n    let serve_dir = ServeDir::new(\"assets\").not_found_service(ServeFile::new(\"assets/index.html\"));\n\n    Router::new()\n        .route(\"/foo\", get(|| async { \"Hi from /foo\" }))\n        .fallback_service(serve_dir)\n}\n\nfn using_serve_dir_with_handler_as_service() -> Router {\n    async fn handle_404() -> (StatusCode, &'static str) {\n        (StatusCode::NOT_FOUND, \"Not found\")\n    }\n\n    // you can convert handler function to service\n    let service = handle_404.into_service();\n\n    let serve_dir = ServeDir::new(\"assets\").not_found_service(service);\n\n    Router::new()\n        .route(\"/foo\", get(|| async { \"Hi from /foo\" }))\n        .fallback_service(serve_dir)\n}\n\nfn two_serve_dirs() -> Router {\n    // you can also have two `ServeDir`s nested at different paths\n    let serve_dir_from_assets = ServeDir::new(\"assets\");\n    let serve_dir_from_dist = ServeDir::new(\"dist\");\n\n    Router::new()\n        .nest_service(\"/assets\", serve_dir_from_assets)\n        .nest_service(\"/dist\", serve_dir_from_dist)\n}\n\n#[allow(clippy::let_and_return)]\nfn calling_serve_dir_from_a_handler() -> Router {\n    // via `tower::Service::call`, or more conveniently `tower::ServiceExt::oneshot` you can\n    // call `ServeDir` yourself from a handler\n    Router::new().nest_service(\n        \"/foo\",\n        get(|request: Request| async {\n            let service = ServeDir::new(\"assets\");\n            let result = service.oneshot(request).await;\n            result\n        }),\n    )\n}\n\nfn using_serve_file_from_a_route() -> Router {\n    Router::new().route_service(\"/foo\", ServeFile::new(\"assets/index.html\"))\n}\n\nasync fn serve(app: Router, port: u16) {\n    let addr = SocketAddr::from(([127, 0, 0, 1], port));\n    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app.layer(TraceLayer::new_for_http())).await;\n}\n"
  },
  {
    "path": "examples/stream-to-file/Cargo.toml",
    "content": "[package]\nname = \"example-stream-to-file\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"multipart\"] }\nfutures-util = { version = \"0.3\", default-features = false, features = [\"sink\", \"std\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntokio-util = { version = \"0.7\", features = [\"io\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/stream-to-file/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-stream-to-file\n//! ```\n\nuse axum::{\n    body::Bytes,\n    extract::{Multipart, Path, Request},\n    http::StatusCode,\n    response::{Html, Redirect},\n    routing::{get, post},\n    BoxError, Router,\n};\nuse futures_util::{Stream, TryStreamExt};\nuse std::{io, pin::pin};\nuse tokio::{fs::File, io::BufWriter};\nuse tokio_util::io::StreamReader;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\nconst UPLOADS_DIRECTORY: &str = \"uploads\";\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // save files to a separate directory to not override files in the current directory\n    tokio::fs::create_dir(UPLOADS_DIRECTORY)\n        .await\n        .expect(\"failed to create `uploads` directory\");\n\n    let app = Router::new()\n        .route(\"/\", get(show_form).post(accept_form))\n        .route(\"/file/{file_name}\", post(save_request_body));\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n// Handler that streams the request body to a file.\n//\n// POST'ing to `/file/foo.txt` will create a file called `foo.txt`.\nasync fn save_request_body(\n    Path(file_name): Path<String>,\n    request: Request,\n) -> Result<(), (StatusCode, String)> {\n    stream_to_file(&file_name, request.into_body().into_data_stream()).await\n}\n\n// Handler that returns HTML for a multipart form.\nasync fn show_form() -> Html<&'static str> {\n    Html(\n        r#\"\n        <!doctype html>\n        <html>\n            <head>\n                <title>Upload something!</title>\n            </head>\n            <body>\n                <form action=\"/\" method=\"post\" enctype=\"multipart/form-data\">\n                    <div>\n                        <label>\n                            Upload file:\n                            <input type=\"file\" name=\"file\" multiple>\n                        </label>\n                    </div>\n\n                    <div>\n                        <input type=\"submit\" value=\"Upload files\">\n                    </div>\n                </form>\n            </body>\n        </html>\n        \"#,\n    )\n}\n\n// Handler that accepts a multipart form upload and streams each field to a file.\nasync fn accept_form(mut multipart: Multipart) -> Result<Redirect, (StatusCode, String)> {\n    while let Ok(Some(field)) = multipart.next_field().await {\n        let file_name = if let Some(file_name) = field.file_name() {\n            file_name.to_owned()\n        } else {\n            continue;\n        };\n\n        stream_to_file(&file_name, field).await?;\n    }\n\n    Ok(Redirect::to(\"/\"))\n}\n\n// Save a `Stream` to a file\nasync fn stream_to_file<S, E>(path: &str, stream: S) -> Result<(), (StatusCode, String)>\nwhere\n    S: Stream<Item = Result<Bytes, E>>,\n    E: Into<BoxError>,\n{\n    if !path_is_valid(path) {\n        return Err((StatusCode::BAD_REQUEST, \"Invalid path\".to_owned()));\n    }\n\n    async {\n        // Convert the stream into an `AsyncRead`.\n        let body_with_io_error = stream.map_err(io::Error::other);\n        let mut body_reader = pin!(StreamReader::new(body_with_io_error));\n\n        // Create the file. `File` implements `AsyncWrite`.\n        let path = std::path::Path::new(UPLOADS_DIRECTORY).join(path);\n        let mut file = BufWriter::new(File::create(path).await?);\n\n        // Copy the body into the file.\n        tokio::io::copy(&mut body_reader, &mut file).await?;\n\n        Ok::<_, io::Error>(())\n    }\n    .await\n    .map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()))\n}\n\n// to prevent directory traversal attacks we ensure the path consists of exactly one normal\n// component\nfn path_is_valid(path: &str) -> bool {\n    let path = std::path::Path::new(path);\n    let mut components = path.components().peekable();\n\n    if let Some(first) = components.peek() {\n        if !matches!(first, std::path::Component::Normal(_)) {\n            return false;\n        }\n    }\n\n    components.count() == 1\n}\n"
  },
  {
    "path": "examples/templates/Cargo.toml",
    "content": "[package]\nname = \"example-templates\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naskama = { version = \"0.15\", default-features = false, features = [\"std\", \"derive\"] }\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\n[dev-dependencies]\nhttp-body-util = \"0.1.0\"\ntower = { version = \"0.5.2\", features = [\"util\"] }\n"
  },
  {
    "path": "examples/templates/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-templates\n//! ```\n\nuse askama::Template;\nuse axum::{\n    extract,\n    http::StatusCode,\n    response::{Html, IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with some routes\n    let app = app();\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nfn app() -> Router {\n    Router::new().route(\"/greet/{name}\", get(greet))\n}\n\nasync fn greet(extract::Path(name): extract::Path<String>) -> impl IntoResponse {\n    let template = HelloTemplate { name };\n    HtmlTemplate(template)\n}\n\n#[derive(Template)]\n#[template(path = \"hello.html\")]\nstruct HelloTemplate {\n    name: String,\n}\n\nstruct HtmlTemplate<T>(T);\n\nimpl<T> IntoResponse for HtmlTemplate<T>\nwhere\n    T: Template,\n{\n    fn into_response(self) -> Response {\n        match self.0.render() {\n            Ok(html) => Html(html).into_response(),\n            Err(err) => (\n                StatusCode::INTERNAL_SERVER_ERROR,\n                format!(\"Failed to render template. Error: {err}\"),\n            )\n                .into_response(),\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{\n        body::Body,\n        http::{Request, StatusCode},\n    };\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    #[tokio::test]\n    async fn test_main() {\n        let response = app()\n            .oneshot(Request::get(\"/greet/Foo\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n        assert_eq!(response.status(), StatusCode::OK);\n        let body = response.into_body();\n        let bytes = body.collect().await.unwrap().to_bytes();\n        let html = String::from_utf8(bytes.to_vec()).unwrap();\n\n        assert_eq!(html, \"<h1>Hello, Foo!</h1>\");\n    }\n}\n"
  },
  {
    "path": "examples/templates/templates/hello.html",
    "content": "<h1>Hello, {{ name }}!</h1>\n"
  },
  {
    "path": "examples/templates-minijinja/Cargo.toml",
    "content": "[package]\nname = \"example-templates-minijinja\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nminijinja = \"2.3.1\"\ntokio = { version = \"1.0\", features = [\"full\"] }\n"
  },
  {
    "path": "examples/templates-minijinja/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-templates-minijinja\n//! ```\n//! Demo for the MiniJinja templating engine.\n//! Exposes three pages all sharing the same layout with a minimal nav menu.\n\nuse axum::extract::State;\nuse axum::http::StatusCode;\nuse axum::{response::Html, routing::get, Router};\nuse minijinja::{context, Environment};\nuse std::sync::Arc;\n\nstruct AppState {\n    env: Environment<'static>,\n}\n\n#[tokio::main]\nasync fn main() {\n    // init template engine and add templates\n    let mut env = Environment::new();\n    env.add_template(\"layout\", include_str!(\"../templates/layout.jinja\"))\n        .unwrap();\n    env.add_template(\"home\", include_str!(\"../templates/home.jinja\"))\n        .unwrap();\n    env.add_template(\"content\", include_str!(\"../templates/content.jinja\"))\n        .unwrap();\n    env.add_template(\"about\", include_str!(\"../templates/about.jinja\"))\n        .unwrap();\n\n    // pass env to handlers via state\n    let app_state = Arc::new(AppState { env });\n\n    // define routes\n    let app = Router::new()\n        .route(\"/\", get(handler_home))\n        .route(\"/content\", get(handler_content))\n        .route(\"/about\", get(handler_about))\n        .with_state(app_state);\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler_home(State(state): State<Arc<AppState>>) -> Result<Html<String>, StatusCode> {\n    let template = state.env.get_template(\"home\").unwrap();\n\n    let rendered = template\n        .render(context! {\n            title => \"Home\",\n            welcome_text => \"Hello World!\",\n        })\n        .unwrap();\n\n    Ok(Html(rendered))\n}\n\nasync fn handler_content(State(state): State<Arc<AppState>>) -> Result<Html<String>, StatusCode> {\n    let template = state.env.get_template(\"content\").unwrap();\n\n    let some_example_entries = vec![\"Data 1\", \"Data 2\", \"Data 3\"];\n\n    let rendered = template\n        .render(context! {\n            title => \"Content\",\n            entries => some_example_entries,\n        })\n        .unwrap();\n\n    Ok(Html(rendered))\n}\n\nasync fn handler_about(State(state): State<Arc<AppState>>) -> Result<Html<String>, StatusCode> {\n    let template = state.env.get_template(\"about\").unwrap();\n\n    let rendered = template.render(context!{\n        title => \"About\",\n        about_text => \"Simple demonstration layout for an axum project with minijinja as templating engine.\",\n    }).unwrap();\n\n    Ok(Html(rendered))\n}\n"
  },
  {
    "path": "examples/templates-minijinja/templates/about.jinja",
    "content": "{% extends \"layout\" %}\n{% block title %}{{ super() }} | {{ title }} {% endblock %}\n{% block body %}\n<h1>{{ title }}</h1>\n<p>{{ about_text }}</p>\n{% endblock %}\n"
  },
  {
    "path": "examples/templates-minijinja/templates/content.jinja",
    "content": "{% extends \"layout\" %}\n{% block title %}{{ super() }} | {{ title }} {% endblock %}\n{% block body %}\n<h1>{{ title }}</h1>\n{% for data_entry in entries %}\n<ul>\n    <li>{{ data_entry }}</li>\n</ul>\n{% endfor %}\n{% endblock %}\n"
  },
  {
    "path": "examples/templates-minijinja/templates/home.jinja",
    "content": "{% extends \"layout\" %}\n{% block title %}{{ super() }} | {{ title }} {% endblock %}\n{% block body %}\n<h1>{{ title }}</h1>\n<p>{{ welcome_text }}</p>\n{% endblock %}\n"
  },
  {
    "path": "examples/templates-minijinja/templates/layout.jinja",
    "content": "<!doctype html>\n<html>\n  <head><title>{% block title %}Website Name{% endblock %}</title></head>\n  <body>\n    <nav>\n        <ul>\n            <li><a href=\"/\">Home</a></li>\n            <li><a href=\"/content\">Content</a></li>\n            <li><a href=\"/about\">About</a></li>\n        </ul>\n    </nav>\n    {% block body %}{% endblock %}\n  </body>\n</html>\n"
  },
  {
    "path": "examples/testing/Cargo.toml",
    "content": "[package]\nname = \"example-testing\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhttp-body-util = \"0.1.0\"\nhyper-util = { version = \"0.1\", features = [\"client\", \"http1\", \"client-legacy\"] }\nmime = \"0.3\"\nserde_json = \"1.0\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower-http = { version = \"0.6.1\", features = [\"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\n[dev-dependencies]\ntower = { version = \"0.5.2\", features = [\"util\"] }\n"
  },
  {
    "path": "examples/testing/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo test -p example-testing\n//! ```\n\nuse std::net::SocketAddr;\n\nuse axum::{\n    extract::ConnectInfo,\n    routing::{get, post},\n    Json, Router,\n};\nuse tower_http::trace::TraceLayer;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app()).await;\n}\n\n/// Having a function that produces our app makes it easy to call it from tests\n/// without having to create an HTTP server.\nfn app() -> Router {\n    Router::new()\n        .route(\"/\", get(|| async { \"Hello, World!\" }))\n        .route(\n            \"/json\",\n            post(|payload: Json<serde_json::Value>| async move {\n                Json(serde_json::json!({ \"data\": payload.0 }))\n            }),\n        )\n        .route(\n            \"/requires-connect-info\",\n            get(|ConnectInfo(addr): ConnectInfo<SocketAddr>| async move { format!(\"Hi {addr}\") }),\n        )\n        // We can still add middleware\n        .layer(TraceLayer::new_for_http())\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{\n        body::Body,\n        extract::connect_info::MockConnectInfo,\n        http::{self, Request, StatusCode},\n    };\n    use http_body_util::BodyExt; // for `collect`\n    use serde_json::{json, Value};\n    use tokio::net::TcpListener;\n    use tower::{Service, ServiceExt}; // for `call`, `oneshot`, and `ready`\n\n    #[tokio::test]\n    async fn hello_world() {\n        let app = app();\n\n        // `Router` implements `tower::Service<Request<Body>>` so we can\n        // call it like any tower service, no need to run an HTTP server.\n        let response = app\n            .oneshot(Request::get(\"/\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n\n        let body = response.into_body().collect().await.unwrap().to_bytes();\n        assert_eq!(&body[..], b\"Hello, World!\");\n    }\n\n    #[tokio::test]\n    async fn json() {\n        let app = app();\n\n        let response = app\n            .oneshot(\n                Request::post(\"/json\")\n                    .header(http::header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref())\n                    .body(Body::from(\n                        serde_json::to_vec(&json!([1, 2, 3, 4])).unwrap(),\n                    ))\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n\n        let body = response.into_body().collect().await.unwrap().to_bytes();\n        let body: Value = serde_json::from_slice(&body).unwrap();\n        assert_eq!(body, json!({ \"data\": [1, 2, 3, 4] }));\n    }\n\n    #[tokio::test]\n    async fn not_found() {\n        let app = app();\n\n        let response = app\n            .oneshot(Request::get(\"/does-not-exist\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::NOT_FOUND);\n        let body = response.into_body().collect().await.unwrap().to_bytes();\n        assert!(body.is_empty());\n    }\n\n    // You can also spawn a server and talk to it like any other HTTP server:\n    #[tokio::test]\n    async fn the_real_deal() {\n        let listener = TcpListener::bind(\"0.0.0.0:0\").await.unwrap();\n        let addr = listener.local_addr().unwrap();\n\n        tokio::spawn(async move {\n            axum::serve(listener, app()).await;\n        });\n\n        let client =\n            hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new())\n                .build_http();\n\n        let response = client\n            .request(\n                Request::get(format!(\"http://{addr}\"))\n                    .header(\"Host\", \"localhost\")\n                    .body(Body::empty())\n                    .unwrap(),\n            )\n            .await\n            .unwrap();\n\n        let body = response.into_body().collect().await.unwrap().to_bytes();\n        assert_eq!(&body[..], b\"Hello, World!\");\n    }\n\n    // You can use `ready()` and `call()` to avoid using `clone()`\n    // in multiple request\n    #[tokio::test]\n    async fn multiple_request() {\n        let mut app = app().into_service();\n\n        let request = Request::get(\"/\").body(Body::empty()).unwrap();\n        let response = ServiceExt::<Request<Body>>::ready(&mut app)\n            .await\n            .unwrap()\n            .call(request)\n            .await\n            .unwrap();\n        assert_eq!(response.status(), StatusCode::OK);\n\n        let request = Request::get(\"/\").body(Body::empty()).unwrap();\n        let response = ServiceExt::<Request<Body>>::ready(&mut app)\n            .await\n            .unwrap()\n            .call(request)\n            .await\n            .unwrap();\n        assert_eq!(response.status(), StatusCode::OK);\n    }\n\n    // Here we're calling `/requires-connect-info` which requires `ConnectInfo`\n    //\n    // That is normally set with `Router::into_make_service_with_connect_info` but we can't easily\n    // use that during tests. The solution is instead to set the `MockConnectInfo` layer during\n    // tests.\n    #[tokio::test]\n    async fn with_into_make_service_with_connect_info() {\n        let mut app = app()\n            .layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 3000))))\n            .into_service();\n\n        let request = Request::get(\"/requires-connect-info\")\n            .body(Body::empty())\n            .unwrap();\n        let response = app.ready().await.unwrap().call(request).await.unwrap();\n        assert_eq!(response.status(), StatusCode::OK);\n    }\n}\n"
  },
  {
    "path": "examples/testing-websockets/Cargo.toml",
    "content": "[package]\nname = \"example-testing-websockets\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"ws\"] }\nfutures-channel = \"0.3\"\nfutures-util = { version = \"0.3\", default-features = false, features = [\"sink\", \"std\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntokio-tungstenite = \"0.29\"\n"
  },
  {
    "path": "examples/testing-websockets/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo test -p example-testing-websockets\n//! ```\n\nuse axum::{\n    extract::{\n        ws::{Message, WebSocket},\n        WebSocketUpgrade,\n    },\n    response::Response,\n    routing::get,\n    Router,\n};\nuse futures_util::{Sink, SinkExt, Stream, StreamExt};\n\n#[tokio::main]\nasync fn main() {\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    println!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app()).await;\n}\n\nfn app() -> Router {\n    // WebSocket routes can generally be tested in two ways:\n    //\n    // - Integration tests where you run the server and connect with a real WebSocket client.\n    // - Unit tests where you mock the socket as some generic send/receive type\n    //\n    // Which version you pick is up to you. Generally we recommend the integration test version\n    // unless your app has a lot of setup that makes it hard to run in a test.\n    Router::new()\n        .route(\"/integration-testable\", get(integration_testable_handler))\n        .route(\"/unit-testable\", get(unit_testable_handler))\n}\n\n// A WebSocket handler that echos any message it receives.\n//\n// This one we'll be integration testing so it can be written in the regular way.\nasync fn integration_testable_handler(ws: WebSocketUpgrade) -> Response {\n    ws.on_upgrade(integration_testable_handle_socket)\n}\n\nasync fn integration_testable_handle_socket(mut socket: WebSocket) {\n    while let Some(Ok(msg)) = socket.recv().await {\n        if let Message::Text(msg) = msg {\n            if socket\n                .send(Message::Text(format!(\"You said: {msg}\").into()))\n                .await\n                .is_err()\n            {\n                break;\n            }\n        }\n    }\n}\n\n// The unit testable version requires some changes.\n//\n// By splitting the socket into an `impl Sink` and `impl Stream` we can test without providing a\n// real socket and instead using channels, which also implement `Sink` and `Stream`.\nasync fn unit_testable_handler(ws: WebSocketUpgrade) -> Response {\n    ws.on_upgrade(|socket| {\n        let (write, read) = socket.split();\n        unit_testable_handle_socket(write, read)\n    })\n}\n\n// The implementation is largely the same as `integration_testable_handle_socket` expect we call\n// methods from `SinkExt` and `StreamExt`.\nasync fn unit_testable_handle_socket<W, R>(mut write: W, mut read: R)\nwhere\n    W: Sink<Message> + Unpin,\n    R: Stream<Item = Result<Message, axum::Error>> + Unpin,\n{\n    while let Some(Ok(msg)) = read.next().await {\n        if let Message::Text(msg) = msg {\n            if write\n                .send(Message::Text(format!(\"You said: {msg}\").into()))\n                .await\n                .is_err()\n            {\n                break;\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use std::{\n        future::IntoFuture,\n        net::{Ipv4Addr, SocketAddr},\n    };\n    use tokio_tungstenite::tungstenite;\n\n    // We can integration test one handler by running the server in a background task and\n    // connecting to it like any other client would.\n    #[tokio::test]\n    async fn integration_test() {\n        let listener = tokio::net::TcpListener::bind(SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0)))\n            .await\n            .unwrap();\n        let addr = listener.local_addr().unwrap();\n        tokio::spawn(axum::serve(listener, app()).into_future());\n\n        let (mut socket, _response) =\n            tokio_tungstenite::connect_async(format!(\"ws://{addr}/integration-testable\"))\n                .await\n                .unwrap();\n\n        socket\n            .send(tungstenite::Message::text(\"foo\"))\n            .await\n            .unwrap();\n\n        let msg = match socket.next().await.unwrap().unwrap() {\n            tungstenite::Message::Text(msg) => msg,\n            other => panic!(\"expected a text message but got {other:?}\"),\n        };\n\n        assert_eq!(msg.as_str(), \"You said: foo\");\n    }\n\n    // We can unit test the other handler by creating channels to read and write from.\n    #[tokio::test]\n    async fn unit_test() {\n        // Need to use \"futures\" channels rather than \"tokio\" channels as they implement `Sink` and\n        // `Stream`\n        let (socket_write, mut test_rx) = futures_channel::mpsc::channel(1024);\n        let (mut test_tx, socket_read) = futures_channel::mpsc::channel(1024);\n\n        tokio::spawn(unit_testable_handle_socket(socket_write, socket_read));\n\n        test_tx.send(Ok(Message::Text(\"foo\".into()))).await.unwrap();\n\n        let msg = match test_rx.next().await.unwrap() {\n            Message::Text(msg) => msg,\n            other => panic!(\"expected a text message but got {other:?}\"),\n        };\n\n        assert_eq!(msg.as_str(), \"You said: foo\");\n    }\n}\n"
  },
  {
    "path": "examples/tls-graceful-shutdown/Cargo.toml",
    "content": "[package]\nname = \"example-tls-graceful-shutdown\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\naxum-extra = { path = \"../../axum-extra\" }\naxum-server = { version = \"0.8\", features = [\"tls-rustls\"] }\ntokio = { version = \"1\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/tls-graceful-shutdown/self_signed_certs/cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUXVYkRCrM/ge03DVymDtXCuybp7gwDQYJKoZIhvcNAQEL\nBQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\nGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X\nDTIxMDczMTE0MjIxMloXDTIyMDczMTE0MjIxMlowWTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\nIEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEA02V5ZjmqLB/VQwTarrz/35qsa83L+DbAoa0001+jVmmC+G9Nufi0\ndaroFWj/Uicv2fZWETU8JoZKUrX4BK9og5cg5rln/CtBRWCUYIwRgY9R/CdBGPn4\nkp+XkSJaCw74ZIyLy/Zfux6h8ES1m9YRnBza+s7U+ImRBRf4MRPtXQ3/mqJxAZYq\ndOnKnvssRyD2qutgVTAxwMUvJWIivRhRYDj7WOpS4CEEeQxP1iH1/T5P7FdtTGdT\nbVBABCA8JhL96uFGPpOYHcM/7R5EIA3yZ5FNg931QzoDITjtXGtQ6y9/l/IYkWm6\nJ67RWcN0IoTsZhz0WNU4gAeslVtJLofn8QIDAQABo1MwUTAdBgNVHQ4EFgQUzFnK\nNfS4LAYuKeWwHbzooER0yZ0wHwYDVR0jBBgwFoAUzFnKNfS4LAYuKeWwHbzooER0\nyZ0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAk4O+e9jia59W\nZwetN4GU7OWcYhmOgSizRSs6u7mTfp62LDMt96WKU3THksOnZ44HnqWQxsSfdFVU\nXJD12tjvVU8Z4FWzQajcHeemUYiDze8EAh6TnxnUcOrU8IcwiKGxCWRY/908jnWg\n+MMscfMCMYTRdeTPqD8fGzAlUCtmyzH6KLE3s4Oo/r5+NR+Uvrwpdvb7xe0MwwO9\nQ/zR4N8ep/HwHVEObcaBofE1ssZLksX7ZgCP9wMgXRWpNAtC5EWxMbxYjBfWFH24\nfDJlBMiGJWg8HHcxK7wQhFh+fuyNzE+xEWPsI9VL1zDftd9x8/QsOagyEOnY8Vxr\nAopvZ09uEQ==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/tls-graceful-shutdown/self_signed_certs/key.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTZXlmOaosH9VD\nBNquvP/fmqxrzcv4NsChrTTTX6NWaYL4b025+LR1qugVaP9SJy/Z9lYRNTwmhkpS\ntfgEr2iDlyDmuWf8K0FFYJRgjBGBj1H8J0EY+fiSn5eRIloLDvhkjIvL9l+7HqHw\nRLWb1hGcHNr6ztT4iZEFF/gxE+1dDf+aonEBlip06cqe+yxHIPaq62BVMDHAxS8l\nYiK9GFFgOPtY6lLgIQR5DE/WIfX9Pk/sV21MZ1NtUEAEIDwmEv3q4UY+k5gdwz/t\nHkQgDfJnkU2D3fVDOgMhOO1ca1DrL3+X8hiRabonrtFZw3QihOxmHPRY1TiAB6yV\nW0kuh+fxAgMBAAECggEADltu8k1qTFLhJgsXWxTFAAe+PBgfCT2WuaRM2So+qqjB\n12Of0MieYPt5hbK63HaC3nfHgqWt7yPhulpXfOH45C8IcgMXl93MMg0MJr58leMI\n+2ojFrIrerHSFm5R1TxwDEwrVm/mMowzDWFtQCc6zPJ8wNn5RuP48HKfTZ3/2fjw\nzEjSwPO2wFMfo1EJNTjlI303lFbdFBs67NaX6puh30M7Tn+gznHKyO5a7F57wkIt\nfkgnEy/sgMedQlwX7bRpUoD6f0fZzV8Qz4cHFywtYErczZJh3VGitJoO/VCIDdty\nRPXOAqVDd7EpP1UUehZlKVWZ0OZMEfRgKbRCel5abQKBgQDwgwrIQ5+BiZv6a0VT\nETeXB+hRbvBinRykNo/RvLc3j1enRh9/zO/ShadZIXgOAiM1Jnr5Gp8KkNGca6K1\nmyhtad7xYPODYzNXXp6T1OPgZxHZLIYzVUj6ypXeV64Te5ZiDaJ1D49czsq+PqsQ\nXRcgBJSNpFtDFiXWpjXWfx8PxwKBgQDhAnLY5Sl2eeQo+ud0MvjwftB/mN2qCzJY\n5AlQpRI4ThWxJgGPuHTR29zVa5iWNYuA5LWrC1y/wx+t5HKUwq+5kxvs+npYpDJD\nZX/w0Glc6s0Jc/mFySkbw9B2LePedL7lRF5OiAyC6D106Sc9V2jlL4IflmOzt4CD\nZTNbLtC6hwKBgHfIzBXxl/9sCcMuqdg1Ovp9dbcZCaATn7ApfHd5BccmHQGyav27\nk7XF2xMJGEHhzqcqAxUNrSgV+E9vTBomrHvRvrd5Ec7eGTPqbBA0d0nMC5eeFTh7\nwV0miH20LX6Gjt9G6yJiHYSbeV5G1+vOcTYBEft5X/qJjU7aePXbWh0BAoGBAJlV\n5tgCCuhvFloK6fHYzqZtdT6O+PfpW20SMXrgkvMF22h2YvgDFrDwqKRUB47NfHzg\n3yBpxNH1ccA5/w97QO8w3gX3h6qicpJVOAPusu6cIBACFZfjRv1hyszOZwvw+Soa\nFj5kHkqTY1YpkREPYS9V2dIW1Wjic1SXgZDw7VM/AoGAP/cZ3ZHTSCDTFlItqy5C\nrIy2AiY0WJsx+K0qcvtosPOOwtnGjWHb1gdaVdfX/IRkSsX4PAOdnsyidNC5/l/m\ny8oa+5WEeGFclWFhr4dnTA766o8HrM2UjIgWWYBF2VKdptGnHxFeJWFUmeQC/xeW\nw37pCS7ykL+7gp7V0WShYsw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/tls-graceful-shutdown/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-tls-graceful-shutdown\n//! ```\n\nuse axum::{\n    handler::HandlerWithoutStateExt,\n    http::{StatusCode, Uri},\n    response::Redirect,\n    routing::get,\n    BoxError, Router,\n};\nuse axum_server::tls_rustls::RustlsConfig;\nuse std::{future::Future, net::SocketAddr, path::PathBuf, time::Duration};\nuse tokio::signal;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[derive(Clone, Copy)]\nstruct Ports {\n    http: u16,\n    https: u16,\n}\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let ports = Ports {\n        http: 7878,\n        https: 3000,\n    };\n\n    //Create a handle for our TLS server so the shutdown signal can all shutdown\n    let handle = axum_server::Handle::new();\n    //save the future for easy shutting down of redirect server\n    let shutdown_future = shutdown_signal(handle.clone());\n\n    // optional: spawn a second server to redirect http requests to this server\n    tokio::spawn(redirect_http_to_https(ports, shutdown_future));\n\n    // configure certificate and private key used by https\n    let config = RustlsConfig::from_pem_file(\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"cert.pem\"),\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"key.pem\"),\n    )\n    .await\n    .unwrap();\n\n    let app = Router::new().route(\"/\", get(handler));\n\n    // run https server\n    let addr = SocketAddr::from(([127, 0, 0, 1], ports.https));\n    tracing::debug!(\"listening on {addr}\");\n    axum_server::bind_rustls(addr, config)\n        .handle(handle)\n        .serve(app.into_make_service())\n        .await\n        .unwrap();\n}\n\nasync fn shutdown_signal(handle: axum_server::Handle<SocketAddr>) {\n    let ctrl_c = async {\n        signal::ctrl_c()\n            .await\n            .expect(\"failed to install Ctrl+C handler\");\n    };\n\n    #[cfg(unix)]\n    let terminate = async {\n        signal::unix::signal(signal::unix::SignalKind::terminate())\n            .expect(\"failed to install signal handler\")\n            .recv()\n            .await;\n    };\n\n    #[cfg(not(unix))]\n    let terminate = std::future::pending::<()>();\n\n    tokio::select! {\n        _ = ctrl_c => {},\n        _ = terminate => {},\n    }\n\n    tracing::info!(\"Received termination signal shutting down\");\n    handle.graceful_shutdown(Some(Duration::from_secs(10))); // 10 secs is how long docker will wait\n                                                             // to force shutdown\n}\n\nasync fn handler() -> &'static str {\n    \"Hello, World!\"\n}\n\nasync fn redirect_http_to_https<F>(ports: Ports, signal: F)\nwhere\n    F: Future<Output = ()> + Send + 'static,\n{\n    fn make_https(uri: Uri, https_port: u16) -> Result<Uri, BoxError> {\n        let mut parts = uri.into_parts();\n\n        parts.scheme = Some(axum::http::uri::Scheme::HTTPS);\n        parts.authority = Some(format!(\"localhost:{https_port}\").parse()?);\n\n        if parts.path_and_query.is_none() {\n            parts.path_and_query = Some(\"/\".parse().unwrap());\n        }\n\n        Ok(Uri::from_parts(parts)?)\n    }\n\n    let redirect = move |uri: Uri| async move {\n        match make_https(uri, ports.https) {\n            Ok(uri) => Ok(Redirect::permanent(uri.to_string())),\n            Err(error) => {\n                tracing::warn!(%error, \"failed to convert URI to HTTPS\");\n                Err(StatusCode::BAD_REQUEST)\n            }\n        }\n    };\n\n    let addr = SocketAddr::from(([127, 0, 0, 1], ports.http));\n    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();\n    tracing::debug!(\"listening on {addr}\");\n    axum::serve(listener, redirect.into_make_service())\n        .with_graceful_shutdown(signal)\n        .await;\n}\n"
  },
  {
    "path": "examples/tls-rustls/Cargo.toml",
    "content": "[package]\nname = \"example-tls-rustls\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\naxum-extra = { path = \"../../axum-extra\" }\naxum-server = { version = \"0.8\", features = [\"tls-rustls\"] }\ntokio = { version = \"1\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/tls-rustls/self_signed_certs/cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUXVYkRCrM/ge03DVymDtXCuybp7gwDQYJKoZIhvcNAQEL\nBQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\nGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X\nDTIxMDczMTE0MjIxMloXDTIyMDczMTE0MjIxMlowWTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\nIEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEA02V5ZjmqLB/VQwTarrz/35qsa83L+DbAoa0001+jVmmC+G9Nufi0\ndaroFWj/Uicv2fZWETU8JoZKUrX4BK9og5cg5rln/CtBRWCUYIwRgY9R/CdBGPn4\nkp+XkSJaCw74ZIyLy/Zfux6h8ES1m9YRnBza+s7U+ImRBRf4MRPtXQ3/mqJxAZYq\ndOnKnvssRyD2qutgVTAxwMUvJWIivRhRYDj7WOpS4CEEeQxP1iH1/T5P7FdtTGdT\nbVBABCA8JhL96uFGPpOYHcM/7R5EIA3yZ5FNg931QzoDITjtXGtQ6y9/l/IYkWm6\nJ67RWcN0IoTsZhz0WNU4gAeslVtJLofn8QIDAQABo1MwUTAdBgNVHQ4EFgQUzFnK\nNfS4LAYuKeWwHbzooER0yZ0wHwYDVR0jBBgwFoAUzFnKNfS4LAYuKeWwHbzooER0\nyZ0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAk4O+e9jia59W\nZwetN4GU7OWcYhmOgSizRSs6u7mTfp62LDMt96WKU3THksOnZ44HnqWQxsSfdFVU\nXJD12tjvVU8Z4FWzQajcHeemUYiDze8EAh6TnxnUcOrU8IcwiKGxCWRY/908jnWg\n+MMscfMCMYTRdeTPqD8fGzAlUCtmyzH6KLE3s4Oo/r5+NR+Uvrwpdvb7xe0MwwO9\nQ/zR4N8ep/HwHVEObcaBofE1ssZLksX7ZgCP9wMgXRWpNAtC5EWxMbxYjBfWFH24\nfDJlBMiGJWg8HHcxK7wQhFh+fuyNzE+xEWPsI9VL1zDftd9x8/QsOagyEOnY8Vxr\nAopvZ09uEQ==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/tls-rustls/self_signed_certs/key.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTZXlmOaosH9VD\nBNquvP/fmqxrzcv4NsChrTTTX6NWaYL4b025+LR1qugVaP9SJy/Z9lYRNTwmhkpS\ntfgEr2iDlyDmuWf8K0FFYJRgjBGBj1H8J0EY+fiSn5eRIloLDvhkjIvL9l+7HqHw\nRLWb1hGcHNr6ztT4iZEFF/gxE+1dDf+aonEBlip06cqe+yxHIPaq62BVMDHAxS8l\nYiK9GFFgOPtY6lLgIQR5DE/WIfX9Pk/sV21MZ1NtUEAEIDwmEv3q4UY+k5gdwz/t\nHkQgDfJnkU2D3fVDOgMhOO1ca1DrL3+X8hiRabonrtFZw3QihOxmHPRY1TiAB6yV\nW0kuh+fxAgMBAAECggEADltu8k1qTFLhJgsXWxTFAAe+PBgfCT2WuaRM2So+qqjB\n12Of0MieYPt5hbK63HaC3nfHgqWt7yPhulpXfOH45C8IcgMXl93MMg0MJr58leMI\n+2ojFrIrerHSFm5R1TxwDEwrVm/mMowzDWFtQCc6zPJ8wNn5RuP48HKfTZ3/2fjw\nzEjSwPO2wFMfo1EJNTjlI303lFbdFBs67NaX6puh30M7Tn+gznHKyO5a7F57wkIt\nfkgnEy/sgMedQlwX7bRpUoD6f0fZzV8Qz4cHFywtYErczZJh3VGitJoO/VCIDdty\nRPXOAqVDd7EpP1UUehZlKVWZ0OZMEfRgKbRCel5abQKBgQDwgwrIQ5+BiZv6a0VT\nETeXB+hRbvBinRykNo/RvLc3j1enRh9/zO/ShadZIXgOAiM1Jnr5Gp8KkNGca6K1\nmyhtad7xYPODYzNXXp6T1OPgZxHZLIYzVUj6ypXeV64Te5ZiDaJ1D49czsq+PqsQ\nXRcgBJSNpFtDFiXWpjXWfx8PxwKBgQDhAnLY5Sl2eeQo+ud0MvjwftB/mN2qCzJY\n5AlQpRI4ThWxJgGPuHTR29zVa5iWNYuA5LWrC1y/wx+t5HKUwq+5kxvs+npYpDJD\nZX/w0Glc6s0Jc/mFySkbw9B2LePedL7lRF5OiAyC6D106Sc9V2jlL4IflmOzt4CD\nZTNbLtC6hwKBgHfIzBXxl/9sCcMuqdg1Ovp9dbcZCaATn7ApfHd5BccmHQGyav27\nk7XF2xMJGEHhzqcqAxUNrSgV+E9vTBomrHvRvrd5Ec7eGTPqbBA0d0nMC5eeFTh7\nwV0miH20LX6Gjt9G6yJiHYSbeV5G1+vOcTYBEft5X/qJjU7aePXbWh0BAoGBAJlV\n5tgCCuhvFloK6fHYzqZtdT6O+PfpW20SMXrgkvMF22h2YvgDFrDwqKRUB47NfHzg\n3yBpxNH1ccA5/w97QO8w3gX3h6qicpJVOAPusu6cIBACFZfjRv1hyszOZwvw+Soa\nFj5kHkqTY1YpkREPYS9V2dIW1Wjic1SXgZDw7VM/AoGAP/cZ3ZHTSCDTFlItqy5C\nrIy2AiY0WJsx+K0qcvtosPOOwtnGjWHb1gdaVdfX/IRkSsX4PAOdnsyidNC5/l/m\ny8oa+5WEeGFclWFhr4dnTA766o8HrM2UjIgWWYBF2VKdptGnHxFeJWFUmeQC/xeW\nw37pCS7ykL+7gp7V0WShYsw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/tls-rustls/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-tls-rustls\n//! ```\n\n#![allow(unused_imports)]\n\nuse axum::{\n    handler::HandlerWithoutStateExt,\n    http::{uri::Authority, StatusCode, Uri},\n    response::Redirect,\n    routing::get,\n    BoxError, Router,\n};\nuse axum_server::tls_rustls::RustlsConfig;\nuse std::{net::SocketAddr, path::PathBuf};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[allow(dead_code)]\n#[derive(Clone, Copy)]\nstruct Ports {\n    http: u16,\n    https: u16,\n}\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let ports = Ports {\n        http: 7878,\n        https: 3000,\n    };\n    // optional: spawn a second server to redirect http requests to this server\n    tokio::spawn(redirect_http_to_https(ports));\n\n    // configure certificate and private key used by https\n    let config = RustlsConfig::from_pem_file(\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"cert.pem\"),\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"key.pem\"),\n    )\n    .await\n    .unwrap();\n\n    let app = Router::new().route(\"/\", get(handler));\n\n    // run https server\n    let addr = SocketAddr::from(([127, 0, 0, 1], ports.https));\n    tracing::debug!(\"listening on {}\", addr);\n    axum_server::bind_rustls(addr, config)\n        .serve(app.into_make_service())\n        .await\n        .unwrap();\n}\n\n#[allow(dead_code)]\nasync fn handler() -> &'static str {\n    \"Hello, World!\"\n}\n\n#[allow(dead_code)]\nasync fn redirect_http_to_https(ports: Ports) {\n    fn make_https(uri: Uri, https_port: u16) -> Result<Uri, BoxError> {\n        let mut parts = uri.into_parts();\n\n        parts.scheme = Some(axum::http::uri::Scheme::HTTPS);\n        parts.authority = Some(format!(\"localhost:{https_port}\").parse()?);\n\n        if parts.path_and_query.is_none() {\n            parts.path_and_query = Some(\"/\".parse().unwrap());\n        }\n\n        Ok(Uri::from_parts(parts)?)\n    }\n\n    let redirect = move |uri: Uri| async move {\n        match make_https(uri, ports.https) {\n            Ok(uri) => Ok(Redirect::permanent(uri.to_string())),\n            Err(error) => {\n                tracing::warn!(%error, \"failed to convert URI to HTTPS\");\n                Err(StatusCode::BAD_REQUEST)\n            }\n        }\n    };\n\n    let addr = SocketAddr::from(([127, 0, 0, 1], ports.http));\n    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, redirect.into_make_service()).await;\n}\n"
  },
  {
    "path": "examples/todos/Cargo.toml",
    "content": "[package]\nname = \"example-todos\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nserde = { version = \"1.0\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower = { version = \"0.5.2\", features = [\"util\", \"timeout\"] }\ntower-http = { version = \"0.6.1\", features = [\"add-extension\", \"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\nuuid = { version = \"1.0\", features = [\"serde\", \"v4\"] }\n"
  },
  {
    "path": "examples/todos/src/main.rs",
    "content": "//! Provides a RESTful web server managing some Todos.\n//!\n//! API will be:\n//!\n//! - `GET /todos`: return a JSON list of Todos.\n//! - `POST /todos`: create a new Todo.\n//! - `PATCH /todos/{id}`: update a specific Todo.\n//! - `DELETE /todos/{id}`: delete a specific Todo.\n//!\n//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-todos\n//! ```\n\nuse axum::{\n    error_handling::HandleErrorLayer,\n    extract::{Path, Query, State},\n    http::StatusCode,\n    response::IntoResponse,\n    routing::{get, patch},\n    Json, Router,\n};\nuse serde::{Deserialize, Serialize};\nuse std::{\n    collections::HashMap,\n    sync::{Arc, RwLock},\n    time::Duration,\n};\nuse tower::{BoxError, ServiceBuilder};\nuse tower_http::trace::TraceLayer;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\nuse uuid::Uuid;\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let db = Db::default();\n\n    // Compose the routes\n    let app = Router::new()\n        .route(\"/todos\", get(todos_index).post(todos_create))\n        .route(\"/todos/{id}\", patch(todos_update).delete(todos_delete))\n        // Add middleware to all routes\n        .layer(\n            ServiceBuilder::new()\n                .layer(HandleErrorLayer::new(|error: BoxError| async move {\n                    if error.is::<tower::timeout::error::Elapsed>() {\n                        Ok(StatusCode::REQUEST_TIMEOUT)\n                    } else {\n                        Err((\n                            StatusCode::INTERNAL_SERVER_ERROR,\n                            format!(\"Unhandled internal error: {error}\"),\n                        ))\n                    }\n                }))\n                .timeout(Duration::from_secs(10))\n                .layer(TraceLayer::new_for_http())\n                .into_inner(),\n        )\n        .with_state(db);\n\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\n// The query parameters for todos index\n#[derive(Debug, Deserialize, Default)]\npub struct Pagination {\n    pub offset: Option<usize>,\n    pub limit: Option<usize>,\n}\n\nasync fn todos_index(pagination: Query<Pagination>, State(db): State<Db>) -> impl IntoResponse {\n    let todos = db.read().unwrap();\n\n    let todos = todos\n        .values()\n        .skip(pagination.offset.unwrap_or(0))\n        .take(pagination.limit.unwrap_or(usize::MAX))\n        .cloned()\n        .collect::<Vec<_>>();\n\n    Json(todos)\n}\n\n#[derive(Debug, Deserialize)]\nstruct CreateTodo {\n    text: String,\n}\n\nasync fn todos_create(State(db): State<Db>, Json(input): Json<CreateTodo>) -> impl IntoResponse {\n    let todo = Todo {\n        id: Uuid::new_v4(),\n        text: input.text,\n        completed: false,\n    };\n\n    db.write().unwrap().insert(todo.id, todo.clone());\n\n    (StatusCode::CREATED, Json(todo))\n}\n\n#[derive(Debug, Deserialize)]\nstruct UpdateTodo {\n    text: Option<String>,\n    completed: Option<bool>,\n}\n\nasync fn todos_update(\n    Path(id): Path<Uuid>,\n    State(db): State<Db>,\n    Json(input): Json<UpdateTodo>,\n) -> Result<impl IntoResponse, StatusCode> {\n    let mut todo = db\n        .read()\n        .unwrap()\n        .get(&id)\n        .cloned()\n        .ok_or(StatusCode::NOT_FOUND)?;\n\n    if let Some(text) = input.text {\n        todo.text = text;\n    }\n\n    if let Some(completed) = input.completed {\n        todo.completed = completed;\n    }\n\n    db.write().unwrap().insert(todo.id, todo.clone());\n\n    Ok(Json(todo))\n}\n\nasync fn todos_delete(Path(id): Path<Uuid>, State(db): State<Db>) -> impl IntoResponse {\n    if db.write().unwrap().remove(&id).is_some() {\n        StatusCode::NO_CONTENT\n    } else {\n        StatusCode::NOT_FOUND\n    }\n}\n\ntype Db = Arc<RwLock<HashMap<Uuid, Todo>>>;\n\n#[derive(Debug, Serialize, Clone)]\nstruct Todo {\n    id: Uuid,\n    text: String,\n    completed: bool,\n}\n"
  },
  {
    "path": "examples/tokio-postgres/Cargo.toml",
    "content": "[package]\nname = \"example-tokio-postgres\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nbb8 = \"0.9.0\"\nbb8-postgres = \"0.9.0\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntokio-postgres = \"0.7.2\"\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/tokio-postgres/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-tokio-postgres\n//! ```\n\nuse axum::{\n    extract::{FromRef, FromRequestParts, State},\n    http::{request::Parts, StatusCode},\n    routing::get,\n    Router,\n};\nuse bb8::{Pool, PooledConnection};\nuse bb8_postgres::PostgresConnectionManager;\nuse tokio_postgres::NoTls;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // set up connection pool\n    let manager =\n        PostgresConnectionManager::new_from_stringlike(\"host=localhost user=postgres\", NoTls)\n            .unwrap();\n    let pool = Pool::builder().build(manager).await.unwrap();\n\n    // build our application with some routes\n    let app = Router::new()\n        .route(\n            \"/\",\n            get(using_connection_pool_extractor).post(using_connection_extractor),\n        )\n        .with_state(pool);\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\ntype ConnectionPool = Pool<PostgresConnectionManager<NoTls>>;\n\nasync fn using_connection_pool_extractor(\n    State(pool): State<ConnectionPool>,\n) -> Result<String, (StatusCode, String)> {\n    let conn = pool.get().await.map_err(internal_error)?;\n\n    let row = conn\n        .query_one(\"select 1 + 1\", &[])\n        .await\n        .map_err(internal_error)?;\n    let two: i32 = row.try_get(0).map_err(internal_error)?;\n\n    Ok(two.to_string())\n}\n\n// we can also write a custom extractor that grabs a connection from the pool\n// which setup is appropriate depends on your application\nstruct DatabaseConnection(PooledConnection<'static, PostgresConnectionManager<NoTls>>);\n\nimpl<S> FromRequestParts<S> for DatabaseConnection\nwhere\n    ConnectionPool: FromRef<S>,\n    S: Send + Sync,\n{\n    type Rejection = (StatusCode, String);\n\n    async fn from_request_parts(_parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let pool = ConnectionPool::from_ref(state);\n\n        let conn = pool.get_owned().await.map_err(internal_error)?;\n\n        Ok(Self(conn))\n    }\n}\n\nasync fn using_connection_extractor(\n    DatabaseConnection(conn): DatabaseConnection,\n) -> Result<String, (StatusCode, String)> {\n    let row = conn\n        .query_one(\"select 1 + 1\", &[])\n        .await\n        .map_err(internal_error)?;\n    let two: i32 = row.try_get(0).map_err(internal_error)?;\n\n    Ok(two.to_string())\n}\n\n/// Utility function for mapping any error into a `500 Internal Server Error`\n/// response.\nfn internal_error<E>(err: E) -> (StatusCode, String)\nwhere\n    E: std::error::Error,\n{\n    (StatusCode::INTERNAL_SERVER_ERROR, err.to_string())\n}\n"
  },
  {
    "path": "examples/tokio-redis/Cargo.toml",
    "content": "[package]\nname = \"example-tokio-redis\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nbb8 = \"0.9\"\nredis = { version = \"1\", default-features = false, features = [\"tokio-comp\", \"bb8\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/tokio-redis/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-tokio-redis\n//! ```\n\nuse axum::{\n    extract::{FromRef, FromRequestParts, State},\n    http::{request::Parts, StatusCode},\n    routing::get,\n    Router,\n};\nuse redis::AsyncCommands;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    tracing::debug!(\"connecting to redis\");\n    let client = redis::Client::open(\"redis://localhost\").unwrap();\n    let pool = bb8::Pool::builder().build(client).await.unwrap();\n\n    {\n        // ping the database before starting\n        let mut conn = pool.get().await.unwrap();\n        conn.set::<&str, &str, ()>(\"foo\", \"bar\").await.unwrap();\n        let result: String = conn.get(\"foo\").await.unwrap();\n        assert_eq!(result, \"bar\");\n    }\n    tracing::debug!(\"successfully connected to redis and pinged it\");\n\n    // build our application with some routes\n    let app = Router::new()\n        .route(\n            \"/\",\n            get(using_connection_pool_extractor).post(using_connection_extractor),\n        )\n        .with_state(pool);\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\ntype ConnectionPool = bb8::Pool<redis::Client>;\n\nasync fn using_connection_pool_extractor(\n    State(pool): State<ConnectionPool>,\n) -> Result<String, (StatusCode, String)> {\n    let mut conn = pool.get().await.map_err(internal_error)?;\n    let result: String = conn.get(\"foo\").await.map_err(internal_error)?;\n    Ok(result)\n}\n\n// we can also write a custom extractor that grabs a connection from the pool\n// which setup is appropriate depends on your application\nstruct DatabaseConnection(bb8::PooledConnection<'static, redis::Client>);\n\nimpl<S> FromRequestParts<S> for DatabaseConnection\nwhere\n    ConnectionPool: FromRef<S>,\n    S: Send + Sync,\n{\n    type Rejection = (StatusCode, String);\n\n    async fn from_request_parts(_parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {\n        let pool = ConnectionPool::from_ref(state);\n\n        let conn = pool.get_owned().await.map_err(internal_error)?;\n\n        Ok(Self(conn))\n    }\n}\n\nasync fn using_connection_extractor(\n    DatabaseConnection(mut conn): DatabaseConnection,\n) -> Result<String, (StatusCode, String)> {\n    let result: String = conn.get(\"foo\").await.map_err(internal_error)?;\n\n    Ok(result)\n}\n\n/// Utility function for mapping any error into a `500 Internal Server Error`\n/// response.\nfn internal_error<E>(err: E) -> (StatusCode, String)\nwhere\n    E: std::error::Error,\n{\n    (StatusCode::INTERNAL_SERVER_ERROR, err.to_string())\n}\n"
  },
  {
    "path": "examples/tracing-aka-logging/Cargo.toml",
    "content": "[package]\nname = \"example-tracing-aka-logging\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"tracing\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntower-http = { version = \"0.6.1\", features = [\"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/tracing-aka-logging/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-tracing-aka-logging\n//! ```\n\nuse axum::{\n    body::Bytes,\n    extract::MatchedPath,\n    http::{HeaderMap, Request},\n    response::{Html, Response},\n    routing::get,\n    Router,\n};\nuse std::time::Duration;\nuse tokio::net::TcpListener;\nuse tower_http::{classify::ServerErrorsFailureClass, trace::TraceLayer};\nuse tracing::{info_span, Span};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                // axum logs rejections from built-in extractors with the `axum::rejection`\n                // target, at `TRACE` level. `axum::rejection=trace` enables showing those events\n                format!(\n                    \"{}=debug,tower_http=debug,axum::rejection=trace\",\n                    env!(\"CARGO_CRATE_NAME\")\n                )\n                .into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with a route\n    let app = Router::new()\n        .route(\"/\", get(handler))\n        // `TraceLayer` is provided by tower-http so you have to add that as a dependency.\n        // It provides good defaults but is also very customizable.\n        //\n        // See https://docs.rs/tower-http/0.1.1/tower_http/trace/index.html for more details.\n        //\n        // If you want to customize the behavior using closures here is how.\n        .layer(\n            TraceLayer::new_for_http()\n                .make_span_with(|request: &Request<_>| {\n                    // Log the matched route's path (with placeholders not filled in).\n                    // Use request.uri() or OriginalUri if you want the real path.\n                    let matched_path = request\n                        .extensions()\n                        .get::<MatchedPath>()\n                        .map(MatchedPath::as_str);\n\n                    info_span!(\n                        \"http_request\",\n                        method = ?request.method(),\n                        matched_path,\n                        some_other_field = tracing::field::Empty,\n                    )\n                })\n                .on_request(|_request: &Request<_>, _span: &Span| {\n                    // You can use `_span.record(\"some_other_field\", value)` in one of these\n                    // closures to attach a value to the initially empty field in the info_span\n                    // created above.\n                })\n                .on_response(|_response: &Response, _latency: Duration, _span: &Span| {\n                    // ...\n                })\n                .on_body_chunk(|_chunk: &Bytes, _latency: Duration, _span: &Span| {\n                    // ...\n                })\n                .on_eos(\n                    |_trailers: Option<&HeaderMap>, _stream_duration: Duration, _span: &Span| {\n                        // ...\n                    },\n                )\n                .on_failure(\n                    |_error: ServerErrorsFailureClass, _latency: Duration, _span: &Span| {\n                        // ...\n                    },\n                ),\n        );\n\n    // run it\n    let listener = TcpListener::bind(\"127.0.0.1:3000\").await.unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nasync fn handler() -> Html<&'static str> {\n    Html(\"<h1>Hello, World!</h1>\")\n}\n"
  },
  {
    "path": "examples/unix-domain-socket/Cargo.toml",
    "content": "[package]\nname = \"example-unix-domain-socket\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\nhttp-body-util = \"0.1\"\nhyper = { version = \"1.0.0\", features = [\"full\"] }\nhyper-util = { version = \"0.1\", features = [\"tokio\", \"server-auto\", \"http1\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/unix-domain-socket/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-unix-domain-socket\n//! ```\n#[cfg(unix)]\n#[tokio::main]\nasync fn main() {\n    unix::server().await;\n}\n\n#[cfg(not(unix))]\nfn main() {\n    println!(\"This example requires unix\")\n}\n\n#[cfg(unix)]\nmod unix {\n    use axum::{\n        body::Body,\n        extract::connect_info::{self, ConnectInfo},\n        http::{Request, StatusCode},\n        routing::get,\n        serve::IncomingStream,\n        Router,\n    };\n    use http_body_util::BodyExt;\n    use hyper_util::rt::TokioIo;\n    use std::{path::PathBuf, sync::Arc};\n    use tokio::net::{unix::UCred, UnixListener, UnixStream};\n    use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n    pub async fn server() {\n        tracing_subscriber::registry()\n            .with(\n                tracing_subscriber::EnvFilter::try_from_default_env()\n                    .unwrap_or_else(|_| \"debug\".into()),\n            )\n            .with(tracing_subscriber::fmt::layer())\n            .init();\n\n        let path = PathBuf::from(\"/tmp/axum/helloworld\");\n\n        let _ = tokio::fs::remove_file(&path).await;\n        tokio::fs::create_dir_all(path.parent().unwrap())\n            .await\n            .unwrap();\n\n        let uds = UnixListener::bind(path.clone()).unwrap();\n        tokio::spawn(async move {\n            let app = Router::new()\n                .route(\"/\", get(handler))\n                .into_make_service_with_connect_info::<UdsConnectInfo>();\n\n            axum::serve(uds, app).await;\n        });\n\n        let stream = TokioIo::new(UnixStream::connect(path).await.unwrap());\n        let (mut sender, conn) = hyper::client::conn::http1::handshake(stream).await.unwrap();\n        tokio::task::spawn(async move {\n            if let Err(err) = conn.await {\n                println!(\"Connection failed: {err:?}\");\n            }\n        });\n\n        let request = Request::get(\"http://uri-doesnt-matter.com\")\n            .body(Body::empty())\n            .unwrap();\n\n        let response = sender.send_request(request).await.unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n\n        let body = response.collect().await.unwrap().to_bytes();\n        let body = String::from_utf8(body.to_vec()).unwrap();\n        assert_eq!(body, \"Hello, World!\");\n    }\n\n    async fn handler(ConnectInfo(info): ConnectInfo<UdsConnectInfo>) -> &'static str {\n        println!(\"new connection from `{info:?}`\");\n\n        \"Hello, World!\"\n    }\n\n    #[derive(Clone, Debug)]\n    #[allow(dead_code)]\n    struct UdsConnectInfo {\n        peer_addr: Arc<tokio::net::unix::SocketAddr>,\n        peer_cred: UCred,\n    }\n\n    impl connect_info::Connected<IncomingStream<'_, UnixListener>> for UdsConnectInfo {\n        fn connect_info(stream: IncomingStream<'_, UnixListener>) -> Self {\n            let peer_addr = stream.io().peer_addr().unwrap();\n            let peer_cred = stream.io().peer_cred().unwrap();\n            Self {\n                peer_addr: Arc::new(peer_addr),\n                peer_cred,\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/validator/Cargo.toml",
    "content": "[package]\nedition = \"2021\"\nname = \"example-validator\"\npublish = false\nversion = \"0.1.0\"\n\n[dependencies]\naxum = { path = \"../../axum\" }\nserde = { version = \"1.0\", features = [\"derive\"] }\nthiserror = \"2\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\nvalidator = { version = \"0.20.0\", features = [\"derive\"] }\n\n[dev-dependencies]\nhttp-body-util = \"0.1.0\"\ntower = { version = \"0.5.2\", features = [\"util\"] }\n"
  },
  {
    "path": "examples/validator/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-validator\n//!\n//! curl '127.0.0.1:3000?name='\n//! -> Input validation error: [name: Can not be empty]\n//!\n//! curl '127.0.0.1:3000?name=LT'\n//! -> <h1>Hello, LT!</h1>\n//! ```\n\nuse axum::{\n    extract::{rejection::FormRejection, Form, FromRequest, Request},\n    http::StatusCode,\n    response::{Html, IntoResponse, Response},\n    routing::get,\n    Router,\n};\nuse serde::{de::DeserializeOwned, Deserialize};\nuse thiserror::Error;\nuse tokio::net::TcpListener;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\nuse validator::Validate;\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with a route\n    let app = app();\n\n    // run it\n    let listener = TcpListener::bind(\"127.0.0.1:3000\").await.unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nfn app() -> Router {\n    Router::new().route(\"/\", get(handler))\n}\n\n#[derive(Debug, Deserialize, Validate)]\npub struct NameInput {\n    #[validate(length(min = 2, message = \"Can not be empty\"))]\n    pub name: String,\n}\n\nasync fn handler(ValidatedForm(input): ValidatedForm<NameInput>) -> Html<String> {\n    Html(format!(\"<h1>Hello, {}!</h1>\", input.name))\n}\n\n#[derive(Debug, Clone, Copy, Default)]\npub struct ValidatedForm<T>(pub T);\n\nimpl<T, S> FromRequest<S> for ValidatedForm<T>\nwhere\n    T: DeserializeOwned + Validate,\n    S: Send + Sync,\n    Form<T>: FromRequest<S, Rejection = FormRejection>,\n{\n    type Rejection = ServerError;\n\n    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {\n        let Form(value) = Form::<T>::from_request(req, state).await?;\n        value.validate()?;\n        Ok(ValidatedForm(value))\n    }\n}\n\n#[derive(Debug, Error)]\npub enum ServerError {\n    #[error(transparent)]\n    ValidationError(#[from] validator::ValidationErrors),\n\n    #[error(transparent)]\n    AxumFormRejection(#[from] FormRejection),\n}\n\nimpl IntoResponse for ServerError {\n    fn into_response(self) -> Response {\n        match self {\n            ServerError::ValidationError(_) => {\n                let message = format!(\"Input validation error: [{self}]\").replace('\\n', \", \");\n                (StatusCode::BAD_REQUEST, message)\n            }\n            ServerError::AxumFormRejection(_) => (StatusCode::BAD_REQUEST, self.to_string()),\n        }\n        .into_response()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{\n        body::Body,\n        http::{Request, StatusCode},\n    };\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    async fn get_html(response: Response<Body>) -> String {\n        let body = response.into_body();\n        let bytes = body.collect().await.unwrap().to_bytes();\n        String::from_utf8(bytes.to_vec()).unwrap()\n    }\n\n    #[tokio::test]\n    async fn test_no_param() {\n        let response = app()\n            .oneshot(Request::get(\"/\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::BAD_REQUEST);\n        let html = get_html(response).await;\n        assert_eq!(html, \"Failed to deserialize form: missing field `name`\");\n    }\n\n    #[tokio::test]\n    async fn test_with_param_without_value() {\n        let response = app()\n            .oneshot(Request::get(\"/?name=\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::BAD_REQUEST);\n        let html = get_html(response).await;\n        assert_eq!(html, \"Input validation error: [name: Can not be empty]\");\n    }\n\n    #[tokio::test]\n    async fn test_with_param_with_short_value() {\n        let response = app()\n            .oneshot(Request::get(\"/?name=X\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::BAD_REQUEST);\n        let html = get_html(response).await;\n        assert_eq!(html, \"Input validation error: [name: Can not be empty]\");\n    }\n\n    #[tokio::test]\n    async fn test_with_param_and_value() {\n        let response = app()\n            .oneshot(Request::get(\"/?name=LT\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n        let html = get_html(response).await;\n        assert_eq!(html, \"<h1>Hello, LT!</h1>\");\n    }\n}\n"
  },
  {
    "path": "examples/versioning/Cargo.toml",
    "content": "[package]\nname = \"example-versioning\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\" }\ntokio = { version = \"1.0\", features = [\"full\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\n[dev-dependencies]\nhttp-body-util = \"0.1.0\"\ntower = { version = \"0.5.2\", features = [\"util\"] }\n"
  },
  {
    "path": "examples/versioning/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-versioning\n//! ```\n\nuse axum::{\n    extract::{FromRequestParts, Path},\n    http::{request::Parts, StatusCode},\n    response::{Html, IntoResponse, Response},\n    routing::get,\n    RequestPartsExt, Router,\n};\nuse std::collections::HashMap;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    // build our application with some routes\n    let app = app();\n\n    // run it\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(listener, app).await;\n}\n\nfn app() -> Router {\n    Router::new().route(\"/{version}/foo\", get(handler))\n}\n\nasync fn handler(version: Version) -> Html<String> {\n    Html(format!(\"received request with version {version:?}\"))\n}\n\n#[derive(Debug)]\nenum Version {\n    V1,\n    V2,\n    V3,\n}\n\nimpl<S> FromRequestParts<S> for Version\nwhere\n    S: Send + Sync,\n{\n    type Rejection = Response;\n\n    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {\n        let params: Path<HashMap<String, String>> =\n            parts.extract().await.map_err(IntoResponse::into_response)?;\n\n        let version = params\n            .get(\"version\")\n            .ok_or_else(|| (StatusCode::NOT_FOUND, \"version param missing\").into_response())?;\n\n        match version.as_str() {\n            \"v1\" => Ok(Version::V1),\n            \"v2\" => Ok(Version::V2),\n            \"v3\" => Ok(Version::V3),\n            _ => Err((StatusCode::NOT_FOUND, \"unknown version\").into_response()),\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use axum::{body::Body, http::Request, http::StatusCode};\n    use http_body_util::BodyExt;\n    use tower::ServiceExt;\n\n    #[tokio::test]\n    async fn test_v1() {\n        let response = app()\n            .oneshot(Request::get(\"/v1/foo\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::OK);\n        let body = response.into_body();\n        let bytes = body.collect().await.unwrap().to_bytes();\n        let html = String::from_utf8(bytes.to_vec()).unwrap();\n\n        assert_eq!(html, \"received request with version V1\");\n    }\n\n    #[tokio::test]\n    async fn test_v4() {\n        let response = app()\n            .oneshot(Request::get(\"/v4/foo\").body(Body::empty()).unwrap())\n            .await\n            .unwrap();\n\n        assert_eq!(response.status(), StatusCode::NOT_FOUND);\n        let body = response.into_body();\n        let bytes = body.collect().await.unwrap().to_bytes();\n        let html = String::from_utf8(bytes.to_vec()).unwrap();\n\n        assert_eq!(html, \"unknown version\");\n    }\n}\n"
  },
  {
    "path": "examples/websockets/Cargo.toml",
    "content": "[package]\nname = \"example-websockets\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[[bin]]\nname = \"example-websockets\"\npath = \"src/main.rs\"\n\n[[bin]]\nname = \"example-client\"\npath = \"src/client.rs\"\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"ws\"] }\naxum-extra = { path = \"../../axum-extra\", features = [\"typed-header\"] }\nfutures-util = { version = \"0.3\", default-features = false, features = [\"sink\", \"std\"] }\nheaders = \"0.4\"\ntokio = { version = \"1.0\", features = [\"full\"] }\ntokio-tungstenite = \"0.29.0\"\ntower-http = { version = \"0.6.1\", features = [\"fs\", \"trace\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/websockets/assets/index.html",
    "content": "<a>Open the console to see stuff, then refresh to initiate exchange.</a>\n<script src='script.js'></script>\n"
  },
  {
    "path": "examples/websockets/assets/script.js",
    "content": "const socket = new WebSocket('ws://localhost:3000/ws');\n\nsocket.addEventListener('open', function (event) {\n    socket.send('Hello Server!');\n});\n\nsocket.addEventListener('message', function (event) {\n    console.log('Message from server ', event.data);\n});\n\n\nsetTimeout(() => {\n    const obj = { hello: \"world\" };\n    const blob = new Blob([JSON.stringify(obj, null, 2)], {\n      type: \"application/json\",\n    });\n    console.log(\"Sending blob over websocket\");\n    socket.send(blob);\n}, 1000);\n\nsetTimeout(() => {\n    socket.send('About done here...');\n    console.log(\"Sending close over websocket\");\n    socket.close(3000, \"Crash and Burn!\");\n}, 3000);"
  },
  {
    "path": "examples/websockets/src/client.rs",
    "content": "//! Based on tokio-tungstenite example websocket client, but with multiple\n//! concurrent websocket clients in one package\n//!\n//! This will connect to a server specified in the SERVER with N_CLIENTS\n//! concurrent connections, and then flood some test messages over websocket.\n//! This will also print whatever it gets into stdout.\n//!\n//! Note that this is not currently optimized for performance, especially around\n//! stdout mutex management. Rather it's intended to show an example of working with axum's\n//! websocket server and how the client-side and server-side code can be quite similar.\n//!\n\nuse futures_util::{SinkExt, StreamExt};\nuse std::ops::ControlFlow;\nuse std::time::Instant;\nuse tokio::task::JoinSet;\nuse tokio_tungstenite::tungstenite::Utf8Bytes;\n\n// we will use tungstenite for websocket client impl (same library as what axum is using)\nuse tokio_tungstenite::{\n    connect_async,\n    tungstenite::protocol::{frame::coding::CloseCode, CloseFrame, Message},\n};\n\nconst N_CLIENTS: usize = 2; //set to desired number\nconst SERVER: &str = \"ws://127.0.0.1:3000/ws\";\n\n#[tokio::main]\nasync fn main() {\n    let start_time = Instant::now();\n    //spawn several clients that will concurrently talk to the server\n    let mut clients = (0..N_CLIENTS).map(spawn_client).collect::<JoinSet<_>>();\n\n    //wait for all our clients to exit\n    while clients.join_next().await.is_some() {}\n\n    let end_time = Instant::now();\n\n    //total time should be the same no matter how many clients we spawn\n    println!(\n        \"Total time taken {:#?} with {N_CLIENTS} concurrent clients, should be about 6.45 seconds.\",\n        end_time - start_time\n    );\n}\n\n//creates a client. quietly exits on failure.\nasync fn spawn_client(who: usize) {\n    let ws_stream = match connect_async(SERVER).await {\n        Ok((stream, response)) => {\n            println!(\"Handshake for client {who} has been completed\");\n            // This will be the HTTP response, same as with server this is the last moment we\n            // can still access HTTP stuff.\n            println!(\"Server response was {response:?}\");\n            stream\n        }\n        Err(e) => {\n            println!(\"WebSocket handshake for client {who} failed with {e}!\");\n            return;\n        }\n    };\n\n    let (mut sender, mut receiver) = ws_stream.split();\n\n    //we can ping the server for start\n    sender\n        .send(Message::Ping(axum::body::Bytes::from_static(\n            b\"Hello, Server!\",\n        )))\n        .await\n        .expect(\"Can not send!\");\n\n    //spawn an async sender to push some more messages into the server\n    let mut send_task = tokio::spawn(async move {\n        for i in 1..30 {\n            // In any websocket error, break loop.\n            if sender\n                .send(Message::Text(format!(\"Message number {i}...\").into()))\n                .await\n                .is_err()\n            {\n                //just as with server, if send fails there is nothing we can do but exit.\n                return;\n            }\n\n            tokio::time::sleep(std::time::Duration::from_millis(300)).await;\n        }\n\n        // When we are done we may want our client to close connection cleanly.\n        println!(\"Sending close to {who}...\");\n        if let Err(e) = sender\n            .send(Message::Close(Some(CloseFrame {\n                code: CloseCode::Normal,\n                reason: Utf8Bytes::from_static(\"Goodbye\"),\n            })))\n            .await\n        {\n            println!(\"Could not send Close due to {e:?}, probably it is ok?\");\n        };\n    });\n\n    //receiver just prints whatever it gets\n    let mut recv_task = tokio::spawn(async move {\n        while let Some(Ok(msg)) = receiver.next().await {\n            // print message and break if instructed to do so\n            if process_message(msg, who).is_break() {\n                break;\n            }\n        }\n    });\n\n    //wait for either task to finish and kill the other task\n    tokio::select! {\n        _ = (&mut send_task) => {\n            recv_task.abort();\n        },\n        _ = (&mut recv_task) => {\n            send_task.abort();\n        }\n    }\n}\n\n/// Function to handle messages we get (with a slight twist that Frame variant is visible\n/// since we are working with the underlying tungstenite library directly without axum here).\nfn process_message(msg: Message, who: usize) -> ControlFlow<(), ()> {\n    match msg {\n        Message::Text(t) => {\n            println!(\">>> {who} got str: {t:?}\");\n        }\n        Message::Binary(d) => {\n            println!(\">>> {who} got {} bytes: {d:?}\", d.len());\n        }\n        Message::Close(c) => {\n            if let Some(cf) = c {\n                println!(\n                    \">>> {who} got close with code {} and reason `{}`\",\n                    cf.code, cf.reason\n                );\n            } else {\n                println!(\">>> {who} somehow got close message without CloseFrame\");\n            }\n            return ControlFlow::Break(());\n        }\n\n        Message::Pong(v) => {\n            println!(\">>> {who} got pong with {v:?}\");\n        }\n        // Just as with axum server, the underlying tungstenite websocket library\n        // will handle Ping for you automagically by replying with Pong and copying the\n        // v according to spec. But if you need the contents of the pings you can see them here.\n        Message::Ping(v) => {\n            println!(\">>> {who} got ping with {v:?}\");\n        }\n\n        Message::Frame(_) => {\n            unreachable!(\"This is never supposed to happen\")\n        }\n    }\n    ControlFlow::Continue(())\n}\n"
  },
  {
    "path": "examples/websockets/src/main.rs",
    "content": "//! Example websocket server.\n//!\n//! Run the server with\n//! ```not_rust\n//! cargo run -p example-websockets --bin example-websockets\n//! ```\n//!\n//! Run a browser client with\n//! ```not_rust\n//! firefox http://localhost:3000\n//! ```\n//!\n//! Alternatively you can run the rust client (showing two\n//! concurrent websocket connections being established) with\n//! ```not_rust\n//! cargo run -p example-websockets --bin example-client\n//! ```\n\nuse axum::{\n    body::Bytes,\n    extract::ws::{Message, Utf8Bytes, WebSocket, WebSocketUpgrade},\n    response::IntoResponse,\n    routing::any,\n    Router,\n};\nuse axum_extra::TypedHeader;\n\nuse std::ops::ControlFlow;\nuse std::{net::SocketAddr, path::PathBuf};\nuse tower_http::{\n    services::ServeDir,\n    trace::{DefaultMakeSpan, TraceLayer},\n};\n\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n//allows to extract the IP of connecting user\nuse axum::extract::connect_info::ConnectInfo;\nuse axum::extract::ws::CloseFrame;\n\n//allows to split the websocket stream into separate TX and RX branches\nuse futures_util::{sink::SinkExt, stream::StreamExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {\n                format!(\"{}=debug,tower_http=debug\", env!(\"CARGO_CRATE_NAME\")).into()\n            }),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let assets_dir = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\")).join(\"assets\");\n\n    // build our application with some routes\n    let app = Router::new()\n        .fallback_service(ServeDir::new(assets_dir).append_index_html_on_directories(true))\n        .route(\"/ws\", any(ws_handler))\n        // logging so we can see what's going on\n        .layer(\n            TraceLayer::new_for_http()\n                .make_span_with(DefaultMakeSpan::default().include_headers(true)),\n        );\n\n    // run it with hyper\n    let listener = tokio::net::TcpListener::bind(\"127.0.0.1:3000\")\n        .await\n        .unwrap();\n    tracing::debug!(\"listening on {}\", listener.local_addr().unwrap());\n    axum::serve(\n        listener,\n        app.into_make_service_with_connect_info::<SocketAddr>(),\n    )\n    .await;\n}\n\n/// The handler for the HTTP request (this gets called when the HTTP request lands at the start\n/// of websocket negotiation). After this completes, the actual switching from HTTP to\n/// websocket protocol will occur.\n/// This is the last point where we can extract TCP/IP metadata such as IP address of the client\n/// as well as things from HTTP headers such as user-agent of the browser etc.\nasync fn ws_handler(\n    ws: WebSocketUpgrade,\n    user_agent: Option<TypedHeader<headers::UserAgent>>,\n    ConnectInfo(addr): ConnectInfo<SocketAddr>,\n) -> impl IntoResponse {\n    let user_agent = if let Some(TypedHeader(user_agent)) = user_agent {\n        user_agent.to_string()\n    } else {\n        String::from(\"Unknown browser\")\n    };\n    println!(\"`{user_agent}` at {addr} connected.\");\n    // finalize the upgrade process by returning upgrade callback.\n    // we can customize the callback by sending additional info such as address.\n    ws.on_upgrade(move |socket| handle_socket(socket, addr))\n}\n\n/// Actual websocket statemachine (one will be spawned per connection)\nasync fn handle_socket(mut socket: WebSocket, who: SocketAddr) {\n    // send a ping (unsupported by some browsers) just to kick things off and get a response\n    if socket\n        .send(Message::Ping(Bytes::from_static(&[1, 2, 3])))\n        .await\n        .is_ok()\n    {\n        println!(\"Pinged {who}...\");\n    } else {\n        println!(\"Could not send ping {who}!\");\n        // no Error here since the only thing we can do is to close the connection.\n        // If we can not send messages, there is no way to salvage the statemachine anyway.\n        return;\n    }\n\n    // receive single message from a client (we can either receive or send with socket).\n    // this will likely be the Pong for our Ping or a hello message from client.\n    // waiting for message from a client will block this task, but will not block other client's\n    // connections.\n    if let Some(msg) = socket.recv().await {\n        if let Ok(msg) = msg {\n            if process_message(msg, who).is_break() {\n                return;\n            }\n        } else {\n            println!(\"client {who} abruptly disconnected\");\n            return;\n        }\n    }\n\n    // Since each client gets individual statemachine, we can pause handling\n    // when necessary to wait for some external event (in this case illustrated by sleeping).\n    // Waiting for this client to finish getting its greetings does not prevent other clients from\n    // connecting to server and receiving their greetings.\n    for i in 1..5 {\n        if socket\n            .send(Message::Text(format!(\"Hi {i} times!\").into()))\n            .await\n            .is_err()\n        {\n            println!(\"client {who} abruptly disconnected\");\n            return;\n        }\n        tokio::time::sleep(std::time::Duration::from_millis(100)).await;\n    }\n\n    // By splitting socket we can send and receive at the same time. In this example we will send\n    // unsolicited messages to client based on some sort of server's internal event (i.e .timer).\n    let (mut sender, mut receiver) = socket.split();\n\n    // Spawn a task that will push several messages to the client (does not matter what client does)\n    let mut send_task = tokio::spawn(async move {\n        let n_msg = 20;\n        for i in 0..n_msg {\n            // In case of any websocket error, we exit.\n            if sender\n                .send(Message::Text(format!(\"Server message {i} ...\").into()))\n                .await\n                .is_err()\n            {\n                return i;\n            }\n\n            tokio::time::sleep(std::time::Duration::from_millis(300)).await;\n        }\n\n        println!(\"Sending close to {who}...\");\n        if let Err(e) = sender\n            .send(Message::Close(Some(CloseFrame {\n                code: axum::extract::ws::close_code::NORMAL,\n                reason: Utf8Bytes::from_static(\"Goodbye\"),\n            })))\n            .await\n        {\n            println!(\"Could not send Close due to {e}, probably it is ok?\");\n        }\n        n_msg\n    });\n\n    // This second task will receive messages from client and print them on server console\n    let mut recv_task = tokio::spawn(async move {\n        let mut cnt = 0;\n        while let Some(Ok(msg)) = receiver.next().await {\n            cnt += 1;\n            // print message and break if instructed to do so\n            if process_message(msg, who).is_break() {\n                break;\n            }\n        }\n        cnt\n    });\n\n    // If any one of the tasks exit, abort the other.\n    tokio::select! {\n        rv_a = (&mut send_task) => {\n            match rv_a {\n                Ok(a) => println!(\"{a} messages sent to {who}\"),\n                Err(a) => println!(\"Error sending messages {a:?}\")\n            }\n            recv_task.abort();\n        },\n        rv_b = (&mut recv_task) => {\n            match rv_b {\n                Ok(b) => println!(\"Received {b} messages\"),\n                Err(b) => println!(\"Error receiving messages {b:?}\")\n            }\n            send_task.abort();\n        }\n    }\n\n    // returning from the handler closes the websocket connection\n    println!(\"Websocket context {who} destroyed\");\n}\n\n/// helper to print contents of messages to stdout. Has special treatment for Close.\nfn process_message(msg: Message, who: SocketAddr) -> ControlFlow<(), ()> {\n    match msg {\n        Message::Text(t) => {\n            println!(\">>> {who} sent str: {t:?}\");\n        }\n        Message::Binary(d) => {\n            println!(\">>> {who} sent {} bytes: {d:?}\", d.len());\n        }\n        Message::Close(c) => {\n            if let Some(cf) = c {\n                println!(\n                    \">>> {who} sent close with code {} and reason `{}`\",\n                    cf.code, cf.reason\n                );\n            } else {\n                println!(\">>> {who} somehow sent close message without CloseFrame\");\n            }\n            return ControlFlow::Break(());\n        }\n\n        Message::Pong(v) => {\n            println!(\">>> {who} sent pong with {v:?}\");\n        }\n        // You should never need to manually handle Message::Ping, as axum's websocket library\n        // will do so for you automagically by replying with Pong and copying the v according to\n        // spec. But if you need the contents of the pings you can see them here.\n        Message::Ping(v) => {\n            println!(\">>> {who} sent ping with {v:?}\");\n        }\n    }\n    ControlFlow::Continue(())\n}\n"
  },
  {
    "path": "examples/websockets-http2/Cargo.toml",
    "content": "[package]\nname = \"example-websockets-http2\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[dependencies]\naxum = { path = \"../../axum\", features = [\"ws\", \"http2\"] }\naxum-server = { version = \"0.8\", features = [\"tls-rustls\"] }\ntokio = { version = \"1\", features = [\"full\"] }\ntower-http = { version = \"0.6\", features = [\"fs\"] }\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "examples/websockets-http2/assets/index.html",
    "content": "<p>Open this page in two windows and try sending some messages!</p>\n<form action=\"javascript:void(0)\">\n    <input type=\"text\" name=\"content\" required>\n    <button>Send</button>\n</form>\n<div id=\"messages\"></div>\n<script src='script.js'></script>\n"
  },
  {
    "path": "examples/websockets-http2/assets/script.js",
    "content": "const socket = new WebSocket('wss://localhost:3000/ws');\n\nsocket.addEventListener('message', e => {\n    document.getElementById(\"messages\").append(e.data, document.createElement(\"br\"));\n});\n\nconst form = document.querySelector(\"form\");\nform.addEventListener(\"submit\", () => {\n    socket.send(form.elements.namedItem(\"content\").value);\n    form.elements.namedItem(\"content\").value = \"\";\n});\n"
  },
  {
    "path": "examples/websockets-http2/self_signed_certs/cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDkzCCAnugAwIBAgIUXVYkRCrM/ge03DVymDtXCuybp7gwDQYJKoZIhvcNAQEL\nBQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\nGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X\nDTIxMDczMTE0MjIxMloXDTIyMDczMTE0MjIxMlowWTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\nIEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEA02V5ZjmqLB/VQwTarrz/35qsa83L+DbAoa0001+jVmmC+G9Nufi0\ndaroFWj/Uicv2fZWETU8JoZKUrX4BK9og5cg5rln/CtBRWCUYIwRgY9R/CdBGPn4\nkp+XkSJaCw74ZIyLy/Zfux6h8ES1m9YRnBza+s7U+ImRBRf4MRPtXQ3/mqJxAZYq\ndOnKnvssRyD2qutgVTAxwMUvJWIivRhRYDj7WOpS4CEEeQxP1iH1/T5P7FdtTGdT\nbVBABCA8JhL96uFGPpOYHcM/7R5EIA3yZ5FNg931QzoDITjtXGtQ6y9/l/IYkWm6\nJ67RWcN0IoTsZhz0WNU4gAeslVtJLofn8QIDAQABo1MwUTAdBgNVHQ4EFgQUzFnK\nNfS4LAYuKeWwHbzooER0yZ0wHwYDVR0jBBgwFoAUzFnKNfS4LAYuKeWwHbzooER0\nyZ0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAk4O+e9jia59W\nZwetN4GU7OWcYhmOgSizRSs6u7mTfp62LDMt96WKU3THksOnZ44HnqWQxsSfdFVU\nXJD12tjvVU8Z4FWzQajcHeemUYiDze8EAh6TnxnUcOrU8IcwiKGxCWRY/908jnWg\n+MMscfMCMYTRdeTPqD8fGzAlUCtmyzH6KLE3s4Oo/r5+NR+Uvrwpdvb7xe0MwwO9\nQ/zR4N8ep/HwHVEObcaBofE1ssZLksX7ZgCP9wMgXRWpNAtC5EWxMbxYjBfWFH24\nfDJlBMiGJWg8HHcxK7wQhFh+fuyNzE+xEWPsI9VL1zDftd9x8/QsOagyEOnY8Vxr\nAopvZ09uEQ==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "examples/websockets-http2/self_signed_certs/key.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTZXlmOaosH9VD\nBNquvP/fmqxrzcv4NsChrTTTX6NWaYL4b025+LR1qugVaP9SJy/Z9lYRNTwmhkpS\ntfgEr2iDlyDmuWf8K0FFYJRgjBGBj1H8J0EY+fiSn5eRIloLDvhkjIvL9l+7HqHw\nRLWb1hGcHNr6ztT4iZEFF/gxE+1dDf+aonEBlip06cqe+yxHIPaq62BVMDHAxS8l\nYiK9GFFgOPtY6lLgIQR5DE/WIfX9Pk/sV21MZ1NtUEAEIDwmEv3q4UY+k5gdwz/t\nHkQgDfJnkU2D3fVDOgMhOO1ca1DrL3+X8hiRabonrtFZw3QihOxmHPRY1TiAB6yV\nW0kuh+fxAgMBAAECggEADltu8k1qTFLhJgsXWxTFAAe+PBgfCT2WuaRM2So+qqjB\n12Of0MieYPt5hbK63HaC3nfHgqWt7yPhulpXfOH45C8IcgMXl93MMg0MJr58leMI\n+2ojFrIrerHSFm5R1TxwDEwrVm/mMowzDWFtQCc6zPJ8wNn5RuP48HKfTZ3/2fjw\nzEjSwPO2wFMfo1EJNTjlI303lFbdFBs67NaX6puh30M7Tn+gznHKyO5a7F57wkIt\nfkgnEy/sgMedQlwX7bRpUoD6f0fZzV8Qz4cHFywtYErczZJh3VGitJoO/VCIDdty\nRPXOAqVDd7EpP1UUehZlKVWZ0OZMEfRgKbRCel5abQKBgQDwgwrIQ5+BiZv6a0VT\nETeXB+hRbvBinRykNo/RvLc3j1enRh9/zO/ShadZIXgOAiM1Jnr5Gp8KkNGca6K1\nmyhtad7xYPODYzNXXp6T1OPgZxHZLIYzVUj6ypXeV64Te5ZiDaJ1D49czsq+PqsQ\nXRcgBJSNpFtDFiXWpjXWfx8PxwKBgQDhAnLY5Sl2eeQo+ud0MvjwftB/mN2qCzJY\n5AlQpRI4ThWxJgGPuHTR29zVa5iWNYuA5LWrC1y/wx+t5HKUwq+5kxvs+npYpDJD\nZX/w0Glc6s0Jc/mFySkbw9B2LePedL7lRF5OiAyC6D106Sc9V2jlL4IflmOzt4CD\nZTNbLtC6hwKBgHfIzBXxl/9sCcMuqdg1Ovp9dbcZCaATn7ApfHd5BccmHQGyav27\nk7XF2xMJGEHhzqcqAxUNrSgV+E9vTBomrHvRvrd5Ec7eGTPqbBA0d0nMC5eeFTh7\nwV0miH20LX6Gjt9G6yJiHYSbeV5G1+vOcTYBEft5X/qJjU7aePXbWh0BAoGBAJlV\n5tgCCuhvFloK6fHYzqZtdT6O+PfpW20SMXrgkvMF22h2YvgDFrDwqKRUB47NfHzg\n3yBpxNH1ccA5/w97QO8w3gX3h6qicpJVOAPusu6cIBACFZfjRv1hyszOZwvw+Soa\nFj5kHkqTY1YpkREPYS9V2dIW1Wjic1SXgZDw7VM/AoGAP/cZ3ZHTSCDTFlItqy5C\nrIy2AiY0WJsx+K0qcvtosPOOwtnGjWHb1gdaVdfX/IRkSsX4PAOdnsyidNC5/l/m\ny8oa+5WEeGFclWFhr4dnTA766o8HrM2UjIgWWYBF2VKdptGnHxFeJWFUmeQC/xeW\nw37pCS7ykL+7gp7V0WShYsw=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "examples/websockets-http2/src/main.rs",
    "content": "//! Run with\n//!\n//! ```not_rust\n//! cargo run -p example-websockets-http2\n//! ```\n\nuse axum::{\n    extract::{\n        ws::{self, WebSocketUpgrade},\n        State,\n    },\n    http::Version,\n    routing::any,\n    Router,\n};\nuse axum_server::tls_rustls::RustlsConfig;\nuse std::{net::SocketAddr, path::PathBuf};\nuse tokio::sync::broadcast;\nuse tower_http::services::ServeDir;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n#[tokio::main]\nasync fn main() {\n    tracing_subscriber::registry()\n        .with(\n            tracing_subscriber::EnvFilter::try_from_default_env()\n                .unwrap_or_else(|_| format!(\"{}=debug\", env!(\"CARGO_CRATE_NAME\")).into()),\n        )\n        .with(tracing_subscriber::fmt::layer())\n        .init();\n\n    let assets_dir = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\")).join(\"assets\");\n\n    // configure certificate and private key used by https\n    let config = RustlsConfig::from_pem_file(\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"cert.pem\"),\n        PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"self_signed_certs\")\n            .join(\"key.pem\"),\n    )\n    .await\n    .unwrap();\n\n    // build our application with some routes and a broadcast channel\n    let app = Router::new()\n        .fallback_service(ServeDir::new(assets_dir).append_index_html_on_directories(true))\n        .route(\"/ws\", any(ws_handler))\n        .with_state(broadcast::channel::<String>(16).0);\n\n    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));\n    tracing::debug!(\"listening on {}\", addr);\n\n    let mut server = axum_server::bind_rustls(addr, config);\n\n    // IMPORTANT: This is required to advertise our support for HTTP/2 websockets to the client.\n    // If you use axum::serve, it is enabled by default.\n    server.http_builder().http2().enable_connect_protocol();\n\n    server.serve(app.into_make_service()).await.unwrap();\n}\n\nasync fn ws_handler(\n    ws: WebSocketUpgrade,\n    version: Version,\n    State(sender): State<broadcast::Sender<String>>,\n) -> axum::response::Response {\n    tracing::debug!(\"accepted a WebSocket using {version:?}\");\n    let mut receiver = sender.subscribe();\n    ws.on_upgrade(|mut ws| async move {\n        loop {\n            tokio::select! {\n                // Since `ws` is a `Stream`, it is by nature cancel-safe.\n                res = ws.recv() => {\n                    match res {\n                        Some(Ok(ws::Message::Text(s))) => {\n                            let _ = sender.send(s.to_string());\n                        }\n                        Some(Ok(_)) => {}\n                        Some(Err(e)) => tracing::debug!(\"client disconnected abruptly: {e}\"),\n                        None => break,\n                    }\n                }\n                // Tokio guarantees that `broadcast::Receiver::recv` is cancel-safe.\n                res = receiver.recv() => {\n                    match res {\n                        Ok(msg) => if let Err(e) = ws.send(ws::Message::Text(msg.into())).await {\n                            tracing::debug!(\"client disconnected abruptly: {e}\");\n                        }\n                        Err(_) => continue,\n                    }\n                }\n            }\n        }\n    })\n}\n"
  }
]