# Spanley
This is a generic string span library,\
it is meant for use with tokenizing\
applications or the likes.
Serde support and API changes\
are coming soon.
Please do look into string interners\
before deciding to use this crate\
to make sure this actually fits your\
use case.\
String interning features may also\
get added on later to this project, but that\
is a much later spot on the roadmap.
# Example
## Input
```rust
use spanley::Span;
let message = "\
This is my generic string span, his name is Spanley.\n\
Say hi Spanley!\
";
let spanley = Span::new(message, 57, 11).unwrap();
println!("{}", spanley);
```
## Output
```text
hi Spanley!
```
# Features
# `location`
Adds the `SpanLocation` struct,\
accessible through `spanley::SpanLocation`\
or simply by calling one of the related\
methods from `spanley::Span` directly.
`SpanLocation` gets the line and offset,\
for possible logging applications.
## Example
### Input
```rust
use spanley::Span;
let message = "\
This is my generic string span, his name is Spanley.\n\
Say hi Spanley!\
";
let spanley = Span::new(message, 57, 11).unwrap();
let location = spanley.get_start_location();
println!("{}", location);
```
### Output
```text
1:4
```
# `location-column`
This can only be compiled in conjecture with\
the `location` feature flag set to `true`.
Adds one relatively large extra dependencies,\
[`unicode-width`].
This adds additional fields on the\
`SpanLocation` struct;\
`column_offset` and\
`column_cjk_offset`,\
which are calculated by the\
[`unicode-width`] crate.
`column_offset` is then used instead\
of `char_offset` in the [`Display`]\
implementation for `SpanLocation`.
## Example
### Input
```rust
use spanley::Span;
let source = "👩👩👦👦👩👩👦👦👩👩👦👦";
// Additional context:
//
// '👩👩👦👦' spans 7 characters behind
// the scenes and 2 columns on a TUI.
// Hence, inputs divisible by 7 and
// Outputs divisible by 2.
let spanley = Span::new(source, 14, 7).unwrap();
let location = spanley.get_start_location();
println!("{}", location.column_offset());
println!("{}", location);
```
### Output
```text
4
0:4
```
# `container`
Adds `SpanContainer`.
`SpanContainer` simplay associates a\
`Span` to an instance of type `T`.
This is best used as a way to construct\
or otherwise handle tokens or other\
types where it is contextually relevant\
to associate it with a `Span`.
## Example
### Input
```rust
use spanley::{Span, SpanContainer};
enum TokenKind {
Hello,
World
}
const source: &str = "Hello World!";
let hello_span = Span::new(source, 0, 5).unwrap(); // Hello
let world_span = Span::new(source, 6, 5).unwrap(); // World
let hello = SpanContainer::new(hello_span, TokenKind::Hello);
let world = SpanContainer::new(world_span, TokenKind::World);
```
[`unicode-width`]: https://crates.io/crates/unicode-width
[`display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html