{"id":29068667,"url":"https://github.com/vallentin/char-positions","last_synced_at":"2025-06-27T11:09:14.677Z","repository":{"id":301248781,"uuid":"1008001990","full_name":"vallentin/char-positions","owner":"vallentin","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-25T23:11:52.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-25T23:15:37.126Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vallentin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-24T21:48:13.000Z","updated_at":"2025-06-25T23:11:56.000Z","dependencies_parsed_at":"2025-06-26T16:45:13.480Z","dependency_job_id":null,"html_url":"https://github.com/vallentin/char-positions","commit_stats":null,"previous_names":["vallentin/char-positions"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vallentin/char-positions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Fchar-positions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Fchar-positions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Fchar-positions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Fchar-positions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vallentin","download_url":"https://codeload.github.com/vallentin/char-positions/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Fchar-positions/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262244922,"owners_count":23281029,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-27T11:09:04.889Z","updated_at":"2025-06-27T11:09:14.663Z","avatar_url":"https://github.com/vallentin.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# char-positions\n\n[![CI](https://github.com/vallentin/char-positions/actions/workflows/rust.yml/badge.svg)](https://github.com/vallentin/char-positions/actions/workflows/rust.yml)\n[![Latest Version](https://img.shields.io/crates/v/char-positions.svg)](https://crates.io/crates/char-positions)\n[![Docs](https://docs.rs/char-positions/badge.svg)](https://docs.rs/char-positions)\n[![dependency status](https://deps.rs/repo/github/vallentin/char-positions/status.svg)](https://deps.rs/repo/github/vallentin/char-positions)\n[![License](https://img.shields.io/github/license/vallentin/char-positions.svg)](https://github.com/vallentin/char-positions)\n\n\u003c!-- cargo-rdme start --\u003e\n\nSimilar to the standard library's [`.char_indicies()`], but instead of only\nproducing the start byte position. This library implements [`.char_positions()`],\nwhich can produce any combination of line, column, start byte, and end byte position.\n\nAs an example use\n\u003ccode\u003etext.[char_positions]::\u0026lt;[LineCol]\u0026gt;()\u003c/code\u003e\nto get the line and column of each [`char`].\nUse [`LineColByteRange`] to additionally get the byte range,\nor just [`Line`] to simply get the line number.\n\n### Example\n\n```rust\nuse char_positions::{CharPositionsExt, LineCol};\n\nlet text = \"Hello 👋\\nWorld 🌏\\n🦀🦀\";\n\nfor (LineCol(line, col), c) in text.char_positions() {\n    println!(\"[Ln {line}, Col {col}] {c:?}\");\n}\n```\n\nWhich will output:\n\n```text\n[Ln 1, Col 1] 'H'\n[Ln 1, Col 2] 'e'\n[Ln 1, Col 3] 'l'\n[Ln 1, Col 4] 'l'\n[Ln 1, Col 5] 'o'\n[Ln 1, Col 6] ' '\n[Ln 1, Col 7] '👋'\n[Ln 1, Col 8] '\\n'\n[Ln 2, Col 1] 'W'\n[Ln 2, Col 2] 'o'\n[Ln 2, Col 3] 'r'\n[Ln 2, Col 4] 'l'\n[Ln 2, Col 5] 'd'\n[Ln 2, Col 6] ' '\n[Ln 2, Col 7] '🌏'\n[Ln 2, Col 8] '\\n'\n[Ln 3, Col 1] '🦀'\n[Ln 3, Col 2] '🦀'\n```\n\n### Supported\n\n| `.char_positions::\u003cT\u003e()` | Produces |\n|:---|---|\n| [`usize`] | Start byte index (same as [`.char_indicies()`]) |\n| [`std::ops::Range\u003cusize\u003e`] | Start byte and end byte index, i.e. `\u0026text[range]` is the `char` |\n| [`LineColByteRange`] | Line number, column number, and byte range |\n| [`LineCol`] | Line number and column number |\n| [`Line`] | Line number |\n| [`Col`] | Column number |\n| [`ByteRange`] | Same as using [`std::ops::Range\u003cusize\u003e`] |\n| [`ByteStart`] | Start byte index (same as [`.char_indicies()`]) |\n| [`ByteEnd`] | End byte index |\n| _Tuples are also supported, e.g._ | |\n| \u003ccode\u003e([Line],)\u003c/code\u003e | _Produces the tuple_ |\n| \u003ccode\u003e([Line], [Col])\u003c/code\u003e | _Produces the tuple_ |\n| \u003ccode\u003e([Line], [Col], [ByteStart], [ByteEnd])\u003c/code\u003e | _Produces the tuple_ |\n| _etc._ | |\n\n### Example - `LineColByteRange`\n\n```rust\nuse char_positions::{CharPositionsExt, LineColByteRange};\n\nlet text = \"Hello 👋\\nWorld 🌏\\n🦀🦀\";\n\nlet mut iter = text\n    .char_positions::\u003cLineColByteRange\u003e()\n    .map(|(LineColByteRange(line, col, range), c)| (line, col, range, c));\n\nassert_eq!(iter.next(), Some((1, 1, 0..1, 'H')));\nassert_eq!(iter.next(), Some((1, 2, 1..2, 'e')));\nassert_eq!(iter.next(), Some((1, 3, 2..3, 'l')));\nassert_eq!(iter.next(), Some((1, 4, 3..4, 'l')));\nassert_eq!(iter.next(), Some((1, 5, 4..5, 'o')));\nassert_eq!(iter.next(), Some((1, 6, 5..6, ' ')));\nassert_eq!(iter.next(), Some((1, 7, 6..10, '👋')));\nassert_eq!(iter.next(), Some((1, 8, 10..11, '\\n')));\nassert_eq!(iter.next(), Some((2, 1, 11..12, 'W')));\nassert_eq!(iter.next(), Some((2, 2, 12..13, 'o')));\nassert_eq!(iter.next(), Some((2, 3, 13..14, 'r')));\nassert_eq!(iter.next(), Some((2, 4, 14..15, 'l')));\nassert_eq!(iter.next(), Some((2, 5, 15..16, 'd')));\nassert_eq!(iter.next(), Some((2, 6, 16..17, ' ')));\nassert_eq!(iter.next(), Some((2, 7, 17..21, '🌏')));\nassert_eq!(iter.next(), Some((2, 8, 21..22, '\\n')));\nassert_eq!(iter.next(), Some((3, 1, 22..26, '🦀')));\nassert_eq!(iter.next(), Some((3, 2, 26..30, '🦀')));\nassert_eq!(iter.next(), None);\n```\n\n\n[`.char_positions()`]: https://docs.rs/char-positions/*/char_positions/trait.CharPositionsExt.html#tymethod.char_positions\n[char_positions]: https://docs.rs/char-positions/*/char_positions/trait.CharPositionsExt.html#tymethod.char_positions\n\n[`LineColByteRange`]: https://docs.rs/char-positions/*/char_positions/struct.LineColByteRange.html\n[`LineCol`]: https://docs.rs/char-positions/*/char_positions/struct.LineCol.html\n[`Line`]: https://docs.rs/char-positions/*/char_positions/struct.Line.html\n[`Col`]: https://docs.rs/char-positions/*/char_positions/struct.Line.html\n[`ByteRange`]: https://docs.rs/char-positions/*/char_positions/struct.ByteRange.html\n[`ByteStart`]: https://docs.rs/char-positions/*/char_positions/struct.ByteStart.html\n[`ByteEnd`]: https://docs.rs/char-positions/*/char_positions/struct.ByteEnd.html\n\n[LineColByteRange]: https://docs.rs/char-positions/*/char_positions/struct.LineColByteRange.html\n[LineCol]: https://docs.rs/char-positions/*/char_positions/struct.LineCol.html\n[Line]: https://docs.rs/char-positions/*/char_positions/struct.Line.html\n[Col]: https://docs.rs/char-positions/*/char_positions/struct.Col.html\n[ByteStart]: https://docs.rs/char-positions/*/char_positions/struct.ByteStart.html\n[ByteEnd]: https://docs.rs/char-positions/*/char_positions/struct.ByteEnd.html\n\n[`.char_indicies()`]: https://doc.rust-lang.org/std/primitive.str.html#method.char_indices\n\n[`char`]: https://doc.rust-lang.org/std/primitive.char.html\n[`usize`]: https://doc.rust-lang.org/std/primitive.usize.html\n[`std::ops::Range\u003cusize\u003e`]: https://doc.rust-lang.org/std/ops/struct.Range.html\n\n\u003c!-- cargo-rdme end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvallentin%2Fchar-positions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvallentin%2Fchar-positions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvallentin%2Fchar-positions/lists"}