1use crate::parser::token_name;
2use crate::{Bytes, Loc};
3
4#[derive(Clone, PartialEq, Eq)]
6#[repr(C)]
7pub struct Token {
8 pub token_type: i32,
11
12 pub token_value: Bytes,
15
16 pub loc: Loc,
18}
19
20impl Token {
21 pub fn as_bytes(&self) -> &Vec<u8> {
23 self.token_value.as_raw()
24 }
25
26 pub fn into_bytes(self) -> Vec<u8> {
28 self.token_value.into_raw()
29 }
30
31 pub fn as_str_lossy(&self) -> Result<&str, std::str::Utf8Error> {
33 std::str::from_utf8(self.token_value.as_raw())
34 }
35
36 pub fn to_string_lossy(&self) -> String {
38 self.token_value.to_string_lossy()
39 }
40
41 pub fn to_string(&self) -> Result<String, std::string::FromUtf8Error> {
43 self.token_value.to_string()
44 }
45
46 pub fn into_string(self) -> Result<String, std::string::FromUtf8Error> {
48 self.token_value.into_string()
49 }
50
51 pub fn token_name(&self) -> &'static str {
53 token_name(self.token_type)
54 }
55}
56
57impl std::fmt::Debug for Token {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 f.write_str(&format!(
60 "[{}, {:?}, {}...{}]",
61 self.token_name(),
62 self.token_value.to_string_lossy(),
63 self.loc.begin,
64 self.loc.end,
65 ))
66 }
67}
68
69#[cfg(test)]
70fn new_token() -> Token {
71 Token {
72 token_type: crate::Lexer::tINTEGER,
73 token_value: Bytes::new(vec![42]),
74 loc: Loc { begin: 1, end: 2 },
75 }
76}
77
78#[test]
79fn test_as_bytes() {
80 let token = new_token();
81 assert_eq!(token.as_bytes(), &vec![42]);
82}
83
84#[test]
85fn test_into_bytes() {
86 let token = new_token();
87 assert_eq!(token.into_bytes(), vec![42]);
88}
89
90#[test]
91fn test_as_str_lossy() {
92 let token = new_token();
93 assert_eq!(token.as_str_lossy(), Ok("*"));
94}
95
96#[test]
97fn test_to_string_lossy() {
98 let token = new_token();
99 assert_eq!(token.to_string_lossy(), String::from("*"));
100}
101
102#[test]
103fn test_fmt() {
104 let token = new_token();
105 assert_eq!(format!("{:?}", token), "[tINTEGER, \"*\", 1...2]");
106}