https://github.com/vallentin/char-positions
https://github.com/vallentin/char-positions
Last synced: 12 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/vallentin/char-positions
- Owner: vallentin
- License: mit
- Created: 2025-06-24T21:48:13.000Z (12 months ago)
- Default Branch: master
- Last Pushed: 2025-06-25T23:11:52.000Z (12 months ago)
- Last Synced: 2025-06-25T23:15:37.126Z (12 months ago)
- Language: Rust
- Size: 0 Bytes
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# char-positions
[](https://github.com/vallentin/char-positions/actions/workflows/rust.yml)
[](https://crates.io/crates/char-positions)
[](https://docs.rs/char-positions)
[](https://deps.rs/repo/github/vallentin/char-positions)
[](https://github.com/vallentin/char-positions)
Similar to the standard library's [`.char_indicies()`], but instead of only
producing the start byte position. This library implements [`.char_positions()`],
which can produce any combination of line, column, start byte, and end byte position.
As an example use
text.[char_positions]::<[LineCol]>()
to get the line and column of each [`char`].
Use [`LineColByteRange`] to additionally get the byte range,
or just [`Line`] to simply get the line number.
### Example
```rust
use char_positions::{CharPositionsExt, LineCol};
let text = "Hello š\nWorld š\nš¦š¦";
for (LineCol(line, col), c) in text.char_positions() {
println!("[Ln {line}, Col {col}] {c:?}");
}
```
Which will output:
```text
[Ln 1, Col 1] 'H'
[Ln 1, Col 2] 'e'
[Ln 1, Col 3] 'l'
[Ln 1, Col 4] 'l'
[Ln 1, Col 5] 'o'
[Ln 1, Col 6] ' '
[Ln 1, Col 7] 'š'
[Ln 1, Col 8] '\n'
[Ln 2, Col 1] 'W'
[Ln 2, Col 2] 'o'
[Ln 2, Col 3] 'r'
[Ln 2, Col 4] 'l'
[Ln 2, Col 5] 'd'
[Ln 2, Col 6] ' '
[Ln 2, Col 7] 'š'
[Ln 2, Col 8] '\n'
[Ln 3, Col 1] 'š¦'
[Ln 3, Col 2] 'š¦'
```
### Supported
| `.char_positions::()` | Produces |
|:---|---|
| [`usize`] | Start byte index (same as [`.char_indicies()`]) |
| [`std::ops::Range`] | Start byte and end byte index, i.e. `&text[range]` is the `char` |
| [`LineColByteRange`] | Line number, column number, and byte range |
| [`LineCol`] | Line number and column number |
| [`Line`] | Line number |
| [`Col`] | Column number |
| [`ByteRange`] | Same as using [`std::ops::Range`] |
| [`ByteStart`] | Start byte index (same as [`.char_indicies()`]) |
| [`ByteEnd`] | End byte index |
| _Tuples are also supported, e.g._ | |
| ([Line],) | _Produces the tuple_ |
| ([Line], [Col]) | _Produces the tuple_ |
| ([Line], [Col], [ByteStart], [ByteEnd]) | _Produces the tuple_ |
| _etc._ | |
### Example - `LineColByteRange`
```rust
use char_positions::{CharPositionsExt, LineColByteRange};
let text = "Hello š\nWorld š\nš¦š¦";
let mut iter = text
.char_positions::()
.map(|(LineColByteRange(line, col, range), c)| (line, col, range, c));
assert_eq!(iter.next(), Some((1, 1, 0..1, 'H')));
assert_eq!(iter.next(), Some((1, 2, 1..2, 'e')));
assert_eq!(iter.next(), Some((1, 3, 2..3, 'l')));
assert_eq!(iter.next(), Some((1, 4, 3..4, 'l')));
assert_eq!(iter.next(), Some((1, 5, 4..5, 'o')));
assert_eq!(iter.next(), Some((1, 6, 5..6, ' ')));
assert_eq!(iter.next(), Some((1, 7, 6..10, 'š')));
assert_eq!(iter.next(), Some((1, 8, 10..11, '\n')));
assert_eq!(iter.next(), Some((2, 1, 11..12, 'W')));
assert_eq!(iter.next(), Some((2, 2, 12..13, 'o')));
assert_eq!(iter.next(), Some((2, 3, 13..14, 'r')));
assert_eq!(iter.next(), Some((2, 4, 14..15, 'l')));
assert_eq!(iter.next(), Some((2, 5, 15..16, 'd')));
assert_eq!(iter.next(), Some((2, 6, 16..17, ' ')));
assert_eq!(iter.next(), Some((2, 7, 17..21, 'š')));
assert_eq!(iter.next(), Some((2, 8, 21..22, '\n')));
assert_eq!(iter.next(), Some((3, 1, 22..26, 'š¦')));
assert_eq!(iter.next(), Some((3, 2, 26..30, 'š¦')));
assert_eq!(iter.next(), None);
```
[`.char_positions()`]: https://docs.rs/char-positions/*/char_positions/trait.CharPositionsExt.html#tymethod.char_positions
[char_positions]: https://docs.rs/char-positions/*/char_positions/trait.CharPositionsExt.html#tymethod.char_positions
[`LineColByteRange`]: https://docs.rs/char-positions/*/char_positions/struct.LineColByteRange.html
[`LineCol`]: https://docs.rs/char-positions/*/char_positions/struct.LineCol.html
[`Line`]: https://docs.rs/char-positions/*/char_positions/struct.Line.html
[`Col`]: https://docs.rs/char-positions/*/char_positions/struct.Line.html
[`ByteRange`]: https://docs.rs/char-positions/*/char_positions/struct.ByteRange.html
[`ByteStart`]: https://docs.rs/char-positions/*/char_positions/struct.ByteStart.html
[`ByteEnd`]: https://docs.rs/char-positions/*/char_positions/struct.ByteEnd.html
[LineColByteRange]: https://docs.rs/char-positions/*/char_positions/struct.LineColByteRange.html
[LineCol]: https://docs.rs/char-positions/*/char_positions/struct.LineCol.html
[Line]: https://docs.rs/char-positions/*/char_positions/struct.Line.html
[Col]: https://docs.rs/char-positions/*/char_positions/struct.Col.html
[ByteStart]: https://docs.rs/char-positions/*/char_positions/struct.ByteStart.html
[ByteEnd]: https://docs.rs/char-positions/*/char_positions/struct.ByteEnd.html
[`.char_indicies()`]: https://doc.rust-lang.org/std/primitive.str.html#method.char_indices
[`char`]: https://doc.rust-lang.org/std/primitive.char.html
[`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
[`std::ops::Range`]: https://doc.rust-lang.org/std/ops/struct.Range.html