Skan
skan is a small Rust crate that provides functionality similar to Java's Scanner class. It allows reading input from various sources (strings, files, etc.) and parsing them into different types, such as words, lines, integers, and floats.
Features
- Create a scanner from a string or any type implementing
Read. - Read input byte-by-byte, word-by-word, or line-by-line.
- Parse numbers (integers, floats, doubles) with error handling.
- Iterator support for byte-wise reading.
- Custom errors for parsing and end-of-data scenarios.
Installation
You can install skan either from Crates.io or directly from the Git repository.
Installing from Crates.io
- Open your
Cargo.tomlfile. - Add
skanto your dependencies:
[]
= "0.1.0"
- In your Rust code, import the scanner:
use Scanner;
- Create a
Scannerinstance to read input:
let mut sc = from_str;
let word = sc.next_word;
Installing directly from Git
- Open your
Cargo.tomlfile. - Add
skanas a dependency using the Git repository URL:
[]
= { = "https://github.com/2teez/skan" }
- Import and use the crate as usual:
use Scanner;
let mut sc = from_str;
let word = sc.next_word;
Modules
scanner
This module contains the main Scanner struct and related functionality.
ScannerError<E>
An enum representing possible scanner errors:
NoMoreData– when there are no more items to read.ParseError(E)– when parsing a string into a number fails.
Implements Display and Error traits for descriptive error messages.
Scanner struct
Holds the scanner state:
data: Vec<u8>– the raw input bytes.wrds: Option<Vec<String>>– optional cached split words/lines.counter: usize– current reading position.
Creating a Scanner
From a reader:
use Scanner;
use File;
let file = open.unwrap;
let mut scanner = new;
From a string:
let mut scanner = from_str;
Methods
has_next() -> bool
Checks if there is more data to read.
let scanner = from_str;
assert!;
next_byte() -> Option<u8>
Returns the next byte from the input without advancing the counter if there is data.
let scanner = from_str;
assert_eq!; // 'H'
next_word() -> Option<String>
Returns the next word (split by space) from the input.
let mut scanner = from_str;
scanner.next_word;
scanner.next_word;
assert_eq!;
next_line() -> Option<String>
Returns the next line (split by \n) from the input.
let mut scanner = from_str;
scanner.next_line;
assert_eq!;
next_number<T>() -> Result<T, ScannerError<T::Err>>
Parses the next word as a number of type T.
let mut scanner = from_str;
scanner.next_word;
scanner.next_word;
scanner.next_word;
assert_eq!;
next_int<T>() -> Result<T, ScannerError<T::Err>>
Parses the next word as an integer. Requires T to implement the Int trait.
use Int;
let mut scanner = from_str;
scanner.next_word;
scanner.next_word;
scanner.next_word;
assert_eq!;
next_float<T>() -> Result<T, ScannerError<T::Err>>
Parses the next word as a floating-point number. Requires T to implement the Float trait.
use Float;
let mut scanner = from_str;
scanner.next_word;
assert_eq!;
next_double() -> Result<f64, ScannerError<f64::Err>>
Parses the next word as an f64 floating-point number.
let mut scanner = from_str;
assert_eq!;
Iterator Implementation
Scanner implements Iterator<Item = u8> to read input byte-by-byte.
let mut scanner = from_str;
for byte in &mut scanner
Internal Helper Methods
delimiter(&self, sep: char) -> Vec<String>– splits the input by the given separator (' 'or'\n') and returns non-empty strings.
Example Usage
use Scanner;
use ;
let mut scanner = from_str;
scanner.next_word; // skip "Age"
let age: i32 = scanner.next_int.unwrap;
scanner.next_word; // skip "Score"
let score: f32 = scanner.next_float.unwrap;
println!;
Error Handling
ScannerError helps identify when parsing fails or when there is no more data. Always handle Result when calling number parsing methods:
match scanner.