lib_ruby_parser/source/
decoded_input.rs1use crate::source::SourceLine;
2
3#[derive(Debug, Default)]
5#[repr(C)]
6pub struct DecodedInput {
7 pub name: String,
9
10 pub lines: Vec<SourceLine>,
12
13 pub bytes: Vec<u8>,
15}
16
17impl DecodedInput {
18 pub fn named<T>(name: T) -> Self
20 where
21 T: Into<String>,
22 {
23 Self {
24 name: name.into(),
25 ..Default::default()
26 }
27 }
28
29 pub fn into_bytes(self) -> Vec<u8> {
31 self.bytes
32 }
33
34 pub(crate) fn take_bytes(&mut self) -> Vec<u8> {
35 std::mem::take(&mut self.bytes)
36 }
37
38 pub fn update_bytes(&mut self, bytes: Vec<u8>) {
40 let mut line = SourceLine {
41 start: 0,
42 end: 0,
43 ends_with_eof: true,
44 };
45 let mut lines = vec![];
46
47 for (idx, c) in bytes.iter().enumerate() {
48 line.end = idx + 1;
49 if *c == b'\n' {
50 line.ends_with_eof = false;
51 lines.push(line);
52 line = SourceLine {
53 start: idx + 1,
54 end: 0,
55 ends_with_eof: true,
56 }
57 }
58 }
59 line.end = bytes.len();
60 line.ends_with_eof = true;
61 lines.push(line);
62
63 self.bytes = bytes;
64 self.lines = lines;
65 }
66
67 pub fn line_col_for_pos(&self, mut pos: usize) -> Option<(usize, usize)> {
71 if pos == self.len() {
72 let last_line = self.lines.last()?;
74 return Some((self.lines.len() - 1, last_line.len()));
75 }
76
77 for (lineno, line) in self.lines.iter().enumerate() {
78 if line.len() > pos {
79 return Some((lineno, pos));
80 } else {
81 pos -= line.len()
82 }
83 }
84
85 None
86 }
87
88 pub(crate) fn line_at(&self, idx: usize) -> &SourceLine {
89 &self.lines[idx]
90 }
91
92 pub(crate) fn substr_at(&self, start: usize, end: usize) -> Option<&[u8]> {
93 if start <= end && end <= self.bytes.len() {
94 Some(&self.bytes[start..end])
95 } else {
96 None
97 }
98 }
99
100 pub(crate) fn len(&self) -> usize {
101 self.bytes.len()
102 }
103
104 pub fn as_shared_bytes(&self) -> &[u8] {
106 self.bytes.as_slice()
107 }
108}