gaia_types/reader/
mod.rs

1#![doc = include_str!("readme.md")]
2
3pub use self::{token::Token, token_stream::TokenStream};
4use crate::{GaiaDiagnostics, GaiaError};
5use byteorder::{ByteOrder, ReadBytesExt};
6use serde::{Deserialize, Serialize};
7use std::{
8    io::{Read, Seek, SeekFrom},
9    marker::PhantomData,
10};
11use url::Url;
12
13mod token;
14mod token_stream;
15
16/// 二进制读取器,用于从实现了 ReadBytesExt trait 的类型中读取数据
17///
18/// 这是一个泛型结构体,可以包装任何实现了 ReadBytesExt trait 的类型,
19/// 提供二进制数据的读取功能。
20#[derive(Debug)]
21pub struct BinaryReader<R, E> {
22    reader: R,
23    position: u64,
24    endian: PhantomData<E>,
25    errors: Vec<GaiaError>,
26}
27
28impl<R: Read, E> Read for BinaryReader<R, E> {
29    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
30        let bytes_read = self.reader.read(buffer)?;
31        self.position += bytes_read as u64;
32        Ok(bytes_read)
33    }
34}
35
36impl<R: Seek, E> Seek for BinaryReader<R, E> {
37    fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
38        let new_position = self.reader.seek(pos)?;
39        self.position = new_position;
40        Ok(new_position)
41    }
42}
43
44impl<R, E> BinaryReader<R, E> {
45    /// 创建新的二进制读取器
46    ///
47    /// # Arguments
48    /// * `lexer` - 要读取的数据
49    ///
50    /// # Returns
51    /// 返回新的 BinaryReader 实例
52    pub fn new(reader: R) -> Self {
53        Self { reader, position: 0, endian: Default::default(), errors: vec![] }
54    }
55
56    /// 获取当前读取位置
57    ///
58    /// # Returns
59    /// 返回当前的字节偏移位置
60    pub fn get_position(&self) -> u64 {
61        self.position
62    }
63
64    /// 设置读取位置
65    ///
66    /// 注意:如果底层reader不支持Seek操作,此函数将返回错误
67    ///
68    /// # Arguments
69    /// * `pos` - 新的读取位置
70    ///
71    /// # Returns
72    /// 返回操作结果
73    pub fn set_position(&mut self, position: u64) -> Result<u64, GaiaError>
74    where
75        R: Seek,
76    {
77        self.reader.seek(SeekFrom::Start(position))?;
78        self.position = position;
79        Ok(position)
80    }
81    /// 完成读取器并返回结果。
82    pub fn finish(self) -> GaiaDiagnostics<R> {
83        GaiaDiagnostics { result: Ok(self.reader), diagnostics: self.errors }
84    }
85
86    pub fn take_errors(&mut self) -> Vec<GaiaError> {
87        std::mem::take(&mut self.errors)
88    }
89}
90
91impl<R: ReadBytesExt, E: ByteOrder> BinaryReader<R, E> {
92    /// 读取 u8
93    ///
94    /// # Returns
95    /// 返回读取的 u8 值或 IO 错误
96    pub fn read_u8(&mut self) -> std::io::Result<u8> {
97        let value = self.reader.read_u8()?;
98        self.position += 1;
99        Ok(value)
100    }
101
102    /// 读取 u16
103    ///
104    /// # Returns
105    /// 返回读取的 u16 值或 IO 错误
106    pub fn read_u16(&mut self) -> std::io::Result<u16> {
107        let value = self.reader.read_u16::<E>()?;
108        self.position += 2;
109        Ok(value)
110    }
111
112    /// 读取 i16
113    ///
114    /// # Returns
115    /// 返回读取的 i16 值或 IO 错误
116    pub fn read_i16(&mut self) -> std::io::Result<i16> {
117        let value = self.reader.read_i16::<E>()?;
118        self.position += 2;
119        Ok(value)
120    }
121
122    /// 读取 u32
123    ///
124    /// # Returns
125    /// 返回读取的 u32 值或 IO 错误
126    pub fn read_u32(&mut self) -> std::io::Result<u32> {
127        let value = self.reader.read_u32::<E>()?;
128        self.position += 4;
129        Ok(value)
130    }
131
132    /// 读取 u64
133    ///
134    /// # Returns
135    /// 返回读取的 u64 值或 IO 错误
136    pub fn read_u64(&mut self) -> std::io::Result<u64> {
137        let value = self.reader.read_u64::<E>()?;
138        self.position += 8;
139        Ok(value)
140    }
141
142    /// 读取指定长度的字节数组
143    ///
144    /// # Arguments
145    /// * `len` - 要读取的字节数
146    ///
147    /// # Returns
148    /// 返回读取的字节数组或 IO 错误
149    pub fn read_bytes(&mut self, len: usize) -> std::io::Result<Vec<u8>> {
150        let mut buf = vec![0u8; len];
151        self.reader.read_exact(&mut buf)?;
152        self.position += len as u64;
153        Ok(buf)
154    }
155
156    /// 读取固定长度的字节数组
157    ///
158    /// # Returns
159    /// 返回读取的字节数组或 IO 错误
160    pub fn read_array<const N: usize>(&mut self) -> std::io::Result<[u8; N]> {
161        let mut buf = [0u8; N];
162        self.reader.read_exact(&mut buf)?;
163        self.position += N as u64;
164        Ok(buf)
165    }
166
167    /// 跳过指定数量的字节
168    ///
169    /// 注意:如果底层reader不支持Seek操作,此函数将返回错误
170    ///
171    /// # Arguments
172    /// * `count` - 要跳过的字节数
173    ///
174    /// # Returns
175    /// 返回操作结果
176    pub fn skip(&mut self, count: u64) -> std::io::Result<u64>
177    where
178        R: Seek,
179    {
180        let new_pos = self.reader.seek(SeekFrom::Current(count as i64))?;
181        self.position = new_pos;
182        Ok(new_pos)
183    }
184}
185
186/// 源代码位置信息,表示代码在源文件中的位置
187///
188/// 该结构体用于跟踪源代码的位置信息,包括行号、列号等。
189#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
190pub struct SourcePosition {
191    /// 行号,从 1 开始计数
192    ///
193    /// 表示当前位置所在的行号,第一行为 1。
194    pub line: u32,
195    /// 列号,从 1 开始计数
196    ///
197    /// 表示当前位置所在的列号,第一列为 1。
198    pub column: u32,
199    /// 字节偏移量,从 0 开始计数
200    ///
201    /// 表示从文件开始到当前位置的字节偏移量。
202    pub offset: usize,
203    /// 长度,表示该位置所覆盖的字节数
204    ///
205    /// 通常用于表示标记或符号的长度。
206    pub length: usize,
207}
208
209/// 源代码位置,包含文件 URL 和位置信息
210///
211/// 该结构体扩展了 SourcePosition,增加了文件 URL 信息,
212/// 可以表示代码在特定文件中的位置。
213#[derive(Clone, Debug, Serialize, Deserialize)]
214pub struct SourceLocation {
215    /// 行号,从 1 开始计数
216    ///
217    /// 表示当前位置所在的行号。
218    pub line: u32,
219    /// 列号,从 1 开始计数
220    ///
221    /// 表示当前位置所在的列号。
222    pub column: u32,
223    /// 源文件的 URL,可选
224    ///
225    /// 如果存在,表示包含该代码的文件的 URL 或路径。
226    /// 可以是文件系统路径或网络 URL。
227    pub url: Option<Url>,
228}
229
230impl Default for SourceLocation {
231    fn default() -> Self {
232        Self { line: 1, column: 1, url: None }
233    }
234}