1use std::{io, mem};
2
3use crate::{
4 Config, DecodableElement, DecoderContext, Element, EncodableElement, EncoderContext, Preamble,
5};
6
7#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub(crate) struct EncodedSource {
9 pub(crate) line: u64,
10 pub(crate) col: u64,
11 pub(crate) contents_index: usize,
12}
13
14impl EncodedSource {
15 const fn new(line: u64, col: u64, contents_index: usize) -> Self {
16 Self {
17 line,
18 col,
19 contents_index,
20 }
21 }
22}
23
24impl Element for EncodedSource {
25 fn len(ctx: &Config) -> usize {
26 2 * u64::len(ctx) + usize::len(ctx)
27 }
28
29 fn validate(&self, preamble: &Preamble) -> io::Result<()> {
30 self.line.validate(preamble)?;
31 self.col.validate(preamble)?;
32 self.contents_index.validate(preamble)?;
33
34 Ok(())
35 }
36}
37
38impl EncodableElement for EncodedSource {
39 fn to_buffer(&self, ctx: &mut EncoderContext, buf: &mut [u8]) {
40 let buf = self.line.encode(ctx, buf);
41 let buf = self.col.encode(ctx, buf);
42 let _ = self.contents_index.encode(ctx, buf);
43 }
44}
45
46impl DecodableElement for EncodedSource {
47 fn try_from_buffer_in_place<'b>(
48 &mut self,
49 ctx: &DecoderContext,
50 buf: &'b [u8],
51 ) -> io::Result<()> {
52 Self::validate_buffer(ctx.config(), buf)?;
53
54 let buf = self.line.try_decode_in_place(ctx, buf)?;
55 let buf = self.col.try_decode_in_place(ctx, buf)?;
56 let _ = self.contents_index.try_decode_in_place(ctx, buf)?;
57
58 Ok(())
59 }
60}
61
62#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
64pub struct EncodableSource {
65 line: u64,
66 col: u64,
67 path: String,
68}
69
70impl EncodableSource {
71 pub const fn new(line: u64, col: u64, path: String) -> Self {
73 Self { line, col, path }
74 }
75
76 pub const fn line(&self) -> u64 {
78 self.line
79 }
80
81 pub const fn col(&self) -> u64 {
83 self.col
84 }
85
86 pub fn path(&self) -> &str {
88 &self.path
89 }
90}
91
92impl Element for EncodableSource {
93 fn len(ctx: &Config) -> usize {
94 EncodedSource::len(ctx)
95 }
96
97 fn validate(&self, preamble: &Preamble) -> io::Result<()> {
98 self.line.validate(preamble)?;
99 self.col.validate(preamble)?;
100
101 Ok(())
102 }
103}
104
105impl EncodableElement for EncodableSource {
106 fn to_buffer(&self, ctx: &mut EncoderContext, buf: &mut [u8]) {
107 let contents_index = ctx.add_path(self.path.clone());
108 let encodable = EncodedSource::new(self.line, self.col, contents_index);
109
110 encodable.to_buffer(ctx, buf)
111 }
112}
113
114#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
116pub struct DecodedSource<'a> {
117 pub(crate) line: u64,
118 pub(crate) col: u64,
119 pub(crate) name: &'a str,
120 pub(crate) contents: &'a str,
121}
122
123impl<'a> Element for DecodedSource<'a> {
124 fn len(ctx: &Config) -> usize {
125 EncodedSource::len(ctx)
126 }
127
128 fn validate(&self, preamble: &Preamble) -> io::Result<()> {
129 self.line.validate(preamble)?;
130 self.col.validate(preamble)?;
131
132 Ok(())
133 }
134}
135
136impl<'a> DecodableElement for DecodedSource<'a> {
137 fn try_from_buffer_in_place<'x, 'b>(
138 &'x mut self,
139 ctx: &DecoderContext<'x>,
140 buf: &'b [u8],
141 ) -> io::Result<()> {
142 let (encoded, _) = EncodedSource::try_decode(ctx, buf)?;
143 let EncodedSource {
144 line,
145 col,
146 contents_index,
147 } = encoded;
148
149 let name = ctx.fetch_name(contents_index).ok_or_else(|| {
150 io::Error::new(
151 io::ErrorKind::Other,
152 "the source name wasn't available in the file cache",
153 )
154 })?;
155
156 let contents = ctx.fetch_contents(contents_index).ok_or_else(|| {
157 io::Error::new(
158 io::ErrorKind::Other,
159 "the source contents wasn't available in the file cache",
160 )
161 })?;
162
163 self.line = line;
164 self.col = col;
165
166 self.name = unsafe { mem::transmute::<&'x str, &'a str>(name) };
171 self.contents = unsafe { mem::transmute::<&'x str, &'a str>(contents) };
172
173 Ok(())
174 }
175}