├── .github ├── dependabot.yml └── workflows │ ├── ci.yml │ └── publish.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── codespan-lsp ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE └── src │ └── lib.rs ├── codespan-reporting ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── assets │ └── readme_preview.svg ├── examples │ ├── custom_files.rs │ ├── peg_calculator.rs │ ├── readme_preview.rs │ ├── reusable_diagnostic.rs │ └── term.rs ├── src │ ├── diagnostic.rs │ ├── files.rs │ ├── lib.rs │ ├── term.rs │ └── term │ │ ├── config.rs │ │ ├── renderer.rs │ │ └── views.rs └── tests │ ├── snapshots │ ├── term__empty__medium_color.snap │ ├── term__empty__medium_no_color.snap │ ├── term__empty__rich_ascii_no_color.snap │ ├── term__empty__rich_color.snap │ ├── term__empty__rich_no_color.snap │ ├── term__empty__short_color.snap │ ├── term__empty__short_no_color.snap │ ├── term__empty_ranges__medium_color.snap │ ├── term__empty_ranges__medium_no_color.snap │ ├── term__empty_ranges__rich_ascii_no_color.snap │ ├── term__empty_ranges__rich_color.snap │ ├── term__empty_ranges__rich_no_color.snap │ ├── term__empty_ranges__short_color.snap │ ├── term__empty_ranges__short_no_color.snap │ ├── term__fizz_buzz__medium_color.snap │ ├── term__fizz_buzz__medium_no_color.snap │ ├── term__fizz_buzz__rich_ascii_no_color.snap │ ├── term__fizz_buzz__rich_color.snap │ ├── term__fizz_buzz__rich_no_color.snap │ ├── term__fizz_buzz__short_color.snap │ ├── term__fizz_buzz__short_no_color.snap │ ├── term__message__medium_color.snap │ ├── term__message__medium_no_color.snap │ ├── term__message__rich_ascii_no_color.snap │ ├── term__message__rich_color.snap │ ├── term__message__rich_no_color.snap │ ├── term__message__short_color.snap │ ├── term__message__short_no_color.snap │ ├── term__message_and_notes__medium_color.snap │ ├── term__message_and_notes__medium_no_color.snap │ ├── term__message_and_notes__rich_ascii_no_color.snap │ ├── term__message_and_notes__rich_color.snap │ ├── term__message_and_notes__rich_no_color.snap │ ├── term__message_and_notes__short_color.snap │ ├── term__message_and_notes__short_no_color.snap │ ├── term__message_errorcode__rich_ascii_no_color.snap │ ├── term__message_errorcode__rich_no_color.snap │ ├── term__message_errorcode__short_no_color.snap │ ├── term__multifile__medium_color.snap │ ├── term__multifile__medium_no_color.snap │ ├── term__multifile__rich_ascii_no_color.snap │ ├── term__multifile__rich_color.snap │ ├── term__multifile__rich_no_color.snap │ ├── term__multifile__short_color.snap │ ├── term__multifile__short_no_color.snap │ ├── term__multiline_omit__rich_no_color.snap │ ├── term__multiline_overlapping__medium_color.snap │ ├── term__multiline_overlapping__medium_no_color.snap │ ├── term__multiline_overlapping__rich_ascii_no_color.snap │ ├── term__multiline_overlapping__rich_color.snap │ ├── term__multiline_overlapping__rich_no_color.snap │ ├── term__multiline_overlapping__short_color.snap │ ├── term__multiline_overlapping__short_no_color.snap │ ├── term__overlapping__medium_color.snap │ ├── term__overlapping__medium_no_color.snap │ ├── term__overlapping__rich_ascii_no_color.snap │ ├── term__overlapping__rich_color.snap │ ├── term__overlapping__rich_no_color.snap │ ├── term__overlapping__short_color.snap │ ├── term__overlapping__short_no_color.snap │ ├── term__position_indicator__medium_no_color.snap │ ├── term__position_indicator__rich_ascii_no_color.snap │ ├── term__position_indicator__rich_no_color.snap │ ├── term__position_indicator__short_no_color.snap │ ├── term__same_line__medium_color.snap │ ├── term__same_line__medium_no_color.snap │ ├── term__same_line__rich_ascii_no_color.snap │ ├── term__same_line__rich_color.snap │ ├── term__same_line__rich_no_color.snap │ ├── term__same_line__short_color.snap │ ├── term__same_line__short_no_color.snap │ ├── term__same_ranges__medium_color.snap │ ├── term__same_ranges__medium_no_color.snap │ ├── term__same_ranges__rich_ascii_no_color.snap │ ├── term__same_ranges__rich_color.snap │ ├── term__same_ranges__rich_no_color.snap │ ├── term__same_ranges__short_color.snap │ ├── term__same_ranges__short_no_color.snap │ ├── term__surrounding_lines__rich_no_color.snap │ ├── term__tab_columns__tab_width_2_no_color.snap │ ├── term__tab_columns__tab_width_3_no_color.snap │ ├── term__tab_columns__tab_width_6_no_color.snap │ ├── term__tab_columns__tab_width_default_no_color.snap │ ├── term__tabbed__tab_width_3_no_color.snap │ ├── term__tabbed__tab_width_6_no_color.snap │ ├── term__tabbed__tab_width_default_no_color.snap │ ├── term__unicode__medium_no_color.snap │ ├── term__unicode__rich_no_color.snap │ ├── term__unicode__short_no_color.snap │ ├── term__unicode_spans__medium_no_color.snap │ ├── term__unicode_spans__rich_no_color.snap │ └── term__unicode_spans__short_no_color.snap │ ├── support │ ├── color_buffer.rs │ └── mod.rs │ └── term.rs └── codespan ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src ├── file.rs ├── index.rs ├── lib.rs ├── location.rs └── span.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "19:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: rustyline 11 | versions: 12 | - "> 6" 13 | - dependency-name: insta 14 | versions: 15 | - 1.5.3 16 | - 1.6.0 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | pull_request: 9 | branches: 10 | - master 11 | 12 | jobs: 13 | check: 14 | runs-on: ubuntu-20.04 15 | strategy: 16 | matrix: 17 | rust: ["1.67.0", "stable", "beta", "nightly"] 18 | name: Check (${{ matrix.rust }}) 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Install minimal ${{ matrix.rust }} 22 | uses: actions-rs/toolchain@v1 23 | with: 24 | profile: minimal 25 | toolchain: ${{ matrix.rust }} 26 | override: true 27 | # Check each crate individually to work around rust-lang/cargo#4942 28 | - name: Run cargo check for codespan-reporting 29 | uses: actions-rs/cargo@v1 30 | with: 31 | command: check 32 | args: --manifest-path "codespan-reporting/Cargo.toml" --features "serialization" 33 | - name: Run cargo check for codespan 34 | uses: actions-rs/cargo@v1 35 | with: 36 | command: check 37 | args: --manifest-path "codespan/Cargo.toml" --features "serialization" 38 | - name: Run cargo check for codespan-lsp 39 | uses: actions-rs/cargo@v1 40 | with: 41 | command: check 42 | args: --manifest-path "codespan-lsp/Cargo.toml" 43 | - name: Switch to minimal lsp-types version for codespan-lsp 44 | uses: actions-rs/cargo@v1 45 | with: 46 | command: update 47 | # NOTE: Keep up to date with the minimum version of `lsp-types` 48 | # specified in `codespan-lsp/Cargo.toml` 49 | args: --precise 0.84.0 -p lsp-types 50 | - name: Run cargo test for codespan-lsp 51 | uses: actions-rs/cargo@v1 52 | with: 53 | command: check 54 | args: --manifest-path "codespan-lsp/Cargo.toml" 55 | 56 | check-no-std: 57 | name: Check 58 | runs-on: ubuntu-latest 59 | strategy: 60 | fail-fast: false 61 | matrix: 62 | rust: 63 | - "1.84.0" 64 | - "stable" 65 | - "beta" 66 | - "nightly" 67 | target: 68 | - "x86_64-unknown-none" 69 | - "wasm32v1-none" 70 | - "thumbv6m-none-eabi" 71 | steps: 72 | - uses: actions/checkout@v4 73 | - uses: dtolnay/rust-toolchain@stable 74 | with: 75 | toolchain: ${{ matrix.rust }} 76 | targets: ${{ matrix.target }} 77 | - name: Run cargo check for codespan-reporting 78 | uses: actions-rs/cargo@v1 79 | with: 80 | command: check 81 | args: --manifest-path "codespan-reporting/Cargo.toml" --no-default-features --features "serialization" --target ${{ matrix.target }} 82 | - name: Run cargo check for codespan 83 | uses: actions-rs/cargo@v1 84 | with: 85 | command: check 86 | args: --manifest-path "codespan/Cargo.toml" --no-default-features --features "serialization" --target ${{ matrix.target }} 87 | 88 | test: 89 | runs-on: ubuntu-20.04 90 | strategy: 91 | matrix: 92 | rust: ["1.67.0", "stable", "beta", "nightly"] 93 | fail-fast: false 94 | name: Test Suite (${{ matrix.rust }}) 95 | steps: 96 | - uses: actions/checkout@v2 97 | - name: Install minimal ${{ matrix.rust }} 98 | uses: actions-rs/toolchain@v1 99 | with: 100 | profile: minimal 101 | toolchain: ${{ matrix.rust }} 102 | override: true 103 | # Test each crate individually to work around rust-lang/cargo#4942 104 | - name: Run cargo test for codespan-reporting 105 | uses: actions-rs/cargo@v1 106 | with: 107 | command: test 108 | args: --manifest-path "codespan-reporting/Cargo.toml" --features "serialization" 109 | - name: Run cargo test for codespan 110 | uses: actions-rs/cargo@v1 111 | with: 112 | command: test 113 | args: --manifest-path "codespan/Cargo.toml" --features "serialization" 114 | - name: Switch to minimal lsp-types version for codespan-lsp 115 | uses: actions-rs/cargo@v1 116 | with: 117 | command: update 118 | # NOTE: Keep up to date with the minimum version of `lsp-types` 119 | # specified in `codespan-lsp/Cargo.toml` 120 | args: --precise 0.84.0 lsp-types 121 | - name: Run cargo test for codespan-lsp 122 | uses: actions-rs/cargo@v1 123 | with: 124 | command: test 125 | args: --manifest-path "codespan-lsp/Cargo.toml" 126 | 127 | fmt: 128 | runs-on: ubuntu-20.04 129 | strategy: 130 | matrix: 131 | rust: ["1.67.0", "stable", "beta", "nightly"] 132 | fail-fast: false 133 | name: Rustfmt (${{ matrix.rust }}) 134 | steps: 135 | - uses: actions/checkout@v2 136 | - name: Install minimal ${{ matrix.rust }} with rustfmt 137 | uses: actions-rs/toolchain@v1 138 | with: 139 | profile: minimal 140 | toolchain: ${{ matrix.rust }} 141 | override: true 142 | components: rustfmt 143 | - name: Run cargo fmt 144 | uses: actions-rs/cargo@v1 145 | with: 146 | command: fmt 147 | args: --all -- --check 148 | 149 | lint: 150 | runs-on: ubuntu-20.04 151 | strategy: 152 | matrix: 153 | rust: ["stable"] 154 | fail-fast: false 155 | name: Rustfmt (${{ matrix.rust }}) 156 | steps: 157 | - uses: actions/checkout@v2 158 | - name: Install minimal ${{ matrix.rust }} with rustfmt 159 | uses: actions-rs/toolchain@v1 160 | with: 161 | profile: minimal 162 | toolchain: ${{ matrix.rust }} 163 | override: true 164 | components: rustfmt 165 | - name: Run cargo clippy 166 | uses: actions-rs/cargo@v1 167 | with: 168 | command: clippy 169 | args: --all 170 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish crates on crates.io 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: "major/minor/patch or semver" 8 | required: false 9 | default: "patch" 10 | lsp-version: 11 | description: "major/minor/patch or semver for codespan-lsp crate (or none if not releasing derive crate)" 12 | required: false 13 | default: "none" 14 | reporting-version: 15 | description: "major/minor/patch or semver for codespan-reporting crate (or none if not releasing derive crate)" 16 | required: false 17 | default: "none" 18 | 19 | jobs: 20 | publish: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set git credentials 25 | run: | 26 | git config user.name github-actions 27 | git config user.email github-actions@github.com 28 | 29 | - name: Crates publish 30 | uses: kaleidawave/crates-release-gh-action@main 31 | id: release 32 | with: 33 | version: | 34 | { 35 | "codespan": "${{ github.event.inputs.version }}", 36 | "codespan-reporting": "${{ github.event.inputs.lsp-version }}", 37 | "codespan-lsp": "${{ github.event.inputs.reporting-version }}" 38 | } 39 | crates-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} 40 | 41 | - name: Push updated Cargo.toml 42 | run: | 43 | git add . 44 | git commit -m "Release: ${{ steps.release.outputs.new-versions-description }}" 45 | echo '${{ steps.release.outputs.new-versions }}' | jq -r '.[]' | while read -r update; do 46 | git tag "release/$update" 47 | done 48 | git push --tags origin main -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, 6 | we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, 7 | regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 8 | 9 | ## Our Standards 10 | 11 | Examples of behavior that contributes to creating a positive environment include: 12 | 13 | * Using welcoming and inclusive language 14 | * Being respectful of differing viewpoints and experiences 15 | * Gracefully accepting constructive criticism 16 | * Focusing on what is best for the community 17 | * Showing empathy towards other community members 18 | 19 | Examples of unacceptable behavior by participants include: 20 | 21 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 22 | * Trolling, insulting/derogatory comments, and personal or political attacks 23 | * Public or private harassment 24 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 25 | * Other conduct which could reasonably be considered inappropriate in a professional setting 26 | 27 | ## Our Responsibilities 28 | 29 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 30 | 31 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, 32 | or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 33 | 34 | ## Scope 35 | 36 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. 37 | Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 38 | Representation of a project may be further defined and clarified by project maintainers. 39 | 40 | ## Enforcement 41 | 42 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a moderator on [#codespan:matrix.org](https://app.element.io/#/room/#codespan:matrix.org) using a "Direct message". 43 | The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. 44 | The project team is obligated to maintain confidentiality with regard to the reporter of an incident. 45 | Further details of specific enforcement policies may be posted separately. 46 | 47 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 48 | 49 | ## Attribution 50 | 51 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 52 | available at [http://contributor-covenant.org/version/1/4][version] 53 | 54 | [homepage]: http://contributor-covenant.org 55 | [version]: http://contributor-covenant.org/version/1/4/ 56 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Contents 4 | 5 | - [Introduction](#introduction) 6 | - [Code of Conduct](#code-of-conduct) 7 | - [Matrix Room](#matrix-room) 8 | - [Reporting Bugs and Suggesting Improvements](#reporting-bugs-and-suggesting-improvements) 9 | - [Contribution Workflow](#contribution-workflow) 10 | - [Quality Standards](#quality-standards) 11 | - [Release Process](#release-process) 12 | 13 | ## Introduction 14 | 15 | Hello, and welcome to the contributing guide for Codespan! 16 | 17 | Codespan is mostly maintained in the spare time of contributors, 18 | so immediate reactions are not to be expected! 19 | By following this guide you'll make it easier for us to address your issues or incorporate your contributions. 20 | 21 | We look forward to working with you! 22 | 23 | ## Code of Conduct 24 | 25 | Please note that this project is released with a [Code of Conduct](./CODE_OF_CONDUCT.md). 26 | By participating in this project you agree to abide by its terms. 27 | 28 | ## Matrix Room 29 | 30 | Joining the matrix room at [#codespan:matrix.org][codespan-matrix] is a good way to get in touch with the developers and community. 31 | 32 | [codespan-matrix]: https://app.element.io/#/room/#codespan:matrix.org 33 | 34 | ## Reporting Bugs and Suggesting Improvements 35 | 36 | Bugs (unwanted behaviour) and suggested improvements are tracked as [GitHub issues][github-issues]. 37 | Before reporting an issue, please check the following points: 38 | 39 | 1. The issue is caused by `codespan-reporting` itself and not by how it is used. 40 | Have a look at the documentation if you are not sure. 41 | If the documentation is not helpful, you can contact the developers at the above matrix chat address or make an issue. 42 | 1. Your issue has not already been reported by someone else. 43 | Please look through the open issues in the [issue tracker][github-issues]. 44 | 45 | When reporting an issue, please add as much relevant information as possible. 46 | This will help developers and maintainers to resolve your issue. Some things you might consider: 47 | 48 | * Use a descriptive title. 49 | * Describe how a problem can be reproduced. Ideally give a minimal example. 50 | * Explain what exactly is the problem and what you expect instead. If it is related to rendering, add screenshots or other illustrations. 51 | 52 | [github-issues]: https://github.com/brendanzab/codespan/issues 53 | 54 | ## Contribution Workflow 55 | 56 | Follow these steps to contribute to the project: 57 | 58 | 1. Make a fork of the [codespan repository][codespan-repo]. 59 | 1. Within your fork, create a branch for your contribution. Use a meaningful name. 60 | 1. Create your contribution, meeting all [contribution quality standards](#quality-standards). 61 | 1. Ensure all the tests pass (`cargo test`). 62 | 1. [Create a pull request][create-a-pr] against the `master` branch of the repository. 63 | 1. Once the pull request is reviewed and CI passes, it will be merged. 64 | 65 | [codespan-repo]: https://github.com/brendanzab/codespan 66 | [create-a-pr]: https://help.github.com/articles/creating-a-pull-request-from-a-fork/ 67 | 68 | ## Quality Standards 69 | 70 | Most quality and style standards are checked automatically by the CI build. 71 | Contributions should: 72 | 73 | - Separate each **logical change** into its own commit. 74 | - Include tests for any new functionality and fixed issues in your pull request. 75 | - Update the changelogs with any added, removed, changed, or fixed functionality. 76 | - Document public functions. 77 | - Format code with `cargo fmt`. 78 | - Avoid adding `unsafe` code. 79 | If it is necessary, provide an explanatory comment on any `unsafe` block explaining its rationale and why it's safe. 80 | - Add a descriptive message for each commit. 81 | Follow [these commit message guidelines][commit-messages]. 82 | - Document your pull requests. 83 | Include the reasoning behind each change, and the testing done. 84 | 85 | [commit-messages]: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 86 | 87 | ## Release Process 88 | 89 | 1. Bump the version numbers of each crate appropriately. 90 | 1. Update the changelogs with the new version ranges. 91 | 1. Create a new PR for the release, and if it passes CI merge it. 92 | 1. Create a new tag for the release, pointing to the merge commit. 93 | 1. Run the following commands in order from the root of the repository. 94 | Note that doing this too quickly may result in an error, 95 | due to a server-side delay in crate publishing: 96 | ``` 97 | cd codespan-reporting && cargo publish; cd .. 98 | cd codespan && cargo publish; cd .. 99 | cd codespan-lsp && cargo publish; cd .. 100 | ``` 101 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["./codespan", "./codespan-reporting", "./codespan-lsp"] 3 | resolver = "2" 4 | 5 | [workspace.lints.clippy] 6 | all = { level = "deny", priority = -1 } 7 | pedantic = { level = "deny", priority = -1 } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # codespan-reporting 2 | 3 | [![Continuous integration][actions-badge]][actions-url] 4 | [![Crates.io][crate-badge]][crate-url] 5 | [![Docs.rs][docs-badge]][docs-url] 6 | [![Matrix][matrix-badge]][matrix-lobby] 7 | 8 | [actions-badge]: https://img.shields.io/github/actions/workflow/status/brendanzab/codespan/ci.yml?branch=master 9 | [actions-url]: https://github.com/brendanzab/codespan/actions 10 | [crate-url]: https://crates.io/crates/codespan-reporting 11 | [crate-badge]: https://img.shields.io/crates/v/codespan-reporting.svg 12 | [docs-url]: https://docs.rs/codespan-reporting 13 | [docs-badge]: https://docs.rs/codespan-reporting/badge.svg 14 | [matrix-badge]: https://img.shields.io/badge/matrix-%23codespan%3Amatrix.org-blue.svg 15 | [matrix-lobby]: https://app.element.io/#/room/#codespan:matrix.org 16 | 17 | Beautiful diagnostic reporting for text-based programming languages. 18 | 19 | ![Example preview](./codespan-reporting/assets/readme_preview.svg?sanitize=true) 20 | 21 | Languages like Rust and Elm already support beautiful error reporting output, 22 | but it can take a significant amount work to implement this for new programming 23 | languages! The `codespan-reporting` crate aims to make beautiful error 24 | diagnostics easy and relatively painless for everyone! 25 | 26 | We're still working on improving the crate to help it support broader use cases, 27 | and improving the quality of the diagnostic rendering, so stay tuned for 28 | updates and please give us feedback if you have it. Contributions are also very 29 | welcome! 30 | 31 | ## Example 32 | 33 | ```rust 34 | use codespan_reporting::diagnostic::{Diagnostic, Label}; 35 | use codespan_reporting::files::SimpleFiles; 36 | use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; 37 | 38 | // `files::SimpleFile` and `files::SimpleFiles` help you get up and running with 39 | // `codespan-reporting` quickly! More complicated use cases can be supported 40 | // by creating custom implementations of the `files::Files` trait. 41 | 42 | let mut files = SimpleFiles::new(); 43 | 44 | let file_id = files.add( 45 | "FizzBuzz.fun", 46 | unindent::unindent( 47 | r#" 48 | module FizzBuzz where 49 | 50 | fizz₁ : Nat → String 51 | fizz₁ num = case (mod num 5) (mod num 3) of 52 | 0 0 => "FizzBuzz" 53 | 0 _ => "Fizz" 54 | _ 0 => "Buzz" 55 | _ _ => num 56 | 57 | fizz₂ : Nat → String 58 | fizz₂ num = 59 | case (mod num 5) (mod num 3) of 60 | 0 0 => "FizzBuzz" 61 | 0 _ => "Fizz" 62 | _ 0 => "Buzz" 63 | _ _ => num 64 | "#, 65 | ), 66 | ); 67 | 68 | // We normally recommend creating a custom diagnostic data type for your 69 | // application, and then converting that to `codespan-reporting`'s diagnostic 70 | // type, but for the sake of this example we construct it directly. 71 | 72 | let diagnostic = Diagnostic::error() 73 | .with_message("`case` clauses have incompatible types") 74 | .with_code("E0308") 75 | .with_labels(vec![ 76 | Label::primary(file_id, 328..331).with_message("expected `String`, found `Nat`"), 77 | Label::secondary(file_id, 211..331).with_message("`case` clauses have incompatible types"), 78 | Label::secondary(file_id, 258..268).with_message("this is found to be of type `String`"), 79 | Label::secondary(file_id, 284..290).with_message("this is found to be of type `String`"), 80 | Label::secondary(file_id, 306..312).with_message("this is found to be of type `String`"), 81 | Label::secondary(file_id, 186..192).with_message("expected type `String` found here"), 82 | ]) 83 | .with_notes(vec![unindent::unindent( 84 | " 85 | expected type `String` 86 | found type `Nat` 87 | ", 88 | )]); 89 | 90 | // We now set up the writer and configuration, and then finally render the 91 | // diagnostic to standard error. 92 | 93 | let writer = StandardStream::stderr(ColorChoice::Always); 94 | let config = codespan_reporting::term::Config::default(); 95 | 96 | term::emit(&mut writer.lock(), &config, &files, &diagnostic)?; 97 | ``` 98 | 99 | ## Running the CLI example 100 | 101 | To get an idea of what the colored CLI output looks like, 102 | clone the [repository](https://github.com/brendanzab/codespan) 103 | and run the following shell command: 104 | 105 | ```sh 106 | cargo run --example term 107 | ``` 108 | 109 | More examples of using `codespan-reporting` can be found in the 110 | [examples directory](./codespan-reporting/examples). 111 | 112 | ## Projects using codespan-reporting 113 | 114 | `codespan-reporting` is currently used in the following projects: 115 | 116 | - [cargo-deny](https://github.com/EmbarkStudios/cargo-deny) 117 | - [cargo-about](https://github.com/EmbarkStudios/cargo-about) 118 | - [CXX](https://github.com/dtolnay/cxx) 119 | - [full_moon](https://github.com/Kampfkarren/full-moon) 120 | - [Gleam](https://github.com/gleam-lang/gleam) 121 | - [Gluon](https://github.com/gluon-lang/gluon) 122 | - [MDBook LinkCheck](https://github.com/Michael-F-Bryan/mdbook-linkcheck) 123 | - [mos](https://github.com/datatrash/mos) 124 | - [Pikelet](https://github.com/pikelet-lang/pikelet) 125 | - [Naga](https://github.com/gfx-rs/wgpu/tree/trunk/naga) 126 | - [Spade](https://gitlab.com/spade-lang/spade) 127 | 128 | ... [any many more](https://crates.io/crates/codespan-reporting/reverse_dependencies) 129 | 130 | ## Alternatives to codespan-reporting 131 | 132 | There are a number of alternatives to `codespan-reporting`, including: 133 | 134 | - [annotate-snippets][annotate-snippets] 135 | - [codemap][codemap] 136 | - [language-reporting][language-reporting] (a fork of codespan) 137 | 138 | These are all ultimately inspired by rustc's excellent [error reporting infrastructure][librustc_errors]. 139 | 140 | [annotate-snippets]: https://crates.io/crates/annotate-snippets 141 | [codemap]: https://crates.io/crates/codemap 142 | [language-reporting]: https://crates.io/crates/language-reporting 143 | [librustc_errors]: https://github.com/rust-lang/rust/tree/master/compiler/rustc_errors/src 144 | 145 | ## Contributing 146 | 147 | A guide to contributing to codespan-reporting [can be found here](/CONTRIBUTING.md). 148 | 149 | ## Code of Conduct 150 | 151 | Please note that this project is released with a [Code of Conduct](./CODE_OF_CONDUCT.md). 152 | By participating in this project you agree to abide by its terms. 153 | -------------------------------------------------------------------------------- /codespan-lsp/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | The minimum supported rustc version is now `1.67.0` (was `1.40.0`). 11 | This is because some dependencies now require this Rust version. 12 | 13 | ### Changed 14 | 15 | - The `lsp-types` dependency was updated to use a version range: `>=0.84, <0.90`, 16 | which includes the latest updates in `0.89.0`. 17 | 18 | ## [0.11.1] - 2021-01-18 19 | 20 | ### Changed 21 | 22 | - The `lsp-types` dependency was updated to use a version range: `>=0.84, <0.89`, 23 | which includes the latest updates in `0.85.0`, `0.86.0`, `0.87.0`, 24 | and `0.88.0`. 25 | 26 | ## [0.11.0] - 2020-11-30 27 | 28 | There is now a [code of conduct](https://github.com/brendanzab/codespan/blob/master/CODE_OF_CONDUCT.md) 29 | and a [contributing guide](https://github.com/brendanzab/codespan/blob/master/CONTRIBUTING.md). 30 | 31 | ### Changed 32 | 33 | - The error type in `codespan-lsp` is replaced with the error type in the `codespan-reporting` crate. 34 | The error type is now `codespan_reporting::file::Error`. 35 | - The `lsp-types` dependency was updated to use the version range: `>=0.84, <0.85`. 36 | Compatibility was broken as a result of the [clarified numeric types] that this crate depended on. 37 | - The `character_to_line_offset` function was made private to reduce the chance of future public breakages. 38 | 39 | [clarified numeric types]: https://github.com/gluon-lang/lsp-types/pull/186 40 | 41 | ## [0.10.1] - 2020-08-17 42 | 43 | ### Changed 44 | 45 | - The `lsp-types` dependency was updated to use a version range: `>=0.70, <0.80`, 46 | which includes the latest updates in `0.79.0`. 47 | 48 | ## [0.10.0] - 2020-07-20 49 | 50 | ### Changed 51 | 52 | - `codespan-lsp` only requires `codespan-reporting`, removing its `codespan` dependency. 53 | - The `lsp-types` dependency was updated to use a version range: `>=0.70,<0.78`, 54 | which includes the latest updates in `0.77.0`. 55 | 56 | ## [0.9.5] - 2020-06-24 57 | ## [0.9.4] - 2020-05-18 58 | 59 | ## [0.9.3] - 2020-04-29 60 | 61 | ### Changed 62 | 63 | - The `lsp-types` dependency was updated to use a version range: `>=0.70,<0.75`, 64 | which includes the latest updates in `0.74.0`. 65 | 66 | ## [0.9.2] - 2020-03-29 67 | ## [0.9.1] - 2020-03-23 68 | ## [0.9.0] - 2020-03-11 69 | 70 | ### Changed 71 | 72 | - The `lsp-types` dependency was updated to use a version range: `>=0.70,<0.74`, 73 | which includes the latest updates in `0.73.0`. 74 | 75 | ### Removed 76 | 77 | - `codespan_lsp` no longer depends on `codespan_reporting`. 78 | - `make_lsp_severity` and `make_lsp_diagnostic` were removed. 79 | It's pretty hard to map the diagnostic structure to LSP diagnostics - we 80 | recommend implementing this as an application-specific concern. 81 | 82 | ## [0.8.0] - 2020-02-24 83 | ## [0.7.0] - 2020-01-06 84 | ## [0.6.0] - 2019-12-18 85 | ## [0.5.0] - 2019-10-02 86 | ## [0.4.1] - 2019-08-25 87 | ## [0.4.0] - 2019-08-22 88 | ## [0.3.0] - 2019-05-01 89 | ## [0.2.1] - 2019-02-26 90 | ## [0.2.0] - 2018-10-11 91 | 92 | [Unreleased]: https://github.com/brendanzab/codespan/compare/v0.11.1...HEAD 93 | [0.11.1]: https://github.com/brendanzab/codespan/compare/v0.11.0..v0.11.1 94 | [0.11.0]: https://github.com/brendanzab/codespan/compare/v0.10.1..v0.11.0 95 | [0.10.1]: https://github.com/brendanzab/codespan/compare/v0.10.0..v0.10.1 96 | [0.10.0]: https://github.com/brendanzab/codespan/compare/v0.9.5...v0.10.0 97 | [0.9.5]: https://github.com/brendanzab/codespan/compare/v0.9.4...v0.9.5 98 | [0.9.4]: https://github.com/brendanzab/codespan/compare/v0.9.3...v0.9.4 99 | [0.9.3]: https://github.com/brendanzab/codespan/compare/v0.9.2...v0.9.3 100 | [0.9.2]: https://github.com/brendanzab/codespan/compare/v0.9.1...v0.9.2 101 | [0.9.1]: https://github.com/brendanzab/codespan/compare/v0.9.0...v0.9.1 102 | [0.9.0]: https://github.com/brendanzab/codespan/compare/v0.8.0...v0.9.0 103 | [0.8.0]: https://github.com/brendanzab/codespan/compare/v0.7.0...v0.8.0 104 | [0.7.0]: https://github.com/brendanzab/codespan/compare/v0.6.0...v0.7.0 105 | [0.6.0]: https://github.com/brendanzab/codespan/compare/v0.5.0...v0.6.0 106 | [0.5.0]: https://github.com/brendanzab/codespan/compare/v0.4.1...v0.5.0 107 | [0.4.1]: https://github.com/brendanzab/codespan/compare/v0.4.0...v0.4.1 108 | [0.4.0]: https://github.com/brendanzab/codespan/compare/v0.3.0...v0.4.0 109 | [0.3.0]: https://github.com/brendanzab/codespan/compare/v0.2.1...v0.3.0 110 | [0.2.1]: https://github.com/brendanzab/codespan/compare/v0.2.0...v0.2.1 111 | [0.2.0]: https://github.com/brendanzab/codespan/releases/tag/v0.2.0 112 | -------------------------------------------------------------------------------- /codespan-lsp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codespan-lsp" 3 | version = "0.11.1" 4 | license = "Apache-2.0" 5 | authors = ["Markus Westerlind "] 6 | description = "Conversions between codespan types and Language Server Protocol types" 7 | homepage = "https://github.com/brendanzab/codespan" 8 | repository = "https://github.com/brendanzab/codespan" 9 | documentation = "https://docs.rs/codespan-lsp" 10 | edition = "2021" 11 | rust-version = "1.67" 12 | 13 | [dependencies] 14 | codespan-reporting = { version = "0.12.0", path = "../codespan-reporting", features = [ 15 | "std", 16 | "termcolor", 17 | ] } 18 | # WARNING: Be extremely careful when expanding this version range. 19 | # We should be confident that all of the uses of `lsp-types` in `codespan-lsp` 20 | # will be valid for all the versions in this range. Getting this range wrong 21 | # could potentially break down-stream builds on a `cargo update`. This is an 22 | # absolute no-no, breaking much of what we enjoy about Cargo! 23 | lsp-types = ">=0.84, <0.92" 24 | url = "2" 25 | 26 | [lints.clippy] 27 | # Certain items from `core` are re-exported in `alloc` and `std`, and likewise `alloc` has items 28 | # re-exported in `std`. 29 | # `core` is available on all platforms, `alloc` is available on almost all, and `std` is only 30 | # available on some. 31 | # These lints ensure we don't import from a "less available" crate without reason. 32 | alloc_instead_of_core = "warn" 33 | std_instead_of_alloc = "warn" 34 | std_instead_of_core = "warn" 35 | -------------------------------------------------------------------------------- /codespan-lsp/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /codespan-lsp/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Utilities for translating from codespan types into Language Server Protocol (LSP) types 2 | 3 | #![forbid(unsafe_code)] 4 | #![no_std] 5 | 6 | #[cfg(test)] 7 | extern crate alloc; 8 | 9 | use core::ops::Range; 10 | 11 | use codespan_reporting::files::{Error, Files}; 12 | 13 | // WARNING: Be extremely careful when adding new imports here, as it could break 14 | // the compatible version range that we claim in our `Cargo.toml`. This could 15 | // potentially break down-stream builds on a `cargo update`. This is an 16 | // absolute no-no, breaking much of what we enjoy about Cargo! 17 | use lsp_types::{Position as LspPosition, Range as LspRange}; 18 | 19 | fn location_to_position( 20 | line_str: &str, 21 | line: usize, 22 | column: usize, 23 | byte_index: usize, 24 | ) -> Result { 25 | if column > line_str.len() { 26 | let max = line_str.len(); 27 | let given = column; 28 | 29 | Err(Error::ColumnTooLarge { given, max }) 30 | } else if !line_str.is_char_boundary(column) { 31 | let given = byte_index; 32 | 33 | Err(Error::InvalidCharBoundary { given }) 34 | } else { 35 | let line_utf16 = line_str[..column].encode_utf16(); 36 | let character = line_utf16.count() as u32; 37 | let line = line as u32; 38 | 39 | Ok(LspPosition { line, character }) 40 | } 41 | } 42 | 43 | pub fn byte_index_to_position<'a, F>( 44 | files: &'a F, 45 | file_id: F::FileId, 46 | byte_index: usize, 47 | ) -> Result 48 | where 49 | F: Files<'a> + ?Sized, 50 | { 51 | let source = files.source(file_id)?; 52 | let source = source.as_ref(); 53 | 54 | let line_index = files.line_index(file_id, byte_index)?; 55 | let line_span = files.line_range(file_id, line_index).unwrap(); 56 | 57 | let line_str = source 58 | .get(line_span.clone()) 59 | .ok_or_else(|| Error::IndexTooLarge { 60 | given: if line_span.start >= source.len() { 61 | line_span.start 62 | } else { 63 | line_span.end 64 | }, 65 | max: source.len() - 1, 66 | })?; 67 | let column = byte_index - line_span.start; 68 | 69 | location_to_position(line_str, line_index, column, byte_index) 70 | } 71 | 72 | pub fn byte_span_to_range<'a, F>( 73 | files: &'a F, 74 | file_id: F::FileId, 75 | span: Range, 76 | ) -> Result 77 | where 78 | F: Files<'a> + ?Sized, 79 | { 80 | Ok(LspRange { 81 | start: byte_index_to_position(files, file_id, span.start)?, 82 | end: byte_index_to_position(files, file_id, span.end)?, 83 | }) 84 | } 85 | 86 | fn character_to_line_offset(line: &str, character: u32) -> Result { 87 | let line_len = line.len(); 88 | let mut character_offset = 0; 89 | 90 | let mut chars = line.chars(); 91 | while let Some(ch) = chars.next() { 92 | if character_offset == character { 93 | let chars_off = chars.as_str().len(); 94 | let ch_off = ch.len_utf8(); 95 | 96 | return Ok(line_len - chars_off - ch_off); 97 | } 98 | 99 | character_offset += ch.len_utf16() as u32; 100 | } 101 | 102 | // Handle positions after the last character on the line 103 | if character_offset == character { 104 | Ok(line_len) 105 | } else { 106 | Err(Error::ColumnTooLarge { 107 | given: character_offset as usize, 108 | max: line.len(), 109 | }) 110 | } 111 | } 112 | 113 | pub fn position_to_byte_index<'a, F>( 114 | files: &'a F, 115 | file_id: F::FileId, 116 | position: &LspPosition, 117 | ) -> Result 118 | where 119 | F: Files<'a> + ?Sized, 120 | { 121 | let source = files.source(file_id)?; 122 | let source = source.as_ref(); 123 | 124 | let line_span = files.line_range(file_id, position.line as usize).unwrap(); 125 | let line_str = source.get(line_span.clone()).unwrap(); 126 | 127 | let byte_offset = character_to_line_offset(line_str, position.character)?; 128 | 129 | Ok(line_span.start + byte_offset) 130 | } 131 | 132 | pub fn range_to_byte_span<'a, F>( 133 | files: &'a F, 134 | file_id: F::FileId, 135 | range: &LspRange, 136 | ) -> Result, Error> 137 | where 138 | F: Files<'a> + ?Sized, 139 | { 140 | Ok(position_to_byte_index(files, file_id, &range.start)? 141 | ..position_to_byte_index(files, file_id, &range.end)?) 142 | } 143 | 144 | #[cfg(test)] 145 | mod tests { 146 | use alloc::string::ToString; 147 | 148 | use codespan_reporting::files::{Location, SimpleFiles}; 149 | 150 | use super::*; 151 | 152 | #[test] 153 | fn position() { 154 | let text = r#" 155 | let test = 2 156 | let test1 = "" 157 | test 158 | "#; 159 | let mut files = SimpleFiles::new(); 160 | let file_id = files.add("test", text); 161 | let pos = position_to_byte_index( 162 | &files, 163 | file_id, 164 | &LspPosition { 165 | line: 3, 166 | character: 2, 167 | }, 168 | ) 169 | .unwrap(); 170 | assert_eq!( 171 | Location { 172 | // One-based 173 | line_number: 3 + 1, 174 | column_number: 2 + 1, 175 | }, 176 | files.location(file_id, pos).unwrap() 177 | ); 178 | } 179 | 180 | // The protocol specifies that each `character` in position is a UTF-16 character. 181 | // This means that `å` and `ä` here counts as 1 while `𐐀` counts as 2. 182 | const UNICODE: &str = "åä t𐐀b"; 183 | 184 | #[test] 185 | fn unicode_get_byte_index() { 186 | let mut files = SimpleFiles::new(); 187 | let file_id = files.add("unicode", UNICODE); 188 | 189 | let result = position_to_byte_index( 190 | &files, 191 | file_id, 192 | &LspPosition { 193 | line: 0, 194 | character: 3, 195 | }, 196 | ); 197 | assert_eq!(result.unwrap(), 5); 198 | 199 | let result = position_to_byte_index( 200 | &files, 201 | file_id, 202 | &LspPosition { 203 | line: 0, 204 | character: 6, 205 | }, 206 | ); 207 | assert_eq!(result.unwrap(), 10); 208 | } 209 | 210 | #[test] 211 | fn unicode_get_position() { 212 | let mut files = SimpleFiles::new(); 213 | let file_id = files.add("unicode", UNICODE.to_string()); 214 | let file_id2 = files.add("unicode newline", "\n".to_string() + UNICODE); 215 | 216 | let result = byte_index_to_position(&files, file_id, 5); 217 | assert_eq!( 218 | result.unwrap(), 219 | LspPosition { 220 | line: 0, 221 | character: 3, 222 | } 223 | ); 224 | 225 | let result = byte_index_to_position(&files, file_id, 10); 226 | assert_eq!( 227 | result.unwrap(), 228 | LspPosition { 229 | line: 0, 230 | character: 6, 231 | } 232 | ); 233 | 234 | let result = byte_index_to_position(&files, file_id2, 11); 235 | assert_eq!( 236 | result.unwrap(), 237 | LspPosition { 238 | line: 1, 239 | character: 6, 240 | } 241 | ); 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /codespan-reporting/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codespan-reporting" 3 | version = "0.12.0" 4 | readme = "../README.md" 5 | license = "Apache-2.0" 6 | authors = ["Brendan Zabarauskas "] 7 | description = "Beautiful diagnostic reporting for text-based programming languages" 8 | homepage = "https://github.com/brendanzab/codespan" 9 | repository = "https://github.com/brendanzab/codespan" 10 | documentation = "https://docs.rs/codespan-reporting" 11 | exclude = ["assets/**"] 12 | edition = "2021" 13 | rust-version = "1.67" 14 | 15 | [dependencies] 16 | serde = { version = "1", default-features = false, optional = true, features = ["derive", "alloc"] } 17 | termcolor = { version = "1.0.4", optional = true } 18 | unicode-width = ">=0.1,<0.3" 19 | 20 | [dev-dependencies] 21 | pico-args = "0.5.0" 22 | anyhow = "1" 23 | insta = "1.6.3" 24 | lazy_static = "1.4" 25 | peg = "0.7" 26 | rustyline = "6" 27 | unindent = "0.1" 28 | 29 | [features] 30 | default = ["std", "termcolor"] 31 | std = ["serde?/std"] 32 | termcolor = ["std", "dep:termcolor"] 33 | serialization = ["serde"] 34 | ascii-only = [] 35 | 36 | [lints.clippy] 37 | # Certain items from `core` are re-exported in `alloc` and `std`, and likewise `alloc` has items 38 | # re-exported in `std`. 39 | # `core` is available on all platforms, `alloc` is available on almost all, and `std` is only 40 | # available on some. 41 | # These lints ensure we don't import from a "less available" crate without reason. 42 | alloc_instead_of_core = "warn" 43 | std_instead_of_alloc = "warn" 44 | std_instead_of_core = "warn" -------------------------------------------------------------------------------- /codespan-reporting/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /codespan-reporting/assets/readme_preview.svg: -------------------------------------------------------------------------------- 1 | 2 | 51 | 52 | 53 |
54 |
error[E0308]: `case` clauses have incompatible types
55 |    ┌─ FizzBuzz.fun:16:16
56 |      
57 | 10    fizz₂ : Nat → String
58 |                     ------ expected type `String` found here
59 | 11    fizz₂ num =
60 | 12       case (mod num 5) (mod num 3) of
61 | 13           0 0 => "FizzBuzz"
62 |                     ---------- this is found to be of type `String`
63 | 14           0 _ => "Fizz"
64 |                     ------ this is found to be of type `String`
65 | 15           _ 0 => "Buzz"
66 |                     ------ this is found to be of type `String`
67 | 16           _ _ => num
68 |                     ^^^ expected `String`, found `Nat`
69 |     ──────────────────' `case` clauses have incompatible types
70 |      
71 |    = expected type `String`
72 |         found type `Nat`
73 | 
74 | 
75 |
76 |
77 |
78 | -------------------------------------------------------------------------------- /codespan-reporting/examples/custom_files.rs: -------------------------------------------------------------------------------- 1 | //! An example that shows how to implement a simple custom file database. 2 | //! The database uses 32-bit file-ids, which could be useful for optimizing 3 | //! memory usage. 4 | //! 5 | //! To run this example, execute the following command from the top level of 6 | //! this repository: 7 | //! 8 | //! ```sh 9 | //! cargo run --example custom_files 10 | //! ``` 11 | 12 | use codespan_reporting::diagnostic::{Diagnostic, Label}; 13 | use codespan_reporting::term; 14 | use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; 15 | use core::ops::Range; 16 | 17 | fn main() -> anyhow::Result<()> { 18 | let mut files = files::Files::new(); 19 | 20 | let file_id0 = files.add("0.greeting", "hello world!").unwrap(); 21 | let file_id1 = files.add("1.greeting", "bye world").unwrap(); 22 | 23 | let messages = vec![ 24 | Message::UnwantedGreetings { 25 | greetings: vec![(file_id0, 0..5), (file_id1, 0..3)], 26 | }, 27 | Message::OverTheTopExclamations { 28 | exclamations: vec![(file_id0, 11..12)], 29 | }, 30 | ]; 31 | 32 | let writer = StandardStream::stderr(ColorChoice::Always); 33 | let config = term::Config::default(); 34 | for message in &messages { 35 | let writer = &mut writer.lock(); 36 | term::emit(writer, &config, &files, &message.to_diagnostic())?; 37 | } 38 | 39 | Ok(()) 40 | } 41 | 42 | /// A module containing the file implementation 43 | mod files { 44 | use codespan_reporting::files; 45 | use core::ops::Range; 46 | 47 | /// A file that is backed by an `Arc`. 48 | #[derive(Debug, Clone)] 49 | struct File { 50 | /// The name of the file. 51 | name: String, 52 | /// The source code of the file. 53 | source: String, 54 | /// The starting byte indices in the source code. 55 | line_starts: Vec, 56 | } 57 | 58 | impl File { 59 | fn line_start(&self, line_index: usize) -> Result { 60 | use core::cmp::Ordering; 61 | 62 | match line_index.cmp(&self.line_starts.len()) { 63 | Ordering::Less => Ok(*self 64 | .line_starts 65 | .get(line_index) 66 | .expect("failed despite previous check")), 67 | Ordering::Equal => Ok(self.source.len()), 68 | Ordering::Greater => Err(files::Error::LineTooLarge { 69 | given: line_index, 70 | max: self.line_starts.len() - 1, 71 | }), 72 | } 73 | } 74 | } 75 | 76 | /// An opaque file identifier. 77 | #[derive(Copy, Clone, PartialEq, Eq)] 78 | pub struct FileId(u32); 79 | 80 | #[derive(Debug, Clone)] 81 | pub struct Files { 82 | files: Vec, 83 | } 84 | 85 | impl Files { 86 | /// Create a new files database. 87 | pub fn new() -> Files { 88 | Files { files: Vec::new() } 89 | } 90 | 91 | /// Add a file to the database, returning the handle that can be used to 92 | /// refer to it again. 93 | pub fn add( 94 | &mut self, 95 | name: impl Into, 96 | source: impl Into, 97 | ) -> Option { 98 | use core::convert::TryFrom; 99 | 100 | let file_id = FileId(u32::try_from(self.files.len()).ok()?); 101 | let name = name.into(); 102 | let source = source.into(); 103 | let line_starts = files::line_starts(&source).collect(); 104 | 105 | self.files.push(File { 106 | name, 107 | line_starts, 108 | source, 109 | }); 110 | 111 | Some(file_id) 112 | } 113 | 114 | /// Get the file corresponding to the given id. 115 | fn get(&self, file_id: FileId) -> Result<&File, files::Error> { 116 | self.files 117 | .get(file_id.0 as usize) 118 | .ok_or(files::Error::FileMissing) 119 | } 120 | } 121 | 122 | impl<'files> files::Files<'files> for Files { 123 | type FileId = FileId; 124 | type Name = &'files str; 125 | type Source = &'files str; 126 | 127 | fn name(&self, file_id: FileId) -> Result<&str, files::Error> { 128 | Ok(self.get(file_id)?.name.as_ref()) 129 | } 130 | 131 | fn source(&self, file_id: FileId) -> Result<&str, files::Error> { 132 | Ok(&self.get(file_id)?.source) 133 | } 134 | 135 | fn line_index(&self, file_id: FileId, byte_index: usize) -> Result { 136 | self.get(file_id)? 137 | .line_starts 138 | .binary_search(&byte_index) 139 | .or_else(|next_line| Ok(next_line - 1)) 140 | } 141 | 142 | fn line_range( 143 | &self, 144 | file_id: FileId, 145 | line_index: usize, 146 | ) -> Result, files::Error> { 147 | let file = self.get(file_id)?; 148 | let line_start = file.line_start(line_index)?; 149 | let next_line_start = file.line_start(line_index + 1)?; 150 | 151 | Ok(line_start..next_line_start) 152 | } 153 | } 154 | } 155 | 156 | /// A Diagnostic message. 157 | enum Message { 158 | UnwantedGreetings { 159 | greetings: Vec<(files::FileId, Range)>, 160 | }, 161 | OverTheTopExclamations { 162 | exclamations: Vec<(files::FileId, Range)>, 163 | }, 164 | } 165 | 166 | impl Message { 167 | fn to_diagnostic(&self) -> Diagnostic { 168 | match self { 169 | Message::UnwantedGreetings { greetings } => Diagnostic::error() 170 | .with_message("greetings are not allowed") 171 | .with_labels( 172 | greetings 173 | .iter() 174 | .map(|(file_id, range)| { 175 | Label::primary(*file_id, range.clone()).with_message("a greeting") 176 | }) 177 | .collect(), 178 | ) 179 | .with_notes(vec![ 180 | "found greetings!".to_owned(), 181 | "pleas no greetings :(".to_owned(), 182 | ]), 183 | Message::OverTheTopExclamations { exclamations } => Diagnostic::error() 184 | .with_message("over-the-top exclamations") 185 | .with_labels( 186 | exclamations 187 | .iter() 188 | .map(|(file_id, range)| { 189 | Label::primary(*file_id, range.clone()).with_message("an exclamation") 190 | }) 191 | .collect(), 192 | ) 193 | .with_notes(vec!["ridiculous!".to_owned()]), 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /codespan-reporting/examples/peg_calculator.rs: -------------------------------------------------------------------------------- 1 | //! An example of using `peg` with `codespan_reporting`. 2 | //! 3 | //! To run this example, execute the following command from the top level of 4 | //! this repository: 5 | //! 6 | //! ```sh 7 | //! cargo run --example peg_calculator 8 | //! ``` 9 | 10 | use codespan_reporting::diagnostic::{Diagnostic, Label}; 11 | use codespan_reporting::files::SimpleFile; 12 | use codespan_reporting::term; 13 | use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; 14 | use rustyline::error::ReadlineError; 15 | use rustyline::Editor; 16 | 17 | #[allow(clippy::redundant_closure_call)] 18 | peg::parser! { 19 | grammar arithmetic() for str { 20 | rule number() -> i64 21 | = n:$(['0'..='9']+) { n.parse().unwrap() } 22 | 23 | pub rule calculate() -> i64 = precedence!{ 24 | x:(@) "+" y:@ { x + y } 25 | x:(@) "-" y:@ { x - y } 26 | "-" v:@ { - v } 27 | -- 28 | x:(@) "*" y:@ { x * y } 29 | x:(@) "/" y:@ { x / y } 30 | -- 31 | x:@ "^" y:(@) { i64::pow(x, y as u32) } 32 | v:@ "!" { (1..v+1).product() } 33 | -- 34 | "(" v:calculate() ")" { v } 35 | n:number() { n } 36 | } 37 | } 38 | } 39 | 40 | fn main() -> anyhow::Result<()> { 41 | let writer = StandardStream::stderr(ColorChoice::Always); 42 | let config = codespan_reporting::term::Config::default(); 43 | let mut editor = Editor::<()>::new(); 44 | 45 | loop { 46 | let line = match editor.readline("> ") { 47 | Ok(line) => line, 48 | Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => return Ok(()), 49 | Err(error) => return Err(error.into()), 50 | }; 51 | 52 | match arithmetic::calculate(&line) { 53 | Ok(number) => println!("{}", number), 54 | Err(error) => { 55 | let file = SimpleFile::new("", line); 56 | 57 | let start = error.location.offset; 58 | let diagnostic = Diagnostic::error() 59 | .with_message("parse error") 60 | .with_labels(vec![ 61 | Label::primary((), start..start).with_message("parse error") 62 | ]) 63 | .with_notes(vec![format!("expected: {}", error.expected)]); 64 | 65 | term::emit(&mut writer.lock(), &config, &file, &diagnostic)?; 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /codespan-reporting/examples/readme_preview.rs: -------------------------------------------------------------------------------- 1 | //! Renders the preview SVG for the README. 2 | //! 3 | //! To update the preview, execute the following command from the top level of 4 | //! the repository: 5 | //! 6 | //! ```sh 7 | //! cargo run --example readme_preview svg > codespan-reporting/assets/readme_preview.svg 8 | //! ``` 9 | 10 | use codespan_reporting::diagnostic::{Diagnostic, Label}; 11 | use codespan_reporting::files::SimpleFile; 12 | use codespan_reporting::term::termcolor::{ 13 | Color, ColorChoice, ColorSpec, StandardStream, WriteColor, 14 | }; 15 | use codespan_reporting::term::{self}; 16 | use std::io::{self, Write}; 17 | 18 | #[derive(Debug)] 19 | pub enum Opts { 20 | /// Render SVG output 21 | Svg, 22 | /// Render Stderr output 23 | Stderr { 24 | /// Configure coloring of output 25 | color: ColorChoice, 26 | }, 27 | } 28 | 29 | fn parse_args() -> Result { 30 | let mut pargs = pico_args::Arguments::from_env(); 31 | match pargs.subcommand()? { 32 | Some(value) => match value.as_str() { 33 | "svg" => Ok(Opts::Svg), 34 | "stderr" => { 35 | let color = pargs 36 | .opt_value_from_str("--color")? 37 | .unwrap_or(ColorChoice::Auto); 38 | Ok(Opts::Stderr { color }) 39 | } 40 | _ => Err(pico_args::Error::Utf8ArgumentParsingFailed { 41 | value, 42 | cause: "not a valid subcommand".to_owned(), 43 | }), 44 | }, 45 | None => Err(pico_args::Error::MissingArgument), 46 | } 47 | } 48 | 49 | fn main() -> anyhow::Result<()> { 50 | let file = SimpleFile::new( 51 | "FizzBuzz.fun", 52 | unindent::unindent( 53 | r#" 54 | module FizzBuzz where 55 | 56 | fizz₁ : Nat → String 57 | fizz₁ num = case (mod num 5) (mod num 3) of 58 | 0 0 => "FizzBuzz" 59 | 0 _ => "Fizz" 60 | _ 0 => "Buzz" 61 | _ _ => num 62 | 63 | fizz₂ : Nat → String 64 | fizz₂ num = 65 | case (mod num 5) (mod num 3) of 66 | 0 0 => "FizzBuzz" 67 | 0 _ => "Fizz" 68 | _ 0 => "Buzz" 69 | _ _ => num 70 | "#, 71 | ), 72 | ); 73 | 74 | let diagnostics = [Diagnostic::error() 75 | .with_message("`case` clauses have incompatible types") 76 | .with_code("E0308") 77 | .with_labels(vec![ 78 | Label::primary((), 328..331).with_message("expected `String`, found `Nat`"), 79 | Label::secondary((), 211..331).with_message("`case` clauses have incompatible types"), 80 | Label::secondary((), 258..268).with_message("this is found to be of type `String`"), 81 | Label::secondary((), 284..290).with_message("this is found to be of type `String`"), 82 | Label::secondary((), 306..312).with_message("this is found to be of type `String`"), 83 | Label::secondary((), 186..192).with_message("expected type `String` found here"), 84 | ]) 85 | .with_notes(vec![unindent::unindent( 86 | " 87 | expected type `String` 88 | found type `Nat` 89 | ", 90 | )])]; 91 | 92 | match parse_args()? { 93 | Opts::Svg => { 94 | let mut buffer = Vec::new(); 95 | let mut writer = HtmlEscapeWriter::new(SvgWriter::new(&mut buffer)); 96 | let config = codespan_reporting::term::Config { 97 | #[cfg(feature = "termcolor")] 98 | styles: codespan_reporting::term::Styles::with_blue(Color::Blue), 99 | ..codespan_reporting::term::Config::default() 100 | }; 101 | 102 | for diagnostic in &diagnostics { 103 | term::emit(&mut writer, &config, &file, diagnostic)?; 104 | } 105 | 106 | let num_lines = buffer.iter().filter(|byte| **byte == b'\n').count() + 1; 107 | 108 | let padding = 10; 109 | let font_size = 12; 110 | let line_spacing = 3; 111 | let width = 882; 112 | let height = padding + num_lines * (font_size + line_spacing) + padding; 113 | 114 | let stdout = std::io::stdout(); 115 | let writer = &mut stdout.lock(); 116 | 117 | write!( 118 | writer, 119 | r#" 120 | 169 | 170 | 171 |
172 |
"#,
173 |                 padding = padding,
174 |                 font_size = font_size,
175 |                 width = width,
176 |                 height = height,
177 |             )?;
178 | 
179 |             writer.write_all(&buffer)?;
180 | 
181 |             write!(
182 |                 writer,
183 |                 "
184 |
185 |
186 |
187 | " 188 | )?; 189 | } 190 | Opts::Stderr { color } => { 191 | let writer = StandardStream::stderr(color); 192 | let config = codespan_reporting::term::Config::default(); 193 | for diagnostic in &diagnostics { 194 | term::emit(&mut writer.lock(), &config, &file, diagnostic)?; 195 | } 196 | } 197 | } 198 | 199 | Ok(()) 200 | } 201 | 202 | /// Rudimentary HTML escaper which performs the following conversions: 203 | /// 204 | /// - `<` ⇒ `<` 205 | /// - `>` ⇒ `>` 206 | /// - `&` ⇒ `&` 207 | pub struct HtmlEscapeWriter { 208 | upstream: W, 209 | } 210 | 211 | impl HtmlEscapeWriter { 212 | pub fn new(upstream: W) -> HtmlEscapeWriter { 213 | HtmlEscapeWriter { upstream } 214 | } 215 | } 216 | 217 | impl Write for HtmlEscapeWriter { 218 | fn write(&mut self, buf: &[u8]) -> io::Result { 219 | let mut last_term = 0usize; 220 | for (i, byte) in buf.iter().enumerate() { 221 | let escape = match byte { 222 | b'<' => &b"<"[..], 223 | b'>' => &b">"[..], 224 | b'&' => &b"&"[..], 225 | _ => continue, 226 | }; 227 | self.upstream.write_all(&buf[last_term..i])?; 228 | last_term = i + 1; 229 | self.upstream.write_all(escape)?; 230 | } 231 | self.upstream.write_all(&buf[last_term..])?; 232 | Ok(buf.len()) 233 | } 234 | 235 | fn flush(&mut self) -> io::Result<()> { 236 | self.upstream.flush() 237 | } 238 | } 239 | 240 | impl WriteColor for HtmlEscapeWriter { 241 | fn supports_color(&self) -> bool { 242 | self.upstream.supports_color() 243 | } 244 | 245 | fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { 246 | self.upstream.set_color(spec) 247 | } 248 | 249 | fn reset(&mut self) -> io::Result<()> { 250 | self.upstream.reset() 251 | } 252 | } 253 | 254 | pub struct SvgWriter { 255 | upstream: W, 256 | color: ColorSpec, 257 | } 258 | 259 | impl SvgWriter { 260 | pub fn new(upstream: W) -> SvgWriter { 261 | SvgWriter { 262 | upstream, 263 | color: ColorSpec::new(), 264 | } 265 | } 266 | } 267 | 268 | impl Write for SvgWriter { 269 | fn write(&mut self, buf: &[u8]) -> io::Result { 270 | self.upstream.write(buf) 271 | } 272 | 273 | fn flush(&mut self) -> io::Result<()> { 274 | self.upstream.flush() 275 | } 276 | } 277 | 278 | impl WriteColor for SvgWriter { 279 | fn supports_color(&self) -> bool { 280 | true 281 | } 282 | 283 | fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { 284 | #![allow(unused_assignments)] 285 | 286 | if self.color == *spec { 287 | return Ok(()); 288 | } else { 289 | if !self.color.is_none() { 290 | write!(self, "")?; 291 | } 292 | self.color = spec.clone(); 293 | } 294 | 295 | if spec.is_none() { 296 | write!(self, "")?; 297 | return Ok(()); 298 | } else { 299 | write!(self, "(first: bool, writer: &mut SvgWriter) -> io::Result { 305 | if !first { 306 | write!(writer, " ")?; 307 | } 308 | 309 | Ok(false) 310 | } 311 | 312 | fn write_color(color: &Color, writer: &mut SvgWriter) -> io::Result<()> { 313 | match color { 314 | Color::Black => write!(writer, "black"), 315 | Color::Blue => write!(writer, "blue"), 316 | Color::Green => write!(writer, "green"), 317 | Color::Red => write!(writer, "red"), 318 | Color::Cyan => write!(writer, "cyan"), 319 | Color::Magenta => write!(writer, "magenta"), 320 | Color::Yellow => write!(writer, "yellow"), 321 | Color::White => write!(writer, "white"), 322 | // TODO: other colors 323 | _ => Ok(()), 324 | } 325 | } 326 | 327 | if let Some(fg) = spec.fg() { 328 | first = write_first(first, self)?; 329 | write!(self, "fg ")?; 330 | write_color(fg, self)?; 331 | } 332 | 333 | if let Some(bg) = spec.bg() { 334 | first = write_first(first, self)?; 335 | write!(self, "bg ")?; 336 | write_color(bg, self)?; 337 | } 338 | 339 | if spec.bold() { 340 | first = write_first(first, self)?; 341 | write!(self, "bold")?; 342 | } 343 | 344 | if spec.underline() { 345 | first = write_first(first, self)?; 346 | write!(self, "underline")?; 347 | } 348 | 349 | if spec.intense() { 350 | first = write_first(first, self)?; 351 | write!(self, "bright")?; 352 | } 353 | 354 | write!(self, "\">")?; 355 | 356 | Ok(()) 357 | } 358 | 359 | fn reset(&mut self) -> io::Result<()> { 360 | let color = self.color.clone(); 361 | 362 | if color != ColorSpec::new() { 363 | write!(self, "")?; 364 | self.color = ColorSpec::new(); 365 | } 366 | 367 | Ok(()) 368 | } 369 | } 370 | -------------------------------------------------------------------------------- /codespan-reporting/examples/reusable_diagnostic.rs: -------------------------------------------------------------------------------- 1 | use codespan_reporting::diagnostic::{Diagnostic, Label}; 2 | use codespan_reporting::files::SimpleFile; 3 | use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; 4 | use codespan_reporting::term::{self}; 5 | use core::ops::Range; 6 | 7 | #[derive(Debug)] 8 | pub struct Opts { 9 | color: ColorChoice, 10 | } 11 | 12 | fn parse_args() -> Result { 13 | let mut pargs = pico_args::Arguments::from_env(); 14 | let color = pargs 15 | .opt_value_from_str("--color")? 16 | .unwrap_or(ColorChoice::Auto); 17 | Ok(Opts { color }) 18 | } 19 | 20 | fn main() -> anyhow::Result<()> { 21 | let file = SimpleFile::new( 22 | "main.rs", 23 | unindent::unindent( 24 | r#" 25 | fn main() { 26 | let foo: i32 = "hello, world"; 27 | foo += 1; 28 | } 29 | "#, 30 | ), 31 | ); 32 | 33 | let errors = [ 34 | Error::MismatchType( 35 | Item::new(20..23, "i32"), 36 | Item::new(31..45, "\"hello, world\""), 37 | ), 38 | Error::MutatingImmutable(Item::new(20..23, "foo"), Item::new(51..59, "foo += 1")), 39 | ]; 40 | 41 | let Opts { color } = parse_args()?; 42 | let writer = StandardStream::stderr(color); 43 | let config = codespan_reporting::term::Config::default(); 44 | for diagnostic in errors.iter().map(Error::report) { 45 | term::emit(&mut writer.lock(), &config, &file, &diagnostic)?; 46 | } 47 | 48 | Ok(()) 49 | } 50 | 51 | /// An error enum that represent all possible errors within your program 52 | enum Error { 53 | MismatchType(Item, Item), 54 | MutatingImmutable(Item, Item), 55 | } 56 | 57 | impl Error { 58 | fn report(&self) -> Diagnostic<()> { 59 | match self { 60 | Error::MismatchType(left, right) => Diagnostic::error() 61 | .with_code("E0308") 62 | .with_message("mismatch types") 63 | .with_labels(vec![ 64 | Label::primary((), right.range.clone()).with_message(format!( 65 | "Expected `{}`, found: `{}`", 66 | left.content, right.content, 67 | )), 68 | Label::secondary((), left.range.clone()).with_message("expected due to this"), 69 | ]), 70 | Error::MutatingImmutable(original, mutating) => Diagnostic::error() 71 | .with_code("E0384") 72 | .with_message(format!( 73 | "cannot mutate immutable variable `{}`", 74 | original.content, 75 | )) 76 | .with_labels(vec![ 77 | Label::secondary((), original.range.clone()).with_message(unindent::unindent( 78 | &format!( 79 | r#" 80 | first assignment to `{0}` 81 | help: make this binding mutable: `mut {0}` 82 | "#, 83 | original.content, 84 | ), 85 | )), 86 | Label::primary((), mutating.range.clone()) 87 | .with_message("cannot assign twice to immutable variable"), 88 | ]), 89 | } 90 | } 91 | } 92 | 93 | /// An item in the source code to be used in the `Error` enum. 94 | /// In a more complex program it could also contain a `files::FileId` to handle errors that occur inside multiple files. 95 | struct Item { 96 | range: Range, 97 | content: String, 98 | } 99 | 100 | impl Item { 101 | fn new(range: Range, content: impl Into) -> Item { 102 | let content = content.into(); 103 | Item { range, content } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /codespan-reporting/examples/term.rs: -------------------------------------------------------------------------------- 1 | //! To run this example, execute the following command from the top level of 2 | //! this repository: 3 | //! 4 | //! ```sh 5 | //! cargo run --example term 6 | //! ``` 7 | 8 | use codespan_reporting::diagnostic::{Diagnostic, Label}; 9 | use codespan_reporting::files::SimpleFiles; 10 | use codespan_reporting::term; 11 | use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; 12 | 13 | #[derive(Debug)] 14 | pub struct Opts { 15 | /// Configure coloring of output 16 | pub color: ColorChoice, 17 | } 18 | 19 | fn parse_args() -> Result { 20 | let mut pargs = pico_args::Arguments::from_env(); 21 | let color = pargs 22 | .opt_value_from_str("--color")? 23 | .unwrap_or(ColorChoice::Auto); 24 | Ok(Opts { color }) 25 | } 26 | 27 | fn main() -> anyhow::Result<()> { 28 | let Opts { color } = parse_args()?; 29 | 30 | let mut files = SimpleFiles::new(); 31 | 32 | let file_id1 = files.add( 33 | "Data/Nat.fun", 34 | unindent::unindent( 35 | " 36 | module Data.Nat where 37 | 38 | data Nat : Type where 39 | zero : Nat 40 | succ : Nat → Nat 41 | 42 | {-# BUILTIN NATRAL Nat #-} 43 | 44 | infixl 6 _+_ _-_ 45 | 46 | _+_ : Nat → Nat → Nat 47 | zero + n₂ = n₂ 48 | succ n₁ + n₂ = succ (n₁ + n₂) 49 | 50 | _-_ : Nat → Nat → Nat 51 | n₁ - zero = n₁ 52 | zero - succ n₂ = zero 53 | succ n₁ - succ n₂ = n₁ - n₂ 54 | ", 55 | ), 56 | ); 57 | 58 | let file_id2 = files.add( 59 | "Test.fun", 60 | unindent::unindent( 61 | r#" 62 | module Test where 63 | 64 | _ : Nat 65 | _ = 123 + "hello" 66 | "#, 67 | ), 68 | ); 69 | 70 | let file_id3 = files.add( 71 | "FizzBuzz.fun", 72 | unindent::unindent( 73 | r#" 74 | module FizzBuzz where 75 | 76 | fizz₁ : Nat → String 77 | fizz₁ num = case (mod num 5) (mod num 3) of 78 | 0 0 => "FizzBuzz" 79 | 0 _ => "Fizz" 80 | _ 0 => "Buzz" 81 | _ _ => num 82 | 83 | fizz₂ : Nat → String 84 | fizz₂ num = 85 | case (mod num 5) (mod num 3) of 86 | 0 0 => "FizzBuzz" 87 | 0 _ => "Fizz" 88 | _ 0 => "Buzz" 89 | _ _ => num 90 | "#, 91 | ), 92 | ); 93 | 94 | let diagnostics = [ 95 | // Unknown builtin error 96 | Diagnostic::error() 97 | .with_message("unknown builtin: `NATRAL`") 98 | .with_labels(vec![ 99 | Label::primary(file_id1, 96..102).with_message("unknown builtin") 100 | ]) 101 | .with_notes(vec![ 102 | "there is a builtin with a similar name: `NATURAL`".to_owned() 103 | ]), 104 | // Unused parameter warning 105 | Diagnostic::warning() 106 | .with_message("unused parameter pattern: `n₂`") 107 | .with_labels(vec![ 108 | Label::primary(file_id1, 285..289).with_message("unused parameter") 109 | ]) 110 | .with_notes(vec!["consider using a wildcard pattern: `_`".to_owned()]), 111 | // Unexpected type error 112 | Diagnostic::error() 113 | .with_message("unexpected type in application of `_+_`") 114 | .with_code("E0001") 115 | .with_labels(vec![ 116 | Label::primary(file_id2, 37..44).with_message("expected `Nat`, found `String`"), 117 | Label::secondary(file_id1, 130..155) 118 | .with_message("based on the definition of `_+_`"), 119 | ]) 120 | .with_notes(vec![unindent::unindent( 121 | " 122 | expected type `Nat` 123 | found type `String` 124 | ", 125 | )]), 126 | // Incompatible match clause error 127 | Diagnostic::error() 128 | .with_message("`case` clauses have incompatible types") 129 | .with_code("E0308") 130 | .with_labels(vec![ 131 | Label::primary(file_id3, 163..166).with_message("expected `String`, found `Nat`"), 132 | Label::secondary(file_id3, 62..166) 133 | .with_message("`case` clauses have incompatible types"), 134 | Label::secondary(file_id3, 41..47) 135 | .with_message("expected type `String` found here"), 136 | ]) 137 | .with_notes(vec![unindent::unindent( 138 | " 139 | expected type `String` 140 | found type `Nat` 141 | ", 142 | )]), 143 | // Incompatible match clause error 144 | Diagnostic::error() 145 | .with_message("`case` clauses have incompatible types") 146 | .with_code("E0308") 147 | .with_labels(vec![ 148 | Label::primary(file_id3, 328..331).with_message("expected `String`, found `Nat`"), 149 | Label::secondary(file_id3, 211..331) 150 | .with_message("`case` clauses have incompatible types"), 151 | Label::secondary(file_id3, 258..268) 152 | .with_message("this is found to be of type `String`"), 153 | Label::secondary(file_id3, 284..290) 154 | .with_message("this is found to be of type `String`"), 155 | Label::secondary(file_id3, 306..312) 156 | .with_message("this is found to be of type `String`"), 157 | Label::secondary(file_id3, 186..192) 158 | .with_message("expected type `String` found here"), 159 | ]) 160 | .with_notes(vec![unindent::unindent( 161 | " 162 | expected type `String` 163 | found type `Nat` 164 | ", 165 | )]), 166 | ]; 167 | 168 | let writer = StandardStream::stderr(color); 169 | let config = codespan_reporting::term::Config::default(); 170 | for diagnostic in &diagnostics { 171 | term::emit(&mut writer.lock(), &config, &files, diagnostic)?; 172 | } 173 | 174 | Ok(()) 175 | } 176 | -------------------------------------------------------------------------------- /codespan-reporting/src/diagnostic.rs: -------------------------------------------------------------------------------- 1 | //! Diagnostic data structures. 2 | 3 | use alloc::{ 4 | string::{String, ToString}, 5 | vec::Vec, 6 | }; 7 | use core::ops::Range; 8 | 9 | #[cfg(feature = "serialization")] 10 | use serde::{Deserialize, Serialize}; 11 | 12 | /// A severity level for diagnostic messages. 13 | /// 14 | /// These are ordered in the following way: 15 | /// 16 | /// ```rust 17 | /// use codespan_reporting::diagnostic::Severity; 18 | /// 19 | /// assert!(Severity::Bug > Severity::Error); 20 | /// assert!(Severity::Error > Severity::Warning); 21 | /// assert!(Severity::Warning > Severity::Note); 22 | /// assert!(Severity::Note > Severity::Help); 23 | /// ``` 24 | #[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord)] 25 | #[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))] 26 | pub enum Severity { 27 | /// A help message. 28 | Help, 29 | /// A note. 30 | Note, 31 | /// A warning. 32 | Warning, 33 | /// An error. 34 | Error, 35 | /// An unexpected bug. 36 | Bug, 37 | } 38 | 39 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd)] 40 | #[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))] 41 | pub enum LabelStyle { 42 | /// Labels that describe the primary cause of a diagnostic. 43 | Primary, 44 | /// Labels that provide additional context for a diagnostic. 45 | Secondary, 46 | } 47 | 48 | /// A label describing an underlined region of code associated with a diagnostic. 49 | #[derive(Clone, Debug, PartialEq, Eq)] 50 | #[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))] 51 | pub struct Label { 52 | /// The style of the label. 53 | pub style: LabelStyle, 54 | /// The file that we are labelling. 55 | pub file_id: FileId, 56 | /// The range in bytes we are going to include in the final snippet. 57 | pub range: Range, 58 | /// An optional message to provide some additional information for the 59 | /// underlined code. These should not include line breaks. 60 | pub message: String, 61 | } 62 | 63 | impl Label { 64 | /// Create a new label. 65 | pub fn new( 66 | style: LabelStyle, 67 | file_id: FileId, 68 | range: impl Into>, 69 | ) -> Label { 70 | Label { 71 | style, 72 | file_id, 73 | range: range.into(), 74 | message: String::new(), 75 | } 76 | } 77 | 78 | /// Create a new label with a style of [`LabelStyle::Primary`]. 79 | /// 80 | /// [`LabelStyle::Primary`]: LabelStyle::Primary 81 | pub fn primary(file_id: FileId, range: impl Into>) -> Label { 82 | Label::new(LabelStyle::Primary, file_id, range) 83 | } 84 | 85 | /// Create a new label with a style of [`LabelStyle::Secondary`]. 86 | /// 87 | /// [`LabelStyle::Secondary`]: LabelStyle::Secondary 88 | pub fn secondary(file_id: FileId, range: impl Into>) -> Label { 89 | Label::new(LabelStyle::Secondary, file_id, range) 90 | } 91 | 92 | /// Add a message to the diagnostic. 93 | pub fn with_message(mut self, message: impl ToString) -> Label { 94 | self.message = message.to_string(); 95 | self 96 | } 97 | } 98 | 99 | /// Represents a diagnostic message that can provide information like errors and 100 | /// warnings to the user. 101 | /// 102 | /// The position of a Diagnostic is considered to be the position of the [`Label`] that has the earliest starting position and has the highest style which appears in all the labels of the diagnostic. 103 | #[derive(Clone, Debug, PartialEq, Eq)] 104 | #[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))] 105 | pub struct Diagnostic { 106 | /// The overall severity of the diagnostic 107 | pub severity: Severity, 108 | /// An optional code that identifies this diagnostic. 109 | pub code: Option, 110 | /// The main message associated with this diagnostic. 111 | /// 112 | /// These should not include line breaks, and in order support the 'short' 113 | /// diagnostic display mod, the message should be specific enough to make 114 | /// sense on its own, without additional context provided by labels and notes. 115 | pub message: String, 116 | /// Source labels that describe the cause of the diagnostic. 117 | /// The order of the labels inside the vector does not have any meaning. 118 | /// The labels are always arranged in the order they appear in the source code. 119 | pub labels: Vec>, 120 | /// Notes that are associated with the primary cause of the diagnostic. 121 | /// These can include line breaks for improved formatting. 122 | pub notes: Vec, 123 | } 124 | 125 | impl Diagnostic { 126 | /// Create a new diagnostic. 127 | pub fn new(severity: Severity) -> Diagnostic { 128 | Diagnostic { 129 | severity, 130 | code: None, 131 | message: String::new(), 132 | labels: Vec::new(), 133 | notes: Vec::new(), 134 | } 135 | } 136 | 137 | /// Create a new diagnostic with a severity of [`Severity::Bug`]. 138 | /// 139 | /// [`Severity::Bug`]: Severity::Bug 140 | pub fn bug() -> Diagnostic { 141 | Diagnostic::new(Severity::Bug) 142 | } 143 | 144 | /// Create a new diagnostic with a severity of [`Severity::Error`]. 145 | /// 146 | /// [`Severity::Error`]: Severity::Error 147 | pub fn error() -> Diagnostic { 148 | Diagnostic::new(Severity::Error) 149 | } 150 | 151 | /// Create a new diagnostic with a severity of [`Severity::Warning`]. 152 | /// 153 | /// [`Severity::Warning`]: Severity::Warning 154 | pub fn warning() -> Diagnostic { 155 | Diagnostic::new(Severity::Warning) 156 | } 157 | 158 | /// Create a new diagnostic with a severity of [`Severity::Note`]. 159 | /// 160 | /// [`Severity::Note`]: Severity::Note 161 | pub fn note() -> Diagnostic { 162 | Diagnostic::new(Severity::Note) 163 | } 164 | 165 | /// Create a new diagnostic with a severity of [`Severity::Help`]. 166 | /// 167 | /// [`Severity::Help`]: Severity::Help 168 | pub fn help() -> Diagnostic { 169 | Diagnostic::new(Severity::Help) 170 | } 171 | 172 | /// Set the error code of the diagnostic. 173 | pub fn with_code(mut self, code: impl ToString) -> Diagnostic { 174 | self.code = Some(code.to_string()); 175 | self 176 | } 177 | 178 | /// Set the message of the diagnostic. 179 | pub fn with_message(mut self, message: impl ToString) -> Diagnostic { 180 | self.message = message.to_string(); 181 | self 182 | } 183 | 184 | /// Add a label to the diagnostic. 185 | pub fn with_label(mut self, label: Label) -> Diagnostic { 186 | self.labels.push(label); 187 | self 188 | } 189 | 190 | /// Add some labels to the diagnostic. 191 | pub fn with_labels(mut self, mut labels: Vec>) -> Diagnostic { 192 | self.labels.append(&mut labels); 193 | self 194 | } 195 | 196 | /// Add some labels to the diagnostic. 197 | pub fn with_labels_iter( 198 | mut self, 199 | labels: impl IntoIterator>, 200 | ) -> Diagnostic { 201 | self.labels.extend(labels); 202 | self 203 | } 204 | 205 | /// Add a note to the diagnostic. 206 | pub fn with_note(mut self, note: impl ToString) -> Diagnostic { 207 | self.notes.push(note.to_string()); 208 | self 209 | } 210 | 211 | /// Add some notes to the diagnostic. 212 | pub fn with_notes(mut self, mut notes: Vec) -> Diagnostic { 213 | self.notes.append(&mut notes); 214 | self 215 | } 216 | 217 | /// Add some notes to the diagnostic. 218 | pub fn with_notes_iter( 219 | mut self, 220 | notes: impl IntoIterator, 221 | ) -> Diagnostic { 222 | self.notes.extend(notes); 223 | self 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /codespan-reporting/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Diagnostic reporting support for the codespan crate. 2 | 3 | #![forbid(unsafe_code)] 4 | #![no_std] 5 | 6 | extern crate alloc; 7 | 8 | #[cfg(feature = "std")] 9 | extern crate std; 10 | 11 | pub mod diagnostic; 12 | pub mod files; 13 | pub mod term; 14 | -------------------------------------------------------------------------------- /codespan-reporting/src/term.rs: -------------------------------------------------------------------------------- 1 | //! Terminal back-end for emitting diagnostics. 2 | 3 | #[cfg(feature = "termcolor")] 4 | use termcolor::WriteColor; 5 | 6 | use crate::diagnostic::Diagnostic; 7 | use crate::files::Files; 8 | 9 | mod config; 10 | mod renderer; 11 | mod views; 12 | 13 | #[cfg(feature = "termcolor")] 14 | pub use termcolor; 15 | 16 | pub use self::config::{Chars, Config, DisplayStyle}; 17 | 18 | #[cfg(feature = "termcolor")] 19 | pub use self::config::Styles; 20 | 21 | /// Emit a diagnostic using the given writer, context, config, and files. 22 | /// 23 | /// The return value covers all error cases. These error case can arise if: 24 | /// * a file was removed from the file database. 25 | /// * a file was changed so that it is too small to have an index 26 | /// * IO fails 27 | pub fn emit<'files, F: Files<'files> + ?Sized>( 28 | #[cfg(feature = "termcolor")] writer: &mut dyn WriteColor, 29 | #[cfg(all(not(feature = "termcolor"), feature = "std"))] writer: &mut dyn std::io::Write, 30 | #[cfg(all(not(feature = "termcolor"), not(feature = "std")))] writer: &mut dyn core::fmt::Write, 31 | config: &Config, 32 | files: &'files F, 33 | diagnostic: &Diagnostic, 34 | ) -> Result<(), super::files::Error> { 35 | use self::renderer::Renderer; 36 | use self::views::{RichDiagnostic, ShortDiagnostic}; 37 | 38 | let mut renderer = Renderer::new(writer, config); 39 | match config.display_style { 40 | DisplayStyle::Rich => RichDiagnostic::new(diagnostic, config).render(files, &mut renderer), 41 | DisplayStyle::Medium => ShortDiagnostic::new(diagnostic, true).render(files, &mut renderer), 42 | DisplayStyle::Short => ShortDiagnostic::new(diagnostic, false).render(files, &mut renderer), 43 | } 44 | } 45 | 46 | #[cfg(all(test, feature = "termcolor"))] 47 | mod tests { 48 | use alloc::{vec, vec::Vec}; 49 | 50 | use super::*; 51 | 52 | use crate::diagnostic::Label; 53 | use crate::files::SimpleFiles; 54 | 55 | #[test] 56 | fn unsized_emit() { 57 | let mut files = SimpleFiles::new(); 58 | 59 | let id = files.add("test", ""); 60 | let mut writer = termcolor::NoColor::new(Vec::::new()); 61 | let diagnostic = Diagnostic::bug().with_labels(vec![Label::primary(id, 0..0)]); 62 | 63 | emit(&mut writer, &Config::default(), &files, &diagnostic).unwrap(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /codespan-reporting/src/term/config.rs: -------------------------------------------------------------------------------- 1 | use alloc::string::String; 2 | 3 | #[cfg(feature = "termcolor")] 4 | use { 5 | crate::diagnostic::{LabelStyle, Severity}, 6 | termcolor::{Color, ColorSpec}, 7 | }; 8 | 9 | /// Configures how a diagnostic is rendered. 10 | #[derive(Clone, Debug)] 11 | pub struct Config { 12 | /// The display style to use when rendering diagnostics. 13 | /// Defaults to: [`DisplayStyle::Rich`]. 14 | /// 15 | /// [`DisplayStyle::Rich`]: DisplayStyle::Rich 16 | pub display_style: DisplayStyle, 17 | /// Column width of tabs. 18 | /// Defaults to: `4`. 19 | pub tab_width: usize, 20 | /// Styles to use when rendering the diagnostic. 21 | #[cfg(feature = "termcolor")] 22 | pub styles: Styles, 23 | /// Characters to use when rendering the diagnostic. 24 | pub chars: Chars, 25 | /// The minimum number of lines to be shown after the line on which a multiline [`Label`] begins. 26 | /// 27 | /// Defaults to: `3`. 28 | /// 29 | /// [`Label`]: crate::diagnostic::Label 30 | pub start_context_lines: usize, 31 | /// The minimum number of lines to be shown before the line on which a multiline [`Label`] ends. 32 | /// 33 | /// Defaults to: `1`. 34 | /// 35 | /// [`Label`]: crate::diagnostic::Label 36 | pub end_context_lines: usize, 37 | /// The minimum number of lines before a label that should be included for context. 38 | /// 39 | /// Defaults to: `0`. 40 | pub before_label_lines: usize, 41 | /// The minimum number of lines after a label that should be included for context. 42 | /// 43 | /// Defaults to: `0`. 44 | pub after_label_lines: usize, 45 | } 46 | 47 | impl Default for Config { 48 | fn default() -> Config { 49 | Config { 50 | display_style: DisplayStyle::Rich, 51 | tab_width: 4, 52 | #[cfg(feature = "termcolor")] 53 | styles: Styles::default(), 54 | chars: Chars::default(), 55 | start_context_lines: 3, 56 | end_context_lines: 1, 57 | before_label_lines: 0, 58 | after_label_lines: 0, 59 | } 60 | } 61 | } 62 | 63 | /// The display style to use when rendering diagnostics. 64 | #[derive(Clone, Debug)] 65 | pub enum DisplayStyle { 66 | /// Output a richly formatted diagnostic, with source code previews. 67 | /// 68 | /// ```text 69 | /// error[E0001]: unexpected type in `+` application 70 | /// ┌─ test:2:9 71 | /// │ 72 | /// 2 │ (+ test "") 73 | /// │ ^^ expected `Int` but found `String` 74 | /// │ 75 | /// = expected type `Int` 76 | /// found type `String` 77 | /// 78 | /// error[E0002]: Bad config found 79 | /// 80 | /// ``` 81 | Rich, 82 | /// Output a condensed diagnostic, with a line number, severity, message and notes (if any). 83 | /// 84 | /// ```text 85 | /// test:2:9: error[E0001]: unexpected type in `+` application 86 | /// = expected type `Int` 87 | /// found type `String` 88 | /// 89 | /// error[E0002]: Bad config found 90 | /// ``` 91 | Medium, 92 | /// Output a short diagnostic, with a line number, severity, and message. 93 | /// 94 | /// ```text 95 | /// test:2:9: error[E0001]: unexpected type in `+` application 96 | /// error[E0002]: Bad config found 97 | /// ``` 98 | Short, 99 | } 100 | 101 | /// Styles to use when rendering the diagnostic. 102 | #[cfg(feature = "termcolor")] 103 | #[derive(Clone, Debug)] 104 | pub struct Styles { 105 | /// The style to use when rendering bug headers. 106 | /// Defaults to `fg:red bold intense`. 107 | pub header_bug: ColorSpec, 108 | /// The style to use when rendering error headers. 109 | /// Defaults to `fg:red bold intense`. 110 | pub header_error: ColorSpec, 111 | /// The style to use when rendering warning headers. 112 | /// Defaults to `fg:yellow bold intense`. 113 | pub header_warning: ColorSpec, 114 | /// The style to use when rendering note headers. 115 | /// Defaults to `fg:green bold intense`. 116 | pub header_note: ColorSpec, 117 | /// The style to use when rendering help headers. 118 | /// Defaults to `fg:cyan bold intense`. 119 | pub header_help: ColorSpec, 120 | /// The style to use when the main diagnostic message. 121 | /// Defaults to `bold intense`. 122 | pub header_message: ColorSpec, 123 | 124 | /// The style to use when rendering bug labels. 125 | /// Defaults to `fg:red`. 126 | pub primary_label_bug: ColorSpec, 127 | /// The style to use when rendering error labels. 128 | /// Defaults to `fg:red`. 129 | pub primary_label_error: ColorSpec, 130 | /// The style to use when rendering warning labels. 131 | /// Defaults to `fg:yellow`. 132 | pub primary_label_warning: ColorSpec, 133 | /// The style to use when rendering note labels. 134 | /// Defaults to `fg:green`. 135 | pub primary_label_note: ColorSpec, 136 | /// The style to use when rendering help labels. 137 | /// Defaults to `fg:cyan`. 138 | pub primary_label_help: ColorSpec, 139 | /// The style to use when rendering secondary labels. 140 | /// Defaults `fg:blue` (or `fg:cyan` on windows). 141 | pub secondary_label: ColorSpec, 142 | 143 | /// The style to use when rendering the line numbers. 144 | /// Defaults `fg:blue` (or `fg:cyan` on windows). 145 | pub line_number: ColorSpec, 146 | /// The style to use when rendering the source code borders. 147 | /// Defaults `fg:blue` (or `fg:cyan` on windows). 148 | pub source_border: ColorSpec, 149 | /// The style to use when rendering the note bullets. 150 | /// Defaults `fg:blue` (or `fg:cyan` on windows). 151 | pub note_bullet: ColorSpec, 152 | } 153 | 154 | #[cfg(feature = "termcolor")] 155 | impl Styles { 156 | /// The style used to mark a header at a given severity. 157 | pub fn header(&self, severity: Severity) -> &ColorSpec { 158 | match severity { 159 | Severity::Bug => &self.header_bug, 160 | Severity::Error => &self.header_error, 161 | Severity::Warning => &self.header_warning, 162 | Severity::Note => &self.header_note, 163 | Severity::Help => &self.header_help, 164 | } 165 | } 166 | 167 | /// The style used to mark a primary or secondary label at a given severity. 168 | pub fn label(&self, severity: Severity, label_style: LabelStyle) -> &ColorSpec { 169 | match (label_style, severity) { 170 | (LabelStyle::Primary, Severity::Bug) => &self.primary_label_bug, 171 | (LabelStyle::Primary, Severity::Error) => &self.primary_label_error, 172 | (LabelStyle::Primary, Severity::Warning) => &self.primary_label_warning, 173 | (LabelStyle::Primary, Severity::Note) => &self.primary_label_note, 174 | (LabelStyle::Primary, Severity::Help) => &self.primary_label_help, 175 | (LabelStyle::Secondary, _) => &self.secondary_label, 176 | } 177 | } 178 | 179 | #[doc(hidden)] 180 | pub fn with_blue(blue: Color) -> Styles { 181 | let header = ColorSpec::new().set_bold(true).set_intense(true).clone(); 182 | 183 | Styles { 184 | header_bug: header.clone().set_fg(Some(Color::Red)).clone(), 185 | header_error: header.clone().set_fg(Some(Color::Red)).clone(), 186 | header_warning: header.clone().set_fg(Some(Color::Yellow)).clone(), 187 | header_note: header.clone().set_fg(Some(Color::Green)).clone(), 188 | header_help: header.clone().set_fg(Some(Color::Cyan)).clone(), 189 | header_message: header, 190 | 191 | primary_label_bug: ColorSpec::new().set_fg(Some(Color::Red)).clone(), 192 | primary_label_error: ColorSpec::new().set_fg(Some(Color::Red)).clone(), 193 | primary_label_warning: ColorSpec::new().set_fg(Some(Color::Yellow)).clone(), 194 | primary_label_note: ColorSpec::new().set_fg(Some(Color::Green)).clone(), 195 | primary_label_help: ColorSpec::new().set_fg(Some(Color::Cyan)).clone(), 196 | secondary_label: ColorSpec::new().set_fg(Some(blue)).clone(), 197 | 198 | line_number: ColorSpec::new().set_fg(Some(blue)).clone(), 199 | source_border: ColorSpec::new().set_fg(Some(blue)).clone(), 200 | note_bullet: ColorSpec::new().set_fg(Some(blue)).clone(), 201 | } 202 | } 203 | } 204 | 205 | #[cfg(feature = "termcolor")] 206 | impl Default for Styles { 207 | fn default() -> Styles { 208 | // Blue is really difficult to see on the standard windows command line 209 | #[cfg(windows)] 210 | const BLUE: Color = Color::Cyan; 211 | #[cfg(not(windows))] 212 | const BLUE: Color = Color::Blue; 213 | 214 | Self::with_blue(BLUE) 215 | } 216 | } 217 | 218 | /// Characters to use when rendering the diagnostic. 219 | /// 220 | /// By using [`Chars::ascii()`] you can switch to an ASCII-only format suitable 221 | /// for rendering on terminals that do not support box drawing characters. 222 | #[derive(Clone, Debug)] 223 | pub struct Chars { 224 | /// The characters to use for the top-left border of the snippet. 225 | /// Defaults to: `"┌─"` or `"-->"` with [`Chars::ascii()`]. 226 | pub snippet_start: String, 227 | /// The character to use for the left border of the source. 228 | /// Defaults to: `'│'` or `'|'` with [`Chars::ascii()`]. 229 | pub source_border_left: char, 230 | /// The character to use for the left border break of the source. 231 | /// Defaults to: `'·'` or `'.'` with [`Chars::ascii()`]. 232 | pub source_border_left_break: char, 233 | 234 | /// The character to use for the note bullet. 235 | /// Defaults to: `'='`. 236 | pub note_bullet: char, 237 | 238 | /// The character to use for marking a single-line primary label. 239 | /// Defaults to: `'^'`. 240 | pub single_primary_caret: char, 241 | /// The character to use for marking a single-line secondary label. 242 | /// Defaults to: `'-'`. 243 | pub single_secondary_caret: char, 244 | 245 | /// The character to use for marking the start of a multi-line primary label. 246 | /// Defaults to: `'^'`. 247 | pub multi_primary_caret_start: char, 248 | /// The character to use for marking the end of a multi-line primary label. 249 | /// Defaults to: `'^'`. 250 | pub multi_primary_caret_end: char, 251 | /// The character to use for marking the start of a multi-line secondary label. 252 | /// Defaults to: `'\''`. 253 | pub multi_secondary_caret_start: char, 254 | /// The character to use for marking the end of a multi-line secondary label. 255 | /// Defaults to: `'\''`. 256 | pub multi_secondary_caret_end: char, 257 | /// The character to use for the top-left corner of a multi-line label. 258 | /// Defaults to: `'╭'` or `'/'` with [`Chars::ascii()`]. 259 | pub multi_top_left: char, 260 | /// The character to use for the top of a multi-line label. 261 | /// Defaults to: `'─'` or `'-'` with [`Chars::ascii()`]. 262 | pub multi_top: char, 263 | /// The character to use for the bottom-left corner of a multi-line label. 264 | /// Defaults to: `'╰'` or `'\'` with [`Chars::ascii()`]. 265 | pub multi_bottom_left: char, 266 | /// The character to use when marking the bottom of a multi-line label. 267 | /// Defaults to: `'─'` or `'-'` with [`Chars::ascii()`]. 268 | pub multi_bottom: char, 269 | /// The character to use for the left of a multi-line label. 270 | /// Defaults to: `'│'` or `'|'` with [`Chars::ascii()`]. 271 | pub multi_left: char, 272 | 273 | /// The character to use for the left of a pointer underneath a caret. 274 | /// Defaults to: `'│'` or `'|'` with [`Chars::ascii()`]. 275 | pub pointer_left: char, 276 | } 277 | 278 | impl Default for Chars { 279 | fn default() -> Chars { 280 | Chars::box_drawing() 281 | } 282 | } 283 | 284 | impl Chars { 285 | /// A character set that uses Unicode box drawing characters. 286 | pub fn box_drawing() -> Chars { 287 | Chars { 288 | snippet_start: "┌─".into(), 289 | source_border_left: '│', 290 | source_border_left_break: '·', 291 | 292 | note_bullet: '=', 293 | 294 | single_primary_caret: '^', 295 | single_secondary_caret: '-', 296 | 297 | multi_primary_caret_start: '^', 298 | multi_primary_caret_end: '^', 299 | multi_secondary_caret_start: '\'', 300 | multi_secondary_caret_end: '\'', 301 | multi_top_left: '╭', 302 | multi_top: '─', 303 | multi_bottom_left: '╰', 304 | multi_bottom: '─', 305 | multi_left: '│', 306 | 307 | pointer_left: '│', 308 | } 309 | } 310 | 311 | /// A character set that only uses ASCII characters. 312 | /// 313 | /// This is useful if your terminal's font does not support box drawing 314 | /// characters well and results in output that looks similar to rustc's 315 | /// diagnostic output. 316 | pub fn ascii() -> Chars { 317 | Chars { 318 | snippet_start: "-->".into(), 319 | source_border_left: '|', 320 | source_border_left_break: '.', 321 | 322 | note_bullet: '=', 323 | 324 | single_primary_caret: '^', 325 | single_secondary_caret: '-', 326 | 327 | multi_primary_caret_start: '^', 328 | multi_primary_caret_end: '^', 329 | multi_secondary_caret_start: '\'', 330 | multi_secondary_caret_end: '\'', 331 | multi_top_left: '/', 332 | multi_top: '-', 333 | multi_bottom_left: '\\', 334 | multi_bottom: '-', 335 | multi_left: '|', 336 | 337 | pointer_left: '|', 338 | } 339 | } 340 | } 341 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}bug{bold bright}: {/} 6 | {fg:Red bold bright}error{bold bright}: {/} 7 | {fg:Yellow bold bright}warning{bold bright}: {/} 8 | {fg:Green bold bright}note{bold bright}: {/} 9 | {fg:Cyan bold bright}help{bold bright}: {/} 10 | {fg:Red bold bright}bug{bold bright}: {/} 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | bug: 6 | error: 7 | warning: 8 | note: 9 | help: 10 | bug: 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | bug: 6 | 7 | error: 8 | 9 | warning: 10 | 11 | note: 12 | 13 | help: 14 | 15 | bug: 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}bug{bold bright}: {/} 6 | 7 | {fg:Red bold bright}error{bold bright}: {/} 8 | 9 | {fg:Yellow bold bright}warning{bold bright}: {/} 10 | 11 | {fg:Green bold bright}note{bold bright}: {/} 12 | 13 | {fg:Cyan bold bright}help{bold bright}: {/} 14 | 15 | {fg:Red bold bright}bug{bold bright}: {/} 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | bug: 6 | 7 | error: 8 | 9 | warning: 10 | 11 | note: 12 | 13 | help: 14 | 15 | bug: 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}bug{bold bright}: {/} 6 | {fg:Red bold bright}error{bold bright}: {/} 7 | {fg:Yellow bold bright}warning{bold bright}: {/} 8 | {fg:Green bold bright}note{bold bright}: {/} 9 | {fg:Cyan bold bright}help{bold bright}: {/} 10 | {fg:Red bold bright}bug{bold bright}: {/} 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | bug: 6 | error: 7 | warning: 8 | note: 9 | help: 10 | bug: 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty_ranges__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | hello:1:7: {fg:Green bold bright}note{bold bright}: middle{/} 6 | hello:1:13: {fg:Green bold bright}note{bold bright}: end of line{/} 7 | hello:2:11: {fg:Green bold bright}note{bold bright}: end of line{/} 8 | hello:3:4: {fg:Green bold bright}note{bold bright}: end of file{/} 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty_ranges__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | hello:1:7: note: middle 6 | hello:1:13: note: end of line 7 | hello:2:11: note: end of line 8 | hello:3:4: note: end of file 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty_ranges__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | note: middle 6 | --> hello:1:7 7 | | 8 | 1 | Hello world! 9 | | ^ middle 10 | 11 | note: end of line 12 | --> hello:1:13 13 | | 14 | 1 | Hello world! 15 | | ^ end of line 16 | 17 | note: end of line 18 | --> hello:2:11 19 | | 20 | 2 | Bye world! 21 | | ^ end of line 22 | 23 | note: end of file 24 | --> hello:3:4 25 | | 26 | 3 | 27 | | ^ end of file 28 | 29 | 30 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty_ranges__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Green bold bright}note{bold bright}: middle{/} 6 | {fg:Blue}┌─{/} hello:1:7 7 | {fg:Blue}│{/} 8 | {fg:Blue}1{/} {fg:Blue}│{/} Hello {fg:Green}w{/}orld! 9 | {fg:Blue}│{/} {fg:Green}^{/} {fg:Green}middle{/} 10 | 11 | {fg:Green bold bright}note{bold bright}: end of line{/} 12 | {fg:Blue}┌─{/} hello:1:13 13 | {fg:Blue}│{/} 14 | {fg:Blue}1{/} {fg:Blue}│{/} Hello world! 15 | {fg:Blue}│{/} {fg:Green}^{/} {fg:Green}end of line{/} 16 | 17 | {fg:Green bold bright}note{bold bright}: end of line{/} 18 | {fg:Blue}┌─{/} hello:2:11 19 | {fg:Blue}│{/} 20 | {fg:Blue}2{/} {fg:Blue}│{/} Bye world! 21 | {fg:Blue}│{/} {fg:Green}^{/} {fg:Green}end of line{/} 22 | 23 | {fg:Green bold bright}note{bold bright}: end of file{/} 24 | {fg:Blue}┌─{/} hello:3:4 25 | {fg:Blue}│{/} 26 | {fg:Blue}3{/} {fg:Blue}│{/} 27 | {fg:Blue}│{/} {fg:Green}^{/} {fg:Green}end of file{/} 28 | 29 | 30 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty_ranges__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | note: middle 6 | ┌─ hello:1:7 7 | │ 8 | 1 │ Hello world! 9 | │ ^ middle 10 | 11 | note: end of line 12 | ┌─ hello:1:13 13 | │ 14 | 1 │ Hello world! 15 | │ ^ end of line 16 | 17 | note: end of line 18 | ┌─ hello:2:11 19 | │ 20 | 2 │ Bye world! 21 | │ ^ end of line 22 | 23 | note: end of file 24 | ┌─ hello:3:4 25 | │ 26 | 3 │ 27 | │ ^ end of file 28 | 29 | 30 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty_ranges__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | hello:1:7: {fg:Green bold bright}note{bold bright}: middle{/} 6 | hello:1:13: {fg:Green bold bright}note{bold bright}: end of line{/} 7 | hello:2:11: {fg:Green bold bright}note{bold bright}: end of line{/} 8 | hello:3:4: {fg:Green bold bright}note{bold bright}: end of file{/} 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__empty_ranges__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | hello:1:7: note: middle 6 | hello:1:13: note: end of line 7 | hello:2:11: note: end of line 8 | hello:3:4: note: end of file 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__fizz_buzz__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | FizzBuzz.fun:8:12: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/} 6 | {fg:Blue}={/} expected type `String` 7 | found type `Nat` 8 | FizzBuzz.fun:16:16: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/} 9 | {fg:Blue}={/} expected type `String` 10 | found type `Nat` 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__fizz_buzz__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | FizzBuzz.fun:8:12: error[E0308]: `case` clauses have incompatible types 6 | = expected type `String` 7 | found type `Nat` 8 | FizzBuzz.fun:16:16: error[E0308]: `case` clauses have incompatible types 9 | = expected type `String` 10 | found type `Nat` 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__fizz_buzz__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0308]: `case` clauses have incompatible types 6 | --> FizzBuzz.fun:8:12 7 | | 8 | 3 | fizz₁ : Nat → String 9 | | ------ expected type `String` found here 10 | 4 | fizz₁ num = case (mod num 5) (mod num 3) of 11 | | /-------------' 12 | 5 | | 0 0 => "FizzBuzz" 13 | 6 | | 0 _ => "Fizz" 14 | 7 | | _ 0 => "Buzz" 15 | 8 | | _ _ => num 16 | | | ^^^ expected `String`, found `Nat` 17 | | \--------------' `case` clauses have incompatible types 18 | | 19 | = expected type `String` 20 | found type `Nat` 21 | 22 | error[E0308]: `case` clauses have incompatible types 23 | --> FizzBuzz.fun:16:16 24 | | 25 | 10 | fizz₂ : Nat → String 26 | | ------ expected type `String` found here 27 | 11 | fizz₂ num = 28 | 12 | / case (mod num 5) (mod num 3) of 29 | 13 | | 0 0 => "FizzBuzz" 30 | | | ---------- this is found to be of type `String` 31 | 14 | | 0 _ => "Fizz" 32 | | | ------ this is found to be of type `String` 33 | 15 | | _ 0 => "Buzz" 34 | | | ------ this is found to be of type `String` 35 | 16 | | _ _ => num 36 | | | ^^^ expected `String`, found `Nat` 37 | | \------------------' `case` clauses have incompatible types 38 | | 39 | = expected type `String` 40 | found type `Nat` 41 | 42 | 43 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__fizz_buzz__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/} 6 | {fg:Blue}┌─{/} FizzBuzz.fun:8:12 7 | {fg:Blue}│{/} 8 | {fg:Blue}3{/} {fg:Blue}│{/} fizz₁ : Nat → String 9 | {fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}expected type `String` found here{/} 10 | {fg:Blue}4{/} {fg:Blue}│{/} fizz₁ num = case (mod num 5) (mod num 3) of 11 | {fg:Blue}│{/} {fg:Blue}╭{/}{fg:Blue}─────────────'{/} 12 | {fg:Blue}5{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 0 => "FizzBuzz" 13 | {fg:Blue}6{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 _ => "Fizz" 14 | {fg:Blue}7{/} {fg:Blue}│{/} {fg:Blue}│{/} _ 0 => "Buzz" 15 | {fg:Blue}8{/} {fg:Blue}│{/} {fg:Blue}│{/} _ _ => {fg:Red}num{/} 16 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}^^^{/} {fg:Red}expected `String`, found `Nat`{/} 17 | {fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}──────────────' `case` clauses have incompatible types{/} 18 | {fg:Blue}│{/} 19 | {fg:Blue}={/} expected type `String` 20 | found type `Nat` 21 | 22 | {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/} 23 | {fg:Blue}┌─{/} FizzBuzz.fun:16:16 24 | {fg:Blue}│{/} 25 | {fg:Blue}10{/} {fg:Blue}│{/} fizz₂ : Nat → String 26 | {fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}expected type `String` found here{/} 27 | {fg:Blue}11{/} {fg:Blue}│{/} fizz₂ num = 28 | {fg:Blue}12{/} {fg:Blue}│{/} {fg:Blue}╭{/} case (mod num 5) (mod num 3) of 29 | {fg:Blue}13{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 0 => "FizzBuzz" 30 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}----------{/} {fg:Blue}this is found to be of type `String`{/} 31 | {fg:Blue}14{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 _ => "Fizz" 32 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}this is found to be of type `String`{/} 33 | {fg:Blue}15{/} {fg:Blue}│{/} {fg:Blue}│{/} _ 0 => "Buzz" 34 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}this is found to be of type `String`{/} 35 | {fg:Blue}16{/} {fg:Blue}│{/} {fg:Blue}│{/} _ _ => {fg:Red}num{/} 36 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}^^^{/} {fg:Red}expected `String`, found `Nat`{/} 37 | {fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}──────────────────' `case` clauses have incompatible types{/} 38 | {fg:Blue}│{/} 39 | {fg:Blue}={/} expected type `String` 40 | found type `Nat` 41 | 42 | 43 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__fizz_buzz__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0308]: `case` clauses have incompatible types 6 | ┌─ FizzBuzz.fun:8:12 7 | │ 8 | 3 │ fizz₁ : Nat → String 9 | │ ------ expected type `String` found here 10 | 4 │ fizz₁ num = case (mod num 5) (mod num 3) of 11 | │ ╭─────────────' 12 | 5 │ │ 0 0 => "FizzBuzz" 13 | 6 │ │ 0 _ => "Fizz" 14 | 7 │ │ _ 0 => "Buzz" 15 | 8 │ │ _ _ => num 16 | │ │ ^^^ expected `String`, found `Nat` 17 | │ ╰──────────────' `case` clauses have incompatible types 18 | │ 19 | = expected type `String` 20 | found type `Nat` 21 | 22 | error[E0308]: `case` clauses have incompatible types 23 | ┌─ FizzBuzz.fun:16:16 24 | │ 25 | 10 │ fizz₂ : Nat → String 26 | │ ------ expected type `String` found here 27 | 11 │ fizz₂ num = 28 | 12 │ ╭ case (mod num 5) (mod num 3) of 29 | 13 │ │ 0 0 => "FizzBuzz" 30 | │ │ ---------- this is found to be of type `String` 31 | 14 │ │ 0 _ => "Fizz" 32 | │ │ ------ this is found to be of type `String` 33 | 15 │ │ _ 0 => "Buzz" 34 | │ │ ------ this is found to be of type `String` 35 | 16 │ │ _ _ => num 36 | │ │ ^^^ expected `String`, found `Nat` 37 | │ ╰──────────────────' `case` clauses have incompatible types 38 | │ 39 | = expected type `String` 40 | found type `Nat` 41 | 42 | 43 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__fizz_buzz__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | FizzBuzz.fun:8:12: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/} 6 | FizzBuzz.fun:16:16: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/} 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__fizz_buzz__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | FizzBuzz.fun:8:12: error[E0308]: `case` clauses have incompatible types 6 | FizzBuzz.fun:16:16: error[E0308]: `case` clauses have incompatible types 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: a message{/} 6 | {fg:Yellow bold bright}warning{bold bright}: a message{/} 7 | {fg:Green bold bright}note{bold bright}: a message{/} 8 | {fg:Cyan bold bright}help{bold bright}: a message{/} 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | warning: a message 7 | note: a message 8 | help: a message 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | 7 | warning: a message 8 | 9 | note: a message 10 | 11 | help: a message 12 | 13 | 14 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: a message{/} 6 | 7 | {fg:Yellow bold bright}warning{bold bright}: a message{/} 8 | 9 | {fg:Green bold bright}note{bold bright}: a message{/} 10 | 11 | {fg:Cyan bold bright}help{bold bright}: a message{/} 12 | 13 | 14 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | 7 | warning: a message 8 | 9 | note: a message 10 | 11 | help: a message 12 | 13 | 14 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: a message{/} 6 | {fg:Yellow bold bright}warning{bold bright}: a message{/} 7 | {fg:Green bold bright}note{bold bright}: a message{/} 8 | {fg:Cyan bold bright}help{bold bright}: a message{/} 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | warning: a message 7 | note: a message 8 | help: a message 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_and_notes__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: a message{/} 6 | {fg:Blue}={/} a note 7 | {fg:Yellow bold bright}warning{bold bright}: a message{/} 8 | {fg:Blue}={/} a note 9 | {fg:Green bold bright}note{bold bright}: a message{/} 10 | {fg:Blue}={/} a note 11 | {fg:Cyan bold bright}help{bold bright}: a message{/} 12 | {fg:Blue}={/} a note 13 | 14 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_and_notes__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | = a note 7 | warning: a message 8 | = a note 9 | note: a message 10 | = a note 11 | help: a message 12 | = a note 13 | 14 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_and_notes__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | = a note 7 | 8 | warning: a message 9 | = a note 10 | 11 | note: a message 12 | = a note 13 | 14 | help: a message 15 | = a note 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_and_notes__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: a message{/} 6 | {fg:Blue}={/} a note 7 | 8 | {fg:Yellow bold bright}warning{bold bright}: a message{/} 9 | {fg:Blue}={/} a note 10 | 11 | {fg:Green bold bright}note{bold bright}: a message{/} 12 | {fg:Blue}={/} a note 13 | 14 | {fg:Cyan bold bright}help{bold bright}: a message{/} 15 | {fg:Blue}={/} a note 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_and_notes__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | = a note 7 | 8 | warning: a message 9 | = a note 10 | 11 | note: a message 12 | = a note 13 | 14 | help: a message 15 | = a note 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_and_notes__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: a message{/} 6 | {fg:Yellow bold bright}warning{bold bright}: a message{/} 7 | {fg:Green bold bright}note{bold bright}: a message{/} 8 | {fg:Cyan bold bright}help{bold bright}: a message{/} 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_and_notes__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: a message 6 | warning: a message 7 | note: a message 8 | help: a message 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_errorcode__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0001]: a message 6 | 7 | warning[W001]: a message 8 | 9 | note[N0815]: a message 10 | 11 | help[H4711]: a message 12 | 13 | error: where did my errorcode go? 14 | 15 | warning: where did my errorcode go? 16 | 17 | note: where did my errorcode go? 18 | 19 | help: where did my errorcode go? 20 | 21 | 22 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_errorcode__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0001]: a message 6 | 7 | warning[W001]: a message 8 | 9 | note[N0815]: a message 10 | 11 | help[H4711]: a message 12 | 13 | error: where did my errorcode go? 14 | 15 | warning: where did my errorcode go? 16 | 17 | note: where did my errorcode go? 18 | 19 | help: where did my errorcode go? 20 | 21 | 22 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__message_errorcode__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0001]: a message 6 | warning[W001]: a message 7 | note[N0815]: a message 8 | help[H4711]: a message 9 | error: where did my errorcode go? 10 | warning: where did my errorcode go? 11 | note: where did my errorcode go? 12 | help: where did my errorcode go? 13 | 14 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multifile__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | Data/Nat.fun:7:13: {fg:Red bold bright}error{bold bright}: unknown builtin: `NATRAL`{/} 6 | {fg:Blue}={/} there is a builtin with a similar name: `NATURAL` 7 | Data/Nat.fun:17:16: {fg:Yellow bold bright}warning{bold bright}: unused parameter pattern: `n₂`{/} 8 | {fg:Blue}={/} consider using a wildcard pattern: `_` 9 | Test.fun:4:11: {fg:Red bold bright}error[E0001]{bold bright}: unexpected type in application of `_+_`{/} 10 | {fg:Blue}={/} expected type `Nat` 11 | found type `String` 12 | 13 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multifile__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | Data/Nat.fun:7:13: error: unknown builtin: `NATRAL` 6 | = there is a builtin with a similar name: `NATURAL` 7 | Data/Nat.fun:17:16: warning: unused parameter pattern: `n₂` 8 | = consider using a wildcard pattern: `_` 9 | Test.fun:4:11: error[E0001]: unexpected type in application of `_+_` 10 | = expected type `Nat` 11 | found type `String` 12 | 13 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multifile__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: unknown builtin: `NATRAL` 6 | --> Data/Nat.fun:7:13 7 | | 8 | 7 | {-# BUILTIN NATRAL Nat #-} 9 | | ^^^^^^ unknown builtin 10 | | 11 | = there is a builtin with a similar name: `NATURAL` 12 | 13 | warning: unused parameter pattern: `n₂` 14 | --> Data/Nat.fun:17:16 15 | | 16 | 17 | zero - succ n₂ = zero 17 | | ^^ unused parameter 18 | | 19 | = consider using a wildcard pattern: `_` 20 | 21 | error[E0001]: unexpected type in application of `_+_` 22 | --> Test.fun:4:11 23 | | 24 | 4 | _ = 123 + "hello" 25 | | ^^^^^^^ expected `Nat`, found `String` 26 | | 27 | --> Data/Nat.fun:11:1 28 | | 29 | 11 | _+_ : Nat → Nat → Nat 30 | | --------------------- based on the definition of `_+_` 31 | | 32 | = expected type `Nat` 33 | found type `String` 34 | 35 | 36 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multifile__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: unknown builtin: `NATRAL`{/} 6 | {fg:Blue}┌─{/} Data/Nat.fun:7:13 7 | {fg:Blue}│{/} 8 | {fg:Blue}7{/} {fg:Blue}│{/} {-# BUILTIN {fg:Red}NATRAL{/} Nat #-} 9 | {fg:Blue}│{/} {fg:Red}^^^^^^{/} {fg:Red}unknown builtin{/} 10 | {fg:Blue}│{/} 11 | {fg:Blue}={/} there is a builtin with a similar name: `NATURAL` 12 | 13 | {fg:Yellow bold bright}warning{bold bright}: unused parameter pattern: `n₂`{/} 14 | {fg:Blue}┌─{/} Data/Nat.fun:17:16 15 | {fg:Blue}│{/} 16 | {fg:Blue}17{/} {fg:Blue}│{/} zero - succ {fg:Yellow}n₂{/} = zero 17 | {fg:Blue}│{/} {fg:Yellow}^^{/} {fg:Yellow}unused parameter{/} 18 | {fg:Blue}│{/} 19 | {fg:Blue}={/} consider using a wildcard pattern: `_` 20 | 21 | {fg:Red bold bright}error[E0001]{bold bright}: unexpected type in application of `_+_`{/} 22 | {fg:Blue}┌─{/} Test.fun:4:11 23 | {fg:Blue}│{/} 24 | {fg:Blue} 4{/} {fg:Blue}│{/} _ = 123 + {fg:Red}"hello"{/} 25 | {fg:Blue}│{/} {fg:Red}^^^^^^^{/} {fg:Red}expected `Nat`, found `String`{/} 26 | {fg:Blue}│{/} 27 | {fg:Blue}┌─{/} Data/Nat.fun:11:1 28 | {fg:Blue}│{/} 29 | {fg:Blue}11{/} {fg:Blue}│{/} _+_ : Nat → Nat → Nat 30 | {fg:Blue}│{/} {fg:Blue}---------------------{/} {fg:Blue}based on the definition of `_+_`{/} 31 | {fg:Blue}│{/} 32 | {fg:Blue}={/} expected type `Nat` 33 | found type `String` 34 | 35 | 36 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multifile__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: unknown builtin: `NATRAL` 6 | ┌─ Data/Nat.fun:7:13 7 | │ 8 | 7 │ {-# BUILTIN NATRAL Nat #-} 9 | │ ^^^^^^ unknown builtin 10 | │ 11 | = there is a builtin with a similar name: `NATURAL` 12 | 13 | warning: unused parameter pattern: `n₂` 14 | ┌─ Data/Nat.fun:17:16 15 | │ 16 | 17 │ zero - succ n₂ = zero 17 | │ ^^ unused parameter 18 | │ 19 | = consider using a wildcard pattern: `_` 20 | 21 | error[E0001]: unexpected type in application of `_+_` 22 | ┌─ Test.fun:4:11 23 | │ 24 | 4 │ _ = 123 + "hello" 25 | │ ^^^^^^^ expected `Nat`, found `String` 26 | │ 27 | ┌─ Data/Nat.fun:11:1 28 | │ 29 | 11 │ _+_ : Nat → Nat → Nat 30 | │ --------------------- based on the definition of `_+_` 31 | │ 32 | = expected type `Nat` 33 | found type `String` 34 | 35 | 36 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multifile__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | Data/Nat.fun:7:13: {fg:Red bold bright}error{bold bright}: unknown builtin: `NATRAL`{/} 6 | Data/Nat.fun:17:16: {fg:Yellow bold bright}warning{bold bright}: unused parameter pattern: `n₂`{/} 7 | Test.fun:4:11: {fg:Red bold bright}error[E0001]{bold bright}: unexpected type in application of `_+_`{/} 8 | 9 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multifile__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | Data/Nat.fun:7:13: error: unknown builtin: `NATRAL` 6 | Data/Nat.fun:17:16: warning: unused parameter pattern: `n₂` 7 | Test.fun:4:11: error[E0001]: unexpected type in application of `_+_` 8 | 9 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_omit__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[empty_if]: empty elseif block 6 | ┌─ empty_if_comments.lua:1:1 7 | │ 8 | 1 │ ╭ elseif 3 then 9 | 2 │ │ 10 | 3 │ │ ╭ 11 | 4 │ │ │ 12 | 5 │ │ │ 13 | · │ │ 14 | 8 │ │ │ 15 | 9 │ │ │ 16 | │ │ ╰' content should be in here 17 | 10 │ │ else 18 | │ ╰───^ 19 | 20 | error[E0308]: mismatched types 21 | ┌─ src/lib.rs:2:6 22 | │ 23 | 2 │ 1 24 | │ ╭─────^ 25 | 3 │ │ + 1 26 | 4 │ │ + 1 27 | · │ 28 | 7 │ │ +1 29 | │ │ - missing whitespace 30 | 8 │ │ + 1 31 | 9 │ │ + 1 32 | 10 │ │ + 1 33 | │ ╰───────^ expected (), found integer 34 | │ 35 | = note: expected type `()` 36 | found type `{integer}` 37 | 38 | 39 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_overlapping__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | codespan/src/file.rs:4:34: {fg:Red bold bright}error[E0308]{bold bright}: match arms have incompatible types{/} 6 | {fg:Blue}={/} expected type `Result` 7 | found type `LineIndexOutOfBoundsError` 8 | 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_overlapping__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | codespan/src/file.rs:4:34: error[E0308]: match arms have incompatible types 6 | = expected type `Result` 7 | found type `LineIndexOutOfBoundsError` 8 | 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_overlapping__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0308]: match arms have incompatible types 6 | --> codespan/src/file.rs:4:34 7 | | 8 | 1 | / match line_index.compare(self.last_line_index()) { 9 | 2 | | Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]), 10 | | | --------------------------------------------- this is found to be of type `Result` 11 | 3 | | Ordering::Equal => Ok(self.source_span().end()), 12 | | | ---------------------------- this is found to be of type `Result` 13 | 4 | | Ordering::Greater => LineIndexOutOfBoundsError { 14 | | /-|----------------------------------^ 15 | 5 | | | given: line_index, 16 | 6 | | | max: self.last_line_index(), 17 | 7 | | | }, 18 | | \-|-------------^ expected enum `Result`, found struct `LineIndexOutOfBoundsError` 19 | 8 | | } 20 | | \---------' `match` arms have incompatible types 21 | | 22 | = expected type `Result` 23 | found type `LineIndexOutOfBoundsError` 24 | 25 | 26 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_overlapping__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error[E0308]{bold bright}: match arms have incompatible types{/} 6 | {fg:Blue}┌─{/} codespan/src/file.rs:4:34 7 | {fg:Blue}│{/} 8 | {fg:Blue}1{/} {fg:Blue}│{/} {fg:Blue}╭{/} match line_index.compare(self.last_line_index()) { 9 | {fg:Blue}2{/} {fg:Blue}│{/} {fg:Blue}│{/} Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]), 10 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}---------------------------------------------{/} {fg:Blue}this is found to be of type `Result`{/} 11 | {fg:Blue}3{/} {fg:Blue}│{/} {fg:Blue}│{/} Ordering::Equal => Ok(self.source_span().end()), 12 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}----------------------------{/} {fg:Blue}this is found to be of type `Result`{/} 13 | {fg:Blue}4{/} {fg:Blue}│{/} {fg:Blue}│{/} Ordering::Greater => {fg:Red}LineIndexOutOfBoundsError {{/} 14 | {fg:Blue}│{/} {fg:Red}╭{/}{fg:Red}─{/}{fg:Blue}│{/}{fg:Red}──────────────────────────────────^{/} 15 | {fg:Blue}5{/} {fg:Blue}│{/} {fg:Red}│{/} {fg:Blue}│{/} {fg:Red} given: line_index,{/} 16 | {fg:Blue}6{/} {fg:Blue}│{/} {fg:Red}│{/} {fg:Blue}│{/} {fg:Red} max: self.last_line_index(),{/} 17 | {fg:Blue}7{/} {fg:Blue}│{/} {fg:Red}│{/} {fg:Blue}│{/} {fg:Red} }{/}, 18 | {fg:Blue}│{/} {fg:Red}╰{/}{fg:Red}─{/}{fg:Blue}│{/}{fg:Red}─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`{/} 19 | {fg:Blue}8{/} {fg:Blue}│{/} {fg:Blue}│{/} } 20 | {fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}─────────' `match` arms have incompatible types{/} 21 | {fg:Blue}│{/} 22 | {fg:Blue}={/} expected type `Result` 23 | found type `LineIndexOutOfBoundsError` 24 | 25 | 26 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_overlapping__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0308]: match arms have incompatible types 6 | ┌─ codespan/src/file.rs:4:34 7 | │ 8 | 1 │ ╭ match line_index.compare(self.last_line_index()) { 9 | 2 │ │ Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]), 10 | │ │ --------------------------------------------- this is found to be of type `Result` 11 | 3 │ │ Ordering::Equal => Ok(self.source_span().end()), 12 | │ │ ---------------------------- this is found to be of type `Result` 13 | 4 │ │ Ordering::Greater => LineIndexOutOfBoundsError { 14 | │ ╭─│──────────────────────────────────^ 15 | 5 │ │ │ given: line_index, 16 | 6 │ │ │ max: self.last_line_index(), 17 | 7 │ │ │ }, 18 | │ ╰─│─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError` 19 | 8 │ │ } 20 | │ ╰─────────' `match` arms have incompatible types 21 | │ 22 | = expected type `Result` 23 | found type `LineIndexOutOfBoundsError` 24 | 25 | 26 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_overlapping__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | codespan/src/file.rs:4:34: {fg:Red bold bright}error[E0308]{bold bright}: match arms have incompatible types{/} 6 | 7 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__multiline_overlapping__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | codespan/src/file.rs:4:34: error[E0308]: match arms have incompatible types 6 | 7 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__overlapping__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | nested_impl_trait.rs:5:56: {fg:Red bold bright}error[E0666]{bold bright}: nested `impl Trait` is not allowed{/} 6 | typeck_type_placeholder_item.rs:1:18: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 7 | typeck_type_placeholder_item.rs:2:25: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 8 | typeck_type_placeholder_item.rs:2:28: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 9 | no_send_res_ports.rs:25:5: {fg:Red bold bright}error[E0277]{bold bright}: `std::rc::Rc<()>` cannot be sent between threads safely{/} 10 | {fg:Blue}={/} help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` 11 | {fg:Blue}={/} note: required because it appears within the type `Port<()>` 12 | {fg:Blue}={/} note: required because it appears within the type `main::Foo` 13 | {fg:Blue}={/} note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]` 14 | {fg:Red bold bright}error{bold bright}: aborting due 5 previous errors{/} 15 | {fg:Blue}={/} Some errors have detailed explanations: E0121, E0277, E0666. 16 | {fg:Blue}={/} For more information about an error, try `rustc --explain E0121`. 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__overlapping__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | nested_impl_trait.rs:5:56: error[E0666]: nested `impl Trait` is not allowed 6 | typeck_type_placeholder_item.rs:1:18: error[E0121]: the type placeholder `_` is not allowed within types on item signatures 7 | typeck_type_placeholder_item.rs:2:25: error[E0121]: the type placeholder `_` is not allowed within types on item signatures 8 | typeck_type_placeholder_item.rs:2:28: error[E0121]: the type placeholder `_` is not allowed within types on item signatures 9 | no_send_res_ports.rs:25:5: error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely 10 | = help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` 11 | = note: required because it appears within the type `Port<()>` 12 | = note: required because it appears within the type `main::Foo` 13 | = note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]` 14 | error: aborting due 5 previous errors 15 | = Some errors have detailed explanations: E0121, E0277, E0666. 16 | = For more information about an error, try `rustc --explain E0121`. 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__overlapping__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0666]: nested `impl Trait` is not allowed 6 | --> nested_impl_trait.rs:5:56 7 | | 8 | 5 | fn bad_in_ret_position(x: impl Into) -> impl Into { x } 9 | | ----------^^^^^^^^^^- 10 | | | | 11 | | | nested `impl Trait` here 12 | | outer `impl Trait` 13 | 14 | error[E0121]: the type placeholder `_` is not allowed within types on item signatures 15 | --> typeck_type_placeholder_item.rs:1:18 16 | | 17 | 1 | fn fn_test1() -> _ { 5 } 18 | | ^ 19 | | | 20 | | not allowed in type signatures 21 | | help: replace with the correct return type: `i32` 22 | 23 | error[E0121]: the type placeholder `_` is not allowed within types on item signatures 24 | --> typeck_type_placeholder_item.rs:2:25 25 | | 26 | 2 | fn fn_test2(x: i32) -> (_, _) { (x, x) } 27 | | -^--^- 28 | | || | 29 | | || not allowed in type signatures 30 | | |not allowed in type signatures 31 | | help: replace with the correct return type: `(i32, i32)` 32 | 33 | error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely 34 | --> no_send_res_ports.rs:25:5 35 | | 36 | 25 | thread::spawn(move|| { 37 | | ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely 38 | | /-------------------' 39 | 26 | | let y = x; 40 | 27 | | println!("{:?}", y); 41 | 28 | | }); 42 | | \------' within this `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]` 43 | | 44 | --> libstd/thread/mod.rs:5:8 45 | | 46 | 5 | F: Send + 'static, 47 | | ---- required by this bound in `std::thread::spawn` 48 | | 49 | = help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` 50 | = note: required because it appears within the type `Port<()>` 51 | = note: required because it appears within the type `main::Foo` 52 | = note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]` 53 | 54 | error: aborting due 5 previous errors 55 | = Some errors have detailed explanations: E0121, E0277, E0666. 56 | = For more information about an error, try `rustc --explain E0121`. 57 | 58 | 59 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__overlapping__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error[E0666]{bold bright}: nested `impl Trait` is not allowed{/} 6 | {fg:Blue}┌─{/} nested_impl_trait.rs:5:56 7 | {fg:Blue}│{/} 8 | {fg:Blue}5{/} {fg:Blue}│{/} fn bad_in_ret_position(x: impl Into) -> impl Into<{fg:Red}impl Debug{/}> { x } 9 | {fg:Blue}│{/} {fg:Blue}----------{fg:Red}^^^^^^^^^^{fg:Blue}-{/} 10 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}│{/} 11 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}nested `impl Trait` here{/} 12 | {fg:Blue}│{/} {fg:Blue}outer `impl Trait`{/} 13 | 14 | {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 15 | {fg:Blue}┌─{/} typeck_type_placeholder_item.rs:1:18 16 | {fg:Blue}│{/} 17 | {fg:Blue}1{/} {fg:Blue}│{/} fn fn_test1() -> {fg:Red}_{/} { 5 } 18 | {fg:Blue}│{/} {fg:Red}^{/} 19 | {fg:Blue}│{/} {fg:Red}│{/} 20 | {fg:Blue}│{/} {fg:Red}not allowed in type signatures{/} 21 | {fg:Blue}│{/} {fg:Blue}help: replace with the correct return type: `i32`{/} 22 | 23 | {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 24 | {fg:Blue}┌─{/} typeck_type_placeholder_item.rs:2:25 25 | {fg:Blue}│{/} 26 | {fg:Blue}2{/} {fg:Blue}│{/} fn fn_test2(x: i32) -> ({fg:Red}_{/}, {fg:Red}_{/}) { (x, x) } 27 | {fg:Blue}│{/} {fg:Blue}-{fg:Red}^{fg:Blue}--{fg:Red}^{fg:Blue}-{/} 28 | {fg:Blue}│{/} {fg:Blue}│{/}{fg:Red}│{/} {fg:Red}│{/} 29 | {fg:Blue}│{/} {fg:Blue}│{/}{fg:Red}│{/} {fg:Red}not allowed in type signatures{/} 30 | {fg:Blue}│{/} {fg:Blue}│{/}{fg:Red}not allowed in type signatures{/} 31 | {fg:Blue}│{/} {fg:Blue}help: replace with the correct return type: `(i32, i32)`{/} 32 | 33 | {fg:Red bold bright}error[E0277]{bold bright}: `std::rc::Rc<()>` cannot be sent between threads safely{/} 34 | {fg:Blue}┌─{/} no_send_res_ports.rs:25:5 35 | {fg:Blue}│{/} 36 | {fg:Blue}25{/} {fg:Blue}│{/} {fg:Red}thread::spawn{/}(move|| { 37 | {fg:Blue}│{/} {fg:Red}^^^^^^^^^^^^^{/} {fg:Red}`std::rc::Rc<()>` cannot be sent between threads safely{/} 38 | {fg:Blue}│{/} {fg:Blue}╭{/}{fg:Blue}───────────────────'{/} 39 | {fg:Blue}26{/} {fg:Blue}│{/} {fg:Blue}│{/} let y = x; 40 | {fg:Blue}27{/} {fg:Blue}│{/} {fg:Blue}│{/} println!("{:?}", y); 41 | {fg:Blue}28{/} {fg:Blue}│{/} {fg:Blue}│{/} }); 42 | {fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}──────' within this `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`{/} 43 | {fg:Blue}│{/} 44 | {fg:Blue}┌─{/} libstd/thread/mod.rs:5:8 45 | {fg:Blue}│{/} 46 | {fg:Blue} 5{/} {fg:Blue}│{/} F: Send + 'static, 47 | {fg:Blue}│{/} {fg:Blue}----{/} {fg:Blue}required by this bound in `std::thread::spawn`{/} 48 | {fg:Blue}│{/} 49 | {fg:Blue}={/} help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` 50 | {fg:Blue}={/} note: required because it appears within the type `Port<()>` 51 | {fg:Blue}={/} note: required because it appears within the type `main::Foo` 52 | {fg:Blue}={/} note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]` 53 | 54 | {fg:Red bold bright}error{bold bright}: aborting due 5 previous errors{/} 55 | {fg:Blue}={/} Some errors have detailed explanations: E0121, E0277, E0666. 56 | {fg:Blue}={/} For more information about an error, try `rustc --explain E0121`. 57 | 58 | 59 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__overlapping__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0666]: nested `impl Trait` is not allowed 6 | ┌─ nested_impl_trait.rs:5:56 7 | │ 8 | 5 │ fn bad_in_ret_position(x: impl Into) -> impl Into { x } 9 | │ ----------^^^^^^^^^^- 10 | │ │ │ 11 | │ │ nested `impl Trait` here 12 | │ outer `impl Trait` 13 | 14 | error[E0121]: the type placeholder `_` is not allowed within types on item signatures 15 | ┌─ typeck_type_placeholder_item.rs:1:18 16 | │ 17 | 1 │ fn fn_test1() -> _ { 5 } 18 | │ ^ 19 | │ │ 20 | │ not allowed in type signatures 21 | │ help: replace with the correct return type: `i32` 22 | 23 | error[E0121]: the type placeholder `_` is not allowed within types on item signatures 24 | ┌─ typeck_type_placeholder_item.rs:2:25 25 | │ 26 | 2 │ fn fn_test2(x: i32) -> (_, _) { (x, x) } 27 | │ -^--^- 28 | │ ││ │ 29 | │ ││ not allowed in type signatures 30 | │ │not allowed in type signatures 31 | │ help: replace with the correct return type: `(i32, i32)` 32 | 33 | error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely 34 | ┌─ no_send_res_ports.rs:25:5 35 | │ 36 | 25 │ thread::spawn(move|| { 37 | │ ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely 38 | │ ╭───────────────────' 39 | 26 │ │ let y = x; 40 | 27 │ │ println!("{:?}", y); 41 | 28 │ │ }); 42 | │ ╰──────' within this `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]` 43 | │ 44 | ┌─ libstd/thread/mod.rs:5:8 45 | │ 46 | 5 │ F: Send + 'static, 47 | │ ---- required by this bound in `std::thread::spawn` 48 | │ 49 | = help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` 50 | = note: required because it appears within the type `Port<()>` 51 | = note: required because it appears within the type `main::Foo` 52 | = note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]` 53 | 54 | error: aborting due 5 previous errors 55 | = Some errors have detailed explanations: E0121, E0277, E0666. 56 | = For more information about an error, try `rustc --explain E0121`. 57 | 58 | 59 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__overlapping__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | nested_impl_trait.rs:5:56: {fg:Red bold bright}error[E0666]{bold bright}: nested `impl Trait` is not allowed{/} 6 | typeck_type_placeholder_item.rs:1:18: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 7 | typeck_type_placeholder_item.rs:2:25: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 8 | typeck_type_placeholder_item.rs:2:28: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/} 9 | no_send_res_ports.rs:25:5: {fg:Red bold bright}error[E0277]{bold bright}: `std::rc::Rc<()>` cannot be sent between threads safely{/} 10 | {fg:Red bold bright}error{bold bright}: aborting due 5 previous errors{/} 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__overlapping__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | nested_impl_trait.rs:5:56: error[E0666]: nested `impl Trait` is not allowed 6 | typeck_type_placeholder_item.rs:1:18: error[E0121]: the type placeholder `_` is not allowed within types on item signatures 7 | typeck_type_placeholder_item.rs:2:25: error[E0121]: the type placeholder `_` is not allowed within types on item signatures 8 | typeck_type_placeholder_item.rs:2:28: error[E0121]: the type placeholder `_` is not allowed within types on item signatures 9 | no_send_res_ports.rs:25:5: error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely 10 | error: aborting due 5 previous errors 11 | 12 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__position_indicator__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | tests/main.js:4:3: warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode 6 | 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__position_indicator__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode 6 | --> tests/main.js:4:3 7 | | 8 | 1 | "use strict"; 9 | | ------------ Strict mode is first declared here 10 | . 11 | 4 | "use strict"; 12 | | ^^^^^^^^^^^^ This strict mode declaration is redundant 13 | 14 | 15 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__position_indicator__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode 6 | ┌─ tests/main.js:4:3 7 | │ 8 | 1 │ "use strict"; 9 | │ ------------ Strict mode is first declared here 10 | · 11 | 4 │ "use strict"; 12 | │ ^^^^^^^^^^^^ This strict mode declaration is redundant 13 | 14 | 15 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__position_indicator__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | tests/main.js:4:3: warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode 6 | 7 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_line__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | one_line.rs:3:12: {fg:Red bold bright}error[E0499]{bold bright}: cannot borrow `v` as mutable more than once at a time{/} 6 | {fg:Red bold bright}error{bold bright}: aborting due to previous error{/} 7 | {fg:Blue}={/} For more information about this error, try `rustc --explain E0499`. 8 | 9 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_line__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | one_line.rs:3:12: error[E0499]: cannot borrow `v` as mutable more than once at a time 6 | error: aborting due to previous error 7 | = For more information about this error, try `rustc --explain E0499`. 8 | 9 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_line__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0499]: cannot borrow `v` as mutable more than once at a time 6 | --> one_line.rs:3:12 7 | | 8 | 3 | v.push(v.pop().unwrap()); 9 | | - ---- ^ second mutable borrow occurs here 10 | | | | 11 | | | first mutable borrow occurs here 12 | | first borrow later used by call 13 | 14 | error: aborting due to previous error 15 | = For more information about this error, try `rustc --explain E0499`. 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_line__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error[E0499]{bold bright}: cannot borrow `v` as mutable more than once at a time{/} 6 | {fg:Blue}┌─{/} one_line.rs:3:12 7 | {fg:Blue}│{/} 8 | {fg:Blue}3{/} {fg:Blue}│{/} v.push({fg:Red}v{/}.pop().unwrap()); 9 | {fg:Blue}│{/} {fg:Blue}-{/} {fg:Blue}----{/} {fg:Red}^{/} {fg:Red}second mutable borrow occurs here{/} 10 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}│{/} 11 | {fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}first mutable borrow occurs here{/} 12 | {fg:Blue}│{/} {fg:Blue}first borrow later used by call{/} 13 | 14 | {fg:Red bold bright}error{bold bright}: aborting due to previous error{/} 15 | {fg:Blue}={/} For more information about this error, try `rustc --explain E0499`. 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_line__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0499]: cannot borrow `v` as mutable more than once at a time 6 | ┌─ one_line.rs:3:12 7 | │ 8 | 3 │ v.push(v.pop().unwrap()); 9 | │ - ---- ^ second mutable borrow occurs here 10 | │ │ │ 11 | │ │ first mutable borrow occurs here 12 | │ first borrow later used by call 13 | 14 | error: aborting due to previous error 15 | = For more information about this error, try `rustc --explain E0499`. 16 | 17 | 18 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_line__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | one_line.rs:3:12: {fg:Red bold bright}error[E0499]{bold bright}: cannot borrow `v` as mutable more than once at a time{/} 6 | {fg:Red bold bright}error{bold bright}: aborting due to previous error{/} 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_line__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | one_line.rs:3:12: error[E0499]: cannot borrow `v` as mutable more than once at a time 6 | error: aborting due to previous error 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_ranges__medium_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | same_range:1:5: {fg:Red bold bright}error{bold bright}: Unexpected token{/} 6 | 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_ranges__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | same_range:1:5: error: Unexpected token 6 | 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_ranges__rich_ascii_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: Unexpected token 6 | --> same_range:1:5 7 | | 8 | 1 | ::S { } 9 | | ^ 10 | | | 11 | | Unexpected '{' 12 | | Expected '(' 13 | 14 | 15 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_ranges__rich_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | {fg:Red bold bright}error{bold bright}: Unexpected token{/} 6 | {fg:Blue}┌─{/} same_range:1:5 7 | {fg:Blue}│{/} 8 | {fg:Blue}1{/} {fg:Blue}│{/} ::S {fg:Red}{{/} } 9 | {fg:Blue}│{/} {fg:Red}^{/} 10 | {fg:Blue}│{/} {fg:Red}│{/} 11 | {fg:Blue}│{/} {fg:Red}Unexpected '{'{/} 12 | {fg:Blue}│{/} {fg:Blue}Expected '('{/} 13 | 14 | 15 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_ranges__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error: Unexpected token 6 | ┌─ same_range:1:5 7 | │ 8 | 1 │ ::S { } 9 | │ ^ 10 | │ │ 11 | │ Unexpected '{' 12 | │ Expected '(' 13 | 14 | 15 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_ranges__short_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_color(&config) 4 | --- 5 | same_range:1:5: {fg:Red bold bright}error{bold bright}: Unexpected token{/} 6 | 7 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__same_ranges__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | same_range:1:5: error: Unexpected token 6 | 7 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__surrounding_lines__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | 5 | --- 6 | error: Unknown attribute macro 7 | ┌─ surroundingLines.fun:1:3 8 | │ 9 | 1 │ #[foo] 10 | │ ^^^ No attribute macro `foo` known 11 | 2 │ fn main() { 12 | 13 | error: Missing argument for format 14 | ┌─ surroundingLines.fun:5:9 15 | │ 16 | 2 │ fn main() { 17 | 3 │ println!( 18 | 4 │ "{}", 19 | │ -- Unable to use `{}`-directive to display `Foo` 20 | 5 │ Foo 21 | │ ^^^ No instance of std::fmt::Display exists for type Foo 22 | 6 │ ); 23 | 24 | error: Syntax error 25 | ┌─ surroundingLines.fun:9:11 26 | │ 27 | 7 │ } 28 | 8 │ 29 | 9 │ struct Foo 30 | │ ^ Missing a semicolon 31 | 32 | 33 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__tab_columns__tab_width_2_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning: tab test 6 | ┌─ tab_columns:1:2 7 | │ 8 | 1 │ hello 9 | │ ^^^^^ 10 | 2 │ ∙ hello 11 | │ ^^^^^ 12 | 3 │ ∙∙ hello 13 | │ ^^^^^ 14 | 4 │ ∙∙∙ hello 15 | │ ^^^^^ 16 | 5 │ ∙∙∙∙ hello 17 | │ ^^^^^ 18 | 6 │ ∙∙∙∙∙ hello 19 | │ ^^^^^ 20 | 7 │ ∙∙∙∙∙∙ hello 21 | │ ^^^^^ 22 | 23 | 24 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__tab_columns__tab_width_3_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning: tab test 6 | ┌─ tab_columns:1:2 7 | │ 8 | 1 │ hello 9 | │ ^^^^^ 10 | 2 │ ∙ hello 11 | │ ^^^^^ 12 | 3 │ ∙∙ hello 13 | │ ^^^^^ 14 | 4 │ ∙∙∙ hello 15 | │ ^^^^^ 16 | 5 │ ∙∙∙∙ hello 17 | │ ^^^^^ 18 | 6 │ ∙∙∙∙∙ hello 19 | │ ^^^^^ 20 | 7 │ ∙∙∙∙∙∙ hello 21 | │ ^^^^^ 22 | 23 | 24 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__tab_columns__tab_width_6_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning: tab test 6 | ┌─ tab_columns:1:2 7 | │ 8 | 1 │ hello 9 | │ ^^^^^ 10 | 2 │ ∙ hello 11 | │ ^^^^^ 12 | 3 │ ∙∙ hello 13 | │ ^^^^^ 14 | 4 │ ∙∙∙ hello 15 | │ ^^^^^ 16 | 5 │ ∙∙∙∙ hello 17 | │ ^^^^^ 18 | 6 │ ∙∙∙∙∙ hello 19 | │ ^^^^^ 20 | 7 │ ∙∙∙∙∙∙ hello 21 | │ ^^^^^ 22 | 23 | 24 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__tab_columns__tab_width_default_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning: tab test 6 | ┌─ tab_columns:1:2 7 | │ 8 | 1 │ hello 9 | │ ^^^^^ 10 | 2 │ ∙ hello 11 | │ ^^^^^ 12 | 3 │ ∙∙ hello 13 | │ ^^^^^ 14 | 4 │ ∙∙∙ hello 15 | │ ^^^^^ 16 | 5 │ ∙∙∙∙ hello 17 | │ ^^^^^ 18 | 6 │ ∙∙∙∙∙ hello 19 | │ ^^^^^ 20 | 7 │ ∙∙∙∙∙∙ hello 21 | │ ^^^^^ 22 | 23 | 24 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__tabbed__tab_width_3_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning: unknown weapon `DogJaw` 6 | ┌─ tabbed:3:11 7 | │ 8 | 3 │ Weapon: DogJaw 9 | │ ^^^^^^ the weapon 10 | 11 | warning: unknown condition `attack-cooldown` 12 | ┌─ tabbed:4:23 13 | │ 14 | 4 │ ReloadingCondition: attack-cooldown 15 | │ ^^^^^^^^^^^^^^^ the condition 16 | 17 | warning: unknown field `Foo` 18 | ┌─ tabbed:5:2 19 | │ 20 | 5 │ Foo: Bar 21 | │ ^^^ the field 22 | 23 | 24 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__tabbed__tab_width_6_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning: unknown weapon `DogJaw` 6 | ┌─ tabbed:3:11 7 | │ 8 | 3 │ Weapon: DogJaw 9 | │ ^^^^^^ the weapon 10 | 11 | warning: unknown condition `attack-cooldown` 12 | ┌─ tabbed:4:23 13 | │ 14 | 4 │ ReloadingCondition: attack-cooldown 15 | │ ^^^^^^^^^^^^^^^ the condition 16 | 17 | warning: unknown field `Foo` 18 | ┌─ tabbed:5:2 19 | │ 20 | 5 │ Foo: Bar 21 | │ ^^^ the field 22 | 23 | 24 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__tabbed__tab_width_default_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | warning: unknown weapon `DogJaw` 6 | ┌─ tabbed:3:11 7 | │ 8 | 3 │ Weapon: DogJaw 9 | │ ^^^^^^ the weapon 10 | 11 | warning: unknown condition `attack-cooldown` 12 | ┌─ tabbed:4:23 13 | │ 14 | 4 │ ReloadingCondition: attack-cooldown 15 | │ ^^^^^^^^^^^^^^^ the condition 16 | 17 | warning: unknown field `Foo` 18 | ┌─ tabbed:5:2 19 | │ 20 | 5 │ Foo: Bar 21 | │ ^^^ the field 22 | 23 | 24 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__unicode__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | unicode.rs:1:8: error[E0703]: invalid ABI: found `路濫狼á́́` 6 | = valid ABIs: 7 | - aapcs 8 | - amdgpu-kernel 9 | - C 10 | - cdecl 11 | - efiapi 12 | - fastcall 13 | - msp430-interrupt 14 | - platform-intrinsic 15 | - ptx-kernel 16 | - Rust 17 | - rust-call 18 | - rust-intrinsic 19 | - stdcall 20 | - system 21 | - sysv64 22 | - thiscall 23 | - unadjusted 24 | - vectorcall 25 | - win64 26 | - x86-interrupt 27 | error: aborting due to previous error 28 | = For more information about this error, try `rustc --explain E0703`. 29 | 30 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__unicode__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E0703]: invalid ABI: found `路濫狼á́́` 6 | ┌─ unicode.rs:1:8 7 | │ 8 | 1 │ extern "路濫狼á́́" fn foo() {} 9 | │ ^^^^^^^^^ invalid ABI 10 | │ 11 | = valid ABIs: 12 | - aapcs 13 | - amdgpu-kernel 14 | - C 15 | - cdecl 16 | - efiapi 17 | - fastcall 18 | - msp430-interrupt 19 | - platform-intrinsic 20 | - ptx-kernel 21 | - Rust 22 | - rust-call 23 | - rust-intrinsic 24 | - stdcall 25 | - system 26 | - sysv64 27 | - thiscall 28 | - unadjusted 29 | - vectorcall 30 | - win64 31 | - x86-interrupt 32 | 33 | error: aborting due to previous error 34 | = For more information about this error, try `rustc --explain E0703`. 35 | 36 | 37 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__unicode__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | unicode.rs:1:8: error[E0703]: invalid ABI: found `路濫狼á́́` 6 | error: aborting due to previous error 7 | 8 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__unicode_spans__medium_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | moon_jump.rs:1:1: error[E01]: cow may not jump during new moon. 6 | note: invalid unicode range 7 | note: invalid unicode range 8 | note: invalid unicode range 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__unicode_spans__rich_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | error[E01]: cow may not jump during new moon. 6 | ┌─ moon_jump.rs:1:1 7 | │ 8 | 1 │ 🐄🌑🐄🌒🐄🌓🐄🌔🐄🌕🐄🌖🐄🌗🐄🌘🐄 9 | │ ^^ Invalid jump 10 | 11 | note: invalid unicode range 12 | ┌─ moon_jump.rs:1:1 13 | │ 14 | 1 │ 🐄🌑🐄🌒🐄🌓🐄🌔🐄🌕🐄🌖🐄🌗🐄🌘🐄 15 | │ -- Cow range does not start at boundary. 16 | 17 | note: invalid unicode range 18 | ┌─ moon_jump.rs:1:3 19 | │ 20 | 1 │ 🐄🌑🐄🌒🐄🌓🐄🌔🐄🌕🐄🌖🐄🌗🐄🌘🐄 21 | │ -- Cow range does not end at boundary. 22 | 23 | note: invalid unicode range 24 | ┌─ moon_jump.rs:1:1 25 | │ 26 | 1 │ 🐄🌑🐄🌒🐄🌓🐄🌔🐄🌕🐄🌖🐄🌗🐄🌘🐄 27 | │ ------ Cow does not start or end at boundary. 28 | 29 | 30 | -------------------------------------------------------------------------------- /codespan-reporting/tests/snapshots/term__unicode_spans__short_no_color.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: codespan-reporting/tests/term.rs 3 | expression: TEST_DATA.emit_no_color(&config) 4 | --- 5 | moon_jump.rs:1:1: error[E01]: cow may not jump during new moon. 6 | note: invalid unicode range 7 | note: invalid unicode range 8 | note: invalid unicode range 9 | 10 | -------------------------------------------------------------------------------- /codespan-reporting/tests/support/color_buffer.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::io::prelude::*; 3 | use termcolor::{ColorSpec, WriteColor}; 4 | 5 | // Color tester from: 6 | // https://github.com/wycats/language-reporting/blob/b021c87e0d4916b5f32756151bf215c220eee52d/crates/render-tree/src/stylesheet/accumulator.rs 7 | 8 | /// A facility for creating visually inspectable representations of colored output 9 | /// so they can be easily tested. 10 | /// 11 | /// A new color is represented as `{style}` and a reset is represented by `{/}`. 12 | /// 13 | /// Attributes are printed in this order: 14 | /// 15 | /// - Foreground color as `fg:Color` 16 | /// - Background color as `bg:Color` 17 | /// - Bold as `bold` 18 | /// - Underline as `underline` 19 | /// - Intense as `bright` 20 | /// 21 | /// For example, the style "intense, bold red foreground" would be printed as: 22 | /// 23 | /// ```text 24 | /// {fg:Red bold intense} 25 | /// ``` 26 | /// 27 | /// Since this implementation attempts to make it possible to faithfully 28 | /// understand what real WriteColor implementations would do, it tries 29 | /// to approximate the contract in the WriteColor trait: "Subsequent 30 | /// writes to this write will use these settings until either reset is 31 | /// called or new color settings are set.") 32 | /// 33 | /// - If set_color is called with a style, `{...}` is emitted containing the 34 | /// color attributes. 35 | /// - If set_color is called with no style, `{/}` is emitted 36 | /// - If reset is called, `{/}` is emitted. 37 | pub struct ColorBuffer { 38 | buf: Vec, 39 | color: ColorSpec, 40 | } 41 | 42 | impl ColorBuffer { 43 | pub fn new() -> ColorBuffer { 44 | ColorBuffer { 45 | buf: Vec::new(), 46 | color: ColorSpec::new(), 47 | } 48 | } 49 | 50 | pub fn into_string(self) -> String { 51 | String::from_utf8(self.buf).unwrap() 52 | } 53 | } 54 | 55 | impl io::Write for ColorBuffer { 56 | fn write(&mut self, buf: &[u8]) -> io::Result { 57 | self.buf.extend(buf); 58 | Ok(buf.len()) 59 | } 60 | 61 | fn flush(&mut self) -> io::Result<()> { 62 | Ok(()) 63 | } 64 | } 65 | 66 | impl WriteColor for ColorBuffer { 67 | fn supports_color(&self) -> bool { 68 | true 69 | } 70 | 71 | fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { 72 | #![allow(unused_assignments)] 73 | 74 | if self.color == *spec { 75 | return Ok(()); 76 | } else { 77 | self.color = spec.clone(); 78 | } 79 | 80 | if spec.is_none() { 81 | write!(self, "{{/}}")?; 82 | return Ok(()); 83 | } else { 84 | write!(self, "{{")?; 85 | } 86 | 87 | let mut first = true; 88 | 89 | fn write_first(first: bool, write: &mut ColorBuffer) -> io::Result { 90 | if !first { 91 | write!(write, " ")?; 92 | } 93 | 94 | Ok(false) 95 | } 96 | 97 | if let Some(fg) = spec.fg() { 98 | first = write_first(first, self)?; 99 | write!(self, "fg:{:?}", fg)?; 100 | } 101 | 102 | if let Some(bg) = spec.bg() { 103 | first = write_first(first, self)?; 104 | write!(self, "bg:{:?}", bg)?; 105 | } 106 | 107 | if spec.bold() { 108 | first = write_first(first, self)?; 109 | write!(self, "bold")?; 110 | } 111 | 112 | if spec.underline() { 113 | first = write_first(first, self)?; 114 | write!(self, "underline")?; 115 | } 116 | 117 | if spec.intense() { 118 | first = write_first(first, self)?; 119 | write!(self, "bright")?; 120 | } 121 | 122 | write!(self, "}}")?; 123 | 124 | Ok(()) 125 | } 126 | 127 | fn reset(&mut self) -> io::Result<()> { 128 | let color = self.color.clone(); 129 | 130 | if color != ColorSpec::new() { 131 | write!(self, "{{/}}")?; 132 | self.color = ColorSpec::new(); 133 | } 134 | 135 | Ok(()) 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /codespan-reporting/tests/support/mod.rs: -------------------------------------------------------------------------------- 1 | use codespan_reporting::diagnostic::Diagnostic; 2 | use codespan_reporting::files::Files; 3 | use codespan_reporting::term::{emit, Config}; 4 | use termcolor::{Buffer, WriteColor}; 5 | 6 | mod color_buffer; 7 | 8 | use self::color_buffer::ColorBuffer; 9 | 10 | pub struct TestData<'files, F: Files<'files>> { 11 | pub files: F, 12 | pub diagnostics: Vec>, 13 | } 14 | 15 | impl<'files, F: Files<'files>> TestData<'files, F> { 16 | fn emit(&'files self, mut writer: W, config: &Config) -> W { 17 | for diagnostic in &self.diagnostics { 18 | emit(&mut writer, config, &self.files, diagnostic).unwrap(); 19 | } 20 | writer 21 | } 22 | 23 | pub fn emit_color(&'files self, config: &Config) -> String { 24 | self.emit(ColorBuffer::new(), config).into_string() 25 | } 26 | 27 | pub fn emit_no_color(&'files self, config: &Config) -> String { 28 | let buffer = self.emit(Buffer::no_color(), config); 29 | String::from_utf8_lossy(buffer.as_slice()).into_owned() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /codespan/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | The minimum supported rustc version is now `1.67.0` (was `1.40.0`). 11 | This is because dependencies of `codespan-lsp` now require this Rust version. 12 | 13 | ### Fixed 14 | 15 | - Removed an erroneous feature gate from the implementation of 16 | `codespan_reporting::Files` for `codespan::Files`. 17 | 18 | ## [0.11.0] - 2020-11-30 19 | 20 | There is now a [code of conduct](https://github.com/brendanzab/codespan/blob/master/CODE_OF_CONDUCT.md) 21 | and a [contributing guide](https://github.com/brendanzab/codespan/blob/master/CONTRIBUTING.md). 22 | 23 | Some versions were skipped to sync up with the `codespan-lsp` crate. The release 24 | process has been changed so this should not happen again. 25 | 26 | ### Changed 27 | 28 | - This crate now depends on `codespan-reporting` non-optionally 29 | because of the new error type. 30 | 31 | ### Fixed 32 | 33 | - Building the crate on operating systems other than unix/windows 34 | with the `serialization` feature enabled. 35 | 36 | ## [0.9.5] - 2020-06-24 37 | 38 | ### Fixed 39 | 40 | - Building the crate with the `reporting` feature disabled. 41 | 42 | ## [0.9.4] - 2020-05-18 43 | ## [0.9.3] - 2020-04-29 44 | ## [0.9.2] - 2020-03-29 45 | 46 | ## [0.9.1] - 2020-03-23 47 | 48 | ### Added 49 | 50 | - `From` is now implemented for `Range` and `Range`. 51 | - More `From<_>` conversions are now implemented for index and offset types. 52 | 53 | ## [0.9.0] - 2020-03-11 54 | 55 | ### Added 56 | 57 | - `codespan` now depends on `codespan_reporting`. This can be disabled via the `reporting` feature. 58 | - `codespan::Files` now implements `codespan_reporting::files::Files` 59 | 60 | ## [0.8.0] - 2020-02-24 61 | ## [0.7.0] - 2020-01-06 62 | ## [0.6.0] - 2019-12-18 63 | ## [0.5.0] - 2019-10-02 64 | ## [0.4.1] - 2019-08-25 65 | ## [0.4.0] - 2019-08-22 66 | ## [0.3.0] - 2019-05-01 67 | ## [0.2.1] - 2019-02-26 68 | ## [0.2.0] - 2018-10-11 69 | 70 | [Unreleased]: https://github.com/brendanzab/codespan/compare/v0.11.1...HEAD 71 | [0.11.1]: https://github.com/brendanzab/codespan/compare/v0.11.0..v0.11.1 72 | [0.11.0]: https://github.com/brendanzab/codespan/compare/v0.9.5...v0.11.0 73 | [0.9.5]: https://github.com/brendanzab/codespan/compare/v0.9.4...v0.9.5 74 | [0.9.4]: https://github.com/brendanzab/codespan/compare/v0.9.3...v0.9.4 75 | [0.9.3]: https://github.com/brendanzab/codespan/compare/v0.9.2...v0.9.3 76 | [0.9.2]: https://github.com/brendanzab/codespan/compare/v0.9.1...v0.9.2 77 | [0.9.1]: https://github.com/brendanzab/codespan/compare/v0.9.0...v0.9.1 78 | [0.9.0]: https://github.com/brendanzab/codespan/compare/v0.8.0...v0.9.0 79 | [0.8.0]: https://github.com/brendanzab/codespan/compare/v0.7.0...v0.8.0 80 | [0.7.0]: https://github.com/brendanzab/codespan/compare/v0.6.0...v0.7.0 81 | [0.6.0]: https://github.com/brendanzab/codespan/compare/v0.5.0...v0.6.0 82 | [0.5.0]: https://github.com/brendanzab/codespan/compare/v0.4.1...v0.5.0 83 | [0.4.1]: https://github.com/brendanzab/codespan/compare/v0.4.0...v0.4.1 84 | [0.4.0]: https://github.com/brendanzab/codespan/compare/v0.3.0...v0.4.0 85 | [0.3.0]: https://github.com/brendanzab/codespan/compare/v0.2.1...v0.3.0 86 | [0.2.1]: https://github.com/brendanzab/codespan/compare/v0.2.0...v0.2.1 87 | [0.2.0]: https://github.com/brendanzab/codespan/releases/tag/v0.2.0 88 | -------------------------------------------------------------------------------- /codespan/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "codespan" 3 | version = "0.12.0" 4 | readme = "README.md" 5 | license = "Apache-2.0" 6 | authors = ["Brendan Zabarauskas "] 7 | description = "Data structures for tracking locations in source code" 8 | homepage = "https://github.com/brendanzab/codespan" 9 | repository = "https://github.com/brendanzab/codespan" 10 | documentation = "https://docs.rs/codespan" 11 | edition = "2021" 12 | rust-version = "1.67" 13 | 14 | [dependencies] 15 | codespan-reporting = { path = "../codespan-reporting", version = "0.12.0", default-features = false } 16 | serde = { version = "1", default-features = false, optional = true, features = [ 17 | "derive", 18 | "alloc", 19 | ] } 20 | 21 | [dev-dependencies] 22 | termcolor = "1" 23 | 24 | [features] 25 | default = ["std", "termcolor"] 26 | std = ["codespan-reporting/std", "serde?/std"] 27 | termcolor = ["std", "codespan-reporting/termcolor"] 28 | serialization = ["serde", "codespan-reporting/serialization"] 29 | 30 | [lints.clippy] 31 | # Certain items from `core` are re-exported in `alloc` and `std`, and likewise `alloc` has items 32 | # re-exported in `std`. 33 | # `core` is available on all platforms, `alloc` is available on almost all, and `std` is only 34 | # available on some. 35 | # These lints ensure we don't import from a "less available" crate without reason. 36 | alloc_instead_of_core = "warn" 37 | std_instead_of_alloc = "warn" 38 | std_instead_of_core = "warn" 39 | -------------------------------------------------------------------------------- /codespan/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /codespan/README.md: -------------------------------------------------------------------------------- 1 | # codespan 2 | 3 | [![Continuous integration][actions-badge]][actions-url] 4 | [![Crates.io][crate-badge]][crate-url] 5 | [![Docs.rs][docs-badge]][docs-url] 6 | [![Matrix][matrix-badge]][matrix-lobby] 7 | 8 | [actions-badge]: https://img.shields.io/github/actions/workflow/status/brendanzab/codespan/ci.yml?branch=master 9 | [actions-url]: https://github.com/brendanzab/codespan/actions 10 | [crate-url]: https://crates.io/crates/codespan 11 | [crate-badge]: https://img.shields.io/crates/v/codespan.svg 12 | [docs-url]: https://docs.rs/codespan 13 | [docs-badge]: https://docs.rs/codespan/badge.svg 14 | [matrix-badge]: https://img.shields.io/badge/matrix-%23codespan%3Amatrix.org-blue.svg 15 | [matrix-lobby]: https://app.element.io/#/room/#codespan:matrix.org 16 | 17 | Utilities for dealing with source code locations. 18 | -------------------------------------------------------------------------------- /codespan/src/index.rs: -------------------------------------------------------------------------------- 1 | //! Wrapper types that specify positions in a source file 2 | 3 | use core::fmt; 4 | use core::ops::{Add, AddAssign, Neg, Sub, SubAssign}; 5 | 6 | #[cfg(feature = "serialization")] 7 | use serde::{Deserialize, Serialize}; 8 | 9 | /// The raw, untyped index. We use a 32-bit integer here for space efficiency, 10 | /// assuming we won't be working with sources larger than 4GB. 11 | pub type RawIndex = u32; 12 | 13 | /// The raw, untyped offset. 14 | pub type RawOffset = i64; 15 | 16 | /// A zero-indexed line offset into a source file 17 | #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 18 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 19 | pub struct LineIndex(pub RawIndex); 20 | 21 | impl LineIndex { 22 | /// The 1-indexed line number. Useful for pretty printing source locations. 23 | /// 24 | /// ```rust 25 | /// use codespan::{LineIndex, LineNumber}; 26 | /// 27 | /// assert_eq!(format!("{}", LineIndex(0).number()), "1"); 28 | /// assert_eq!(format!("{}", LineIndex(3).number()), "4"); 29 | /// ``` 30 | pub const fn number(self) -> LineNumber { 31 | LineNumber(self.0 + 1) 32 | } 33 | 34 | /// Convert the index into a `usize`, for use in array indexing 35 | pub const fn to_usize(self) -> usize { 36 | self.0 as usize 37 | } 38 | } 39 | 40 | impl fmt::Debug for LineIndex { 41 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 42 | write!(f, "LineIndex(")?; 43 | self.0.fmt(f)?; 44 | write!(f, ")") 45 | } 46 | } 47 | 48 | impl fmt::Display for LineIndex { 49 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 50 | self.0.fmt(f) 51 | } 52 | } 53 | 54 | /// A 1-indexed line number. Useful for pretty printing source locations. 55 | #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 56 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 57 | pub struct LineNumber(RawIndex); 58 | 59 | impl LineNumber { 60 | /// Convert the number into a `usize` 61 | pub const fn to_usize(self) -> usize { 62 | self.0 as usize 63 | } 64 | } 65 | 66 | impl fmt::Debug for LineNumber { 67 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 68 | write!(f, "LineNumber(")?; 69 | self.0.fmt(f)?; 70 | write!(f, ")") 71 | } 72 | } 73 | 74 | impl fmt::Display for LineNumber { 75 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 76 | self.0.fmt(f) 77 | } 78 | } 79 | 80 | /// A line offset in a source file 81 | #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 82 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 83 | pub struct LineOffset(pub RawOffset); 84 | 85 | impl fmt::Debug for LineOffset { 86 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 87 | write!(f, "LineOffset(")?; 88 | self.0.fmt(f)?; 89 | write!(f, ")") 90 | } 91 | } 92 | 93 | impl fmt::Display for LineOffset { 94 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 95 | self.0.fmt(f) 96 | } 97 | } 98 | 99 | /// A zero-indexed column offset into a source file 100 | #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 101 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 102 | pub struct ColumnIndex(pub RawIndex); 103 | 104 | impl ColumnIndex { 105 | /// The 1-indexed column number. Useful for pretty printing source locations. 106 | /// 107 | /// ```rust 108 | /// use codespan::{ColumnIndex, ColumnNumber}; 109 | /// 110 | /// assert_eq!(format!("{}", ColumnIndex(0).number()), "1"); 111 | /// assert_eq!(format!("{}", ColumnIndex(3).number()), "4"); 112 | /// ``` 113 | pub const fn number(self) -> ColumnNumber { 114 | ColumnNumber(self.0 + 1) 115 | } 116 | 117 | /// Convert the index into a `usize`, for use in array indexing 118 | pub const fn to_usize(self) -> usize { 119 | self.0 as usize 120 | } 121 | } 122 | 123 | impl fmt::Debug for ColumnIndex { 124 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 125 | write!(f, "ColumnIndex(")?; 126 | self.0.fmt(f)?; 127 | write!(f, ")") 128 | } 129 | } 130 | 131 | impl fmt::Display for ColumnIndex { 132 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 133 | self.0.fmt(f) 134 | } 135 | } 136 | 137 | /// A 1-indexed column number. Useful for pretty printing source locations. 138 | #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 139 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 140 | pub struct ColumnNumber(RawIndex); 141 | 142 | impl fmt::Debug for ColumnNumber { 143 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 144 | write!(f, "ColumnNumber(")?; 145 | self.0.fmt(f)?; 146 | write!(f, ")") 147 | } 148 | } 149 | 150 | impl fmt::Display for ColumnNumber { 151 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 152 | self.0.fmt(f) 153 | } 154 | } 155 | 156 | /// A column offset in a source file 157 | #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 158 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 159 | pub struct ColumnOffset(pub RawOffset); 160 | 161 | impl fmt::Debug for ColumnOffset { 162 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 163 | write!(f, "ColumnOffset(")?; 164 | self.0.fmt(f)?; 165 | write!(f, ")") 166 | } 167 | } 168 | 169 | impl fmt::Display for ColumnOffset { 170 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 171 | self.0.fmt(f) 172 | } 173 | } 174 | 175 | /// A byte position in a source file. 176 | #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] 177 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 178 | pub struct ByteIndex(pub RawIndex); 179 | 180 | impl ByteIndex { 181 | /// Convert the position into a `usize`, for use in array indexing 182 | pub const fn to_usize(self) -> usize { 183 | self.0 as usize 184 | } 185 | } 186 | 187 | impl fmt::Debug for ByteIndex { 188 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 189 | write!(f, "ByteIndex(")?; 190 | self.0.fmt(f)?; 191 | write!(f, ")") 192 | } 193 | } 194 | 195 | impl fmt::Display for ByteIndex { 196 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 197 | self.0.fmt(f) 198 | } 199 | } 200 | 201 | /// A byte offset in a source file 202 | #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 203 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 204 | pub struct ByteOffset(pub RawOffset); 205 | 206 | impl ByteOffset { 207 | /// Create a byte offset from a UTF8-encoded character 208 | /// 209 | /// ```rust 210 | /// use codespan::ByteOffset; 211 | /// 212 | /// assert_eq!(ByteOffset::from_char_len('A').to_usize(), 1); 213 | /// assert_eq!(ByteOffset::from_char_len('ß').to_usize(), 2); 214 | /// assert_eq!(ByteOffset::from_char_len('ℝ').to_usize(), 3); 215 | /// assert_eq!(ByteOffset::from_char_len('💣').to_usize(), 4); 216 | /// ``` 217 | pub fn from_char_len(ch: char) -> ByteOffset { 218 | ByteOffset(ch.len_utf8() as RawOffset) 219 | } 220 | 221 | /// Create a byte offset from a UTF- encoded string 222 | /// 223 | /// ```rust 224 | /// use codespan::ByteOffset; 225 | /// 226 | /// assert_eq!(ByteOffset::from_str_len("A").to_usize(), 1); 227 | /// assert_eq!(ByteOffset::from_str_len("ß").to_usize(), 2); 228 | /// assert_eq!(ByteOffset::from_str_len("ℝ").to_usize(), 3); 229 | /// assert_eq!(ByteOffset::from_str_len("💣").to_usize(), 4); 230 | /// ``` 231 | pub fn from_str_len(value: &str) -> ByteOffset { 232 | ByteOffset(value.len() as RawOffset) 233 | } 234 | 235 | /// Convert the offset into a `usize`, for use in array indexing 236 | pub const fn to_usize(self) -> usize { 237 | self.0 as usize 238 | } 239 | } 240 | 241 | impl Default for ByteOffset { 242 | #[inline] 243 | fn default() -> ByteOffset { 244 | ByteOffset(0) 245 | } 246 | } 247 | 248 | impl fmt::Debug for ByteOffset { 249 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 250 | write!(f, "ByteOffset(")?; 251 | self.0.fmt(f)?; 252 | write!(f, ")") 253 | } 254 | } 255 | 256 | impl fmt::Display for ByteOffset { 257 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 258 | self.0.fmt(f) 259 | } 260 | } 261 | 262 | /// A relative offset between two indices 263 | /// 264 | /// These can be thought of as 1-dimensional vectors 265 | pub trait Offset: Copy + Ord 266 | where 267 | Self: Neg, 268 | Self: Add, 269 | Self: AddAssign, 270 | Self: Sub, 271 | Self: SubAssign, 272 | { 273 | const ZERO: Self; 274 | } 275 | 276 | /// Index types 277 | /// 278 | /// These can be thought of as 1-dimensional points 279 | pub trait Index: Copy + Ord 280 | where 281 | Self: Add<::Offset, Output = Self>, 282 | Self: AddAssign<::Offset>, 283 | Self: Sub<::Offset, Output = Self>, 284 | Self: SubAssign<::Offset>, 285 | Self: Sub::Offset>, 286 | { 287 | type Offset: Offset; 288 | } 289 | 290 | macro_rules! impl_index { 291 | ($Index:ident, $Offset:ident) => { 292 | impl From for $Offset { 293 | #[inline] 294 | fn from(i: RawOffset) -> Self { 295 | $Offset(i) 296 | } 297 | } 298 | 299 | impl From for $Index { 300 | #[inline] 301 | fn from(i: RawIndex) -> Self { 302 | $Index(i) 303 | } 304 | } 305 | 306 | impl From<$Index> for RawIndex { 307 | #[inline] 308 | fn from(index: $Index) -> RawIndex { 309 | index.0 310 | } 311 | } 312 | 313 | impl From<$Offset> for RawOffset { 314 | #[inline] 315 | fn from(offset: $Offset) -> RawOffset { 316 | offset.0 317 | } 318 | } 319 | 320 | impl From<$Index> for usize { 321 | #[inline] 322 | fn from(index: $Index) -> usize { 323 | index.0 as usize 324 | } 325 | } 326 | 327 | impl From<$Offset> for usize { 328 | #[inline] 329 | fn from(offset: $Offset) -> usize { 330 | offset.0 as usize 331 | } 332 | } 333 | 334 | impl Offset for $Offset { 335 | const ZERO: $Offset = $Offset(0); 336 | } 337 | 338 | impl Index for $Index { 339 | type Offset = $Offset; 340 | } 341 | 342 | impl Add<$Offset> for $Index { 343 | type Output = $Index; 344 | 345 | #[inline] 346 | fn add(self, rhs: $Offset) -> $Index { 347 | $Index((self.0 as RawOffset + rhs.0) as RawIndex) 348 | } 349 | } 350 | 351 | impl AddAssign<$Offset> for $Index { 352 | #[inline] 353 | fn add_assign(&mut self, rhs: $Offset) { 354 | *self = *self + rhs; 355 | } 356 | } 357 | 358 | impl Neg for $Offset { 359 | type Output = $Offset; 360 | 361 | #[inline] 362 | fn neg(self) -> $Offset { 363 | $Offset(-self.0) 364 | } 365 | } 366 | 367 | impl Add<$Offset> for $Offset { 368 | type Output = $Offset; 369 | 370 | #[inline] 371 | fn add(self, rhs: $Offset) -> $Offset { 372 | $Offset(self.0 + rhs.0) 373 | } 374 | } 375 | 376 | impl AddAssign<$Offset> for $Offset { 377 | #[inline] 378 | fn add_assign(&mut self, rhs: $Offset) { 379 | self.0 += rhs.0; 380 | } 381 | } 382 | 383 | impl Sub<$Offset> for $Offset { 384 | type Output = $Offset; 385 | 386 | #[inline] 387 | fn sub(self, rhs: $Offset) -> $Offset { 388 | $Offset(self.0 - rhs.0) 389 | } 390 | } 391 | 392 | impl SubAssign<$Offset> for $Offset { 393 | #[inline] 394 | fn sub_assign(&mut self, rhs: $Offset) { 395 | self.0 -= rhs.0; 396 | } 397 | } 398 | 399 | impl Sub for $Index { 400 | type Output = $Offset; 401 | 402 | #[inline] 403 | fn sub(self, rhs: $Index) -> $Offset { 404 | $Offset(self.0 as RawOffset - rhs.0 as RawOffset) 405 | } 406 | } 407 | 408 | impl Sub<$Offset> for $Index { 409 | type Output = $Index; 410 | 411 | #[inline] 412 | fn sub(self, rhs: $Offset) -> $Index { 413 | $Index((self.0 as RawOffset - rhs.0 as RawOffset) as u32) 414 | } 415 | } 416 | 417 | impl SubAssign<$Offset> for $Index { 418 | #[inline] 419 | fn sub_assign(&mut self, rhs: $Offset) { 420 | self.0 = (self.0 as RawOffset - rhs.0) as RawIndex; 421 | } 422 | } 423 | }; 424 | } 425 | 426 | impl_index!(LineIndex, LineOffset); 427 | impl_index!(ColumnIndex, ColumnOffset); 428 | impl_index!(ByteIndex, ByteOffset); 429 | -------------------------------------------------------------------------------- /codespan/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Utilities for working with source code and printing nicely formatted 2 | //! diagnostic information like warnings and errors. 3 | //! 4 | //! # Optional Features 5 | //! 6 | //! Extra functionality is accessible by enabling feature flags. The features 7 | //! currently available are: 8 | //! 9 | //! - **serialization** - Adds `Serialize` and `Deserialize` implementations 10 | //! for use with `serde` 11 | 12 | #![forbid(unsafe_code)] 13 | #![no_std] 14 | 15 | #[cfg(feature = "std")] 16 | extern crate std; 17 | 18 | extern crate alloc; 19 | 20 | mod file; 21 | mod index; 22 | mod location; 23 | mod span; 24 | 25 | pub use crate::file::{FileId, Files}; 26 | pub use crate::index::{ByteIndex, ByteOffset}; 27 | pub use crate::index::{ColumnIndex, ColumnNumber, ColumnOffset}; 28 | pub use crate::index::{Index, Offset}; 29 | pub use crate::index::{LineIndex, LineNumber, LineOffset}; 30 | pub use crate::index::{RawIndex, RawOffset}; 31 | pub use crate::location::Location; 32 | pub use crate::span::Span; 33 | -------------------------------------------------------------------------------- /codespan/src/location.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "serialization")] 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use crate::{ColumnIndex, LineIndex}; 5 | 6 | /// A location in a source file. 7 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 8 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 9 | pub struct Location { 10 | /// The line index in the source file. 11 | pub line: LineIndex, 12 | /// The column index in the source file. 13 | pub column: ColumnIndex, 14 | } 15 | 16 | impl Location { 17 | /// Construct a new location from a line index and a column index. 18 | pub fn new(line: impl Into, column: impl Into) -> Location { 19 | Location { 20 | line: line.into(), 21 | column: column.into(), 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /codespan/src/span.rs: -------------------------------------------------------------------------------- 1 | use core::fmt; 2 | use core::ops::Range; 3 | 4 | use crate::{ByteIndex, RawIndex}; 5 | 6 | #[cfg(feature = "serialization")] 7 | use serde::{Deserialize, Serialize}; 8 | 9 | #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] 10 | #[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))] 11 | pub struct Span { 12 | start: ByteIndex, 13 | end: ByteIndex, 14 | } 15 | 16 | impl Span { 17 | /// Create a new span from a starting and ending span. 18 | pub fn new(start: impl Into, end: impl Into) -> Span { 19 | let start = start.into(); 20 | let end = end.into(); 21 | 22 | assert!(end >= start); 23 | 24 | Span { start, end } 25 | } 26 | 27 | /// Gives an empty span at the start of a source. 28 | pub const fn initial() -> Span { 29 | Span { 30 | start: ByteIndex(0), 31 | end: ByteIndex(0), 32 | } 33 | } 34 | 35 | /// Measure the span of a string. 36 | /// 37 | /// ```rust 38 | /// use codespan::{ByteIndex, Span}; 39 | /// 40 | /// let span = Span::from_str("hello"); 41 | /// 42 | /// assert_eq!(span, Span::new(0, 5)); 43 | /// ``` 44 | #[allow(clippy::should_implement_trait)] 45 | pub fn from_str(s: &str) -> Span { 46 | Span::new(0, s.len() as u32) 47 | } 48 | 49 | /// Combine two spans by taking the start of the earlier span 50 | /// and the end of the later span. 51 | /// 52 | /// Note: this will work even if the two spans are disjoint. 53 | /// If this doesn't make sense in your application, you should handle it yourself. 54 | /// In that case, you can use `Span::disjoint` as a convenience function. 55 | /// 56 | /// ```rust 57 | /// use codespan::Span; 58 | /// 59 | /// let span1 = Span::new(0, 4); 60 | /// let span2 = Span::new(10, 16); 61 | /// 62 | /// assert_eq!(Span::merge(span1, span2), Span::new(0, 16)); 63 | /// ``` 64 | pub fn merge(self, other: Span) -> Span { 65 | use core::cmp::{max, min}; 66 | 67 | let start = min(self.start, other.start); 68 | let end = max(self.end, other.end); 69 | Span::new(start, end) 70 | } 71 | 72 | /// A helper function to tell whether two spans do not overlap. 73 | /// 74 | /// ``` 75 | /// use codespan::Span; 76 | /// let span1 = Span::new(0, 4); 77 | /// let span2 = Span::new(10, 16); 78 | /// assert!(span1.disjoint(span2)); 79 | /// ``` 80 | pub fn disjoint(self, other: Span) -> bool { 81 | let (first, last) = if self.end < other.end { 82 | (self, other) 83 | } else { 84 | (other, self) 85 | }; 86 | first.end <= last.start 87 | } 88 | 89 | /// Get the starting byte index. 90 | /// 91 | /// ```rust 92 | /// use codespan::{ByteIndex, Span}; 93 | /// 94 | /// let span = Span::new(0, 4); 95 | /// 96 | /// assert_eq!(span.start(), ByteIndex::from(0)); 97 | /// ``` 98 | pub fn start(self) -> ByteIndex { 99 | self.start 100 | } 101 | 102 | /// Get the ending byte index. 103 | /// 104 | /// ```rust 105 | /// use codespan::{ByteIndex, Span}; 106 | /// 107 | /// let span = Span::new(0, 4); 108 | /// 109 | /// assert_eq!(span.end(), ByteIndex::from(4)); 110 | /// ``` 111 | pub fn end(self) -> ByteIndex { 112 | self.end 113 | } 114 | } 115 | 116 | impl Default for Span { 117 | fn default() -> Span { 118 | Span::initial() 119 | } 120 | } 121 | 122 | impl fmt::Display for Span { 123 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 124 | write!( 125 | f, 126 | "[{start}, {end})", 127 | start = self.start(), 128 | end = self.end(), 129 | ) 130 | } 131 | } 132 | 133 | impl From> for Span 134 | where 135 | I: Into, 136 | { 137 | fn from(range: Range) -> Span { 138 | Span::new(range.start, range.end) 139 | } 140 | } 141 | 142 | impl From for Range { 143 | fn from(span: Span) -> Range { 144 | span.start.into()..span.end.into() 145 | } 146 | } 147 | 148 | impl From for Range { 149 | fn from(span: Span) -> Range { 150 | span.start.0..span.end.0 151 | } 152 | } 153 | 154 | #[cfg(test)] 155 | mod test { 156 | #[test] 157 | fn test_merge() { 158 | use super::Span; 159 | 160 | // overlap 161 | let a = Span::from(1..5); 162 | let b = Span::from(3..10); 163 | assert_eq!(a.merge(b), Span::from(1..10)); 164 | assert_eq!(b.merge(a), Span::from(1..10)); 165 | 166 | // subset 167 | let two_four = (2..4).into(); 168 | assert_eq!(a.merge(two_four), (1..5).into()); 169 | assert_eq!(two_four.merge(a), (1..5).into()); 170 | 171 | // disjoint 172 | let ten_twenty = (10..20).into(); 173 | assert_eq!(a.merge(ten_twenty), (1..20).into()); 174 | assert_eq!(ten_twenty.merge(a), (1..20).into()); 175 | 176 | // identity 177 | assert_eq!(a.merge(a), a); 178 | } 179 | 180 | #[test] 181 | fn test_disjoint() { 182 | use super::Span; 183 | 184 | // overlap 185 | let a = Span::from(1..5); 186 | let b = Span::from(3..10); 187 | assert!(!a.disjoint(b)); 188 | assert!(!b.disjoint(a)); 189 | 190 | // subset 191 | let two_four = (2..4).into(); 192 | assert!(!a.disjoint(two_four)); 193 | assert!(!two_four.disjoint(a)); 194 | 195 | // disjoint 196 | let ten_twenty = (10..20).into(); 197 | assert!(a.disjoint(ten_twenty)); 198 | assert!(ten_twenty.disjoint(a)); 199 | 200 | // identity 201 | assert!(!a.disjoint(a)); 202 | 203 | // off by one (upper bound) 204 | let c = Span::from(5..10); 205 | assert!(a.disjoint(c)); 206 | assert!(c.disjoint(a)); 207 | // off by one (lower bound) 208 | let d = Span::from(0..1); 209 | assert!(a.disjoint(d)); 210 | assert!(d.disjoint(a)); 211 | } 212 | } 213 | --------------------------------------------------------------------------------