#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Position {
pub line: usize,
pub column: usize,
}
impl Position {
#[must_use]
pub fn new(line: usize, column: usize) -> Self {
Self { line, column }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Span {
pub start: Position,
pub end: Position,
}
impl Span {
#[must_use]
pub fn new(start: Position, end: Position) -> Self {
Self { start, end }
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TokenKind {
DirectiveOpen,
DirectiveClose,
ChordOpen,
ChordClose,
Colon,
Text(String),
Newline,
Eof,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Token {
pub kind: TokenKind,
pub span: Span,
}
impl Token {
#[must_use]
pub fn new(kind: TokenKind, span: Span) -> Self {
Self { kind, span }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn position_new() {
let pos = Position::new(1, 5);
assert_eq!(pos.line, 1);
assert_eq!(pos.column, 5);
}
#[test]
fn span_new() {
let span = Span::new(Position::new(1, 1), Position::new(1, 5));
assert_eq!(span.start, Position::new(1, 1));
assert_eq!(span.end, Position::new(1, 5));
}
#[test]
fn token_new() {
let span = Span::new(Position::new(1, 1), Position::new(1, 2));
let token = Token::new(TokenKind::DirectiveOpen, span);
assert_eq!(token.kind, TokenKind::DirectiveOpen);
assert_eq!(token.span, span);
}
#[test]
fn token_kind_text_equality() {
let a = TokenKind::Text("hello".to_string());
let b = TokenKind::Text("hello".to_string());
let c = TokenKind::Text("world".to_string());
assert_eq!(a, b);
assert_ne!(a, c);
}
}