json_syntax/
code_map.rs

1use core::fmt;
2use std::{borrow::Borrow, ops::Deref};
3
4use locspan::Span;
5
6/// Code-map.
7#[derive(Debug, Default, Clone)]
8pub struct CodeMap(Vec<Entry>);
9
10impl CodeMap {
11	pub fn as_slice(&self) -> &[Entry] {
12		&self.0
13	}
14
15	pub(crate) fn reserve(&mut self, position: usize) -> usize {
16		let i = self.0.len();
17		self.0.push(Entry {
18			span: Span::new(position, position),
19			volume: 0,
20		});
21		i
22	}
23
24	pub(crate) fn get_mut(&mut self, i: usize) -> Option<&mut Entry> {
25		self.0.get_mut(i)
26	}
27
28	pub fn iter(&self) -> Iter {
29		self.0.iter().enumerate()
30	}
31}
32
33impl Deref for CodeMap {
34	type Target = [Entry];
35
36	fn deref(&self) -> &Self::Target {
37		self.as_slice()
38	}
39}
40
41impl AsRef<[Entry]> for CodeMap {
42	fn as_ref(&self) -> &[Entry] {
43		self.as_slice()
44	}
45}
46
47impl Borrow<[Entry]> for CodeMap {
48	fn borrow(&self) -> &[Entry] {
49		self.as_slice()
50	}
51}
52
53pub type Iter<'a> = std::iter::Enumerate<std::slice::Iter<'a, Entry>>;
54
55pub type IntoIter = std::iter::Enumerate<std::vec::IntoIter<Entry>>;
56
57impl<'a> IntoIterator for &'a CodeMap {
58	type IntoIter = Iter<'a>;
59	type Item = (usize, &'a Entry);
60
61	fn into_iter(self) -> Self::IntoIter {
62		self.iter()
63	}
64}
65
66impl IntoIterator for CodeMap {
67	type IntoIter = IntoIter;
68	type Item = (usize, Entry);
69
70	fn into_iter(self) -> Self::IntoIter {
71		self.0.into_iter().enumerate()
72	}
73}
74
75/// Code-map entry.
76///
77/// Provides code-mapping metadata about a fragment of JSON value.
78#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
79pub struct Entry {
80	/// Byte span of the fragment in the original source code.
81	pub span: Span,
82
83	/// Number of sub-fragment (including the fragment itself).
84	pub volume: usize,
85}
86
87impl Entry {
88	pub fn new(span: Span, volume: usize) -> Self {
89		Self { span, volume }
90	}
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
94pub struct Mapped<T> {
95	pub offset: usize,
96	pub value: T,
97}
98
99impl<T> Mapped<T> {
100	pub fn new(offset: usize, value: T) -> Self {
101		Self { offset, value }
102	}
103}
104
105impl<T: fmt::Display> fmt::Display for Mapped<T> {
106	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107		self.value.fmt(f)
108	}
109}
110
111impl<T: 'static + std::error::Error> std::error::Error for Mapped<T> {
112	fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
113		Some(&self.value)
114	}
115}
116
117#[cfg(test)]
118mod tests {
119	use super::Entry;
120	use crate::{Parse, Value};
121	use locspan::Span;
122
123	#[test]
124	fn code_map_t1() {
125		let (value, code_map) = Value::parse_str(r#"{ "a": 0, "b": [1, 2] }"#).unwrap();
126		let expected = [
127			Entry::new(Span::new(0, 23), 9),  // { "a": 0, "b": [1, 2] }
128			Entry::new(Span::new(2, 8), 3),   // "a": 0
129			Entry::new(Span::new(2, 5), 1),   // "a"
130			Entry::new(Span::new(7, 8), 1),   // 0
131			Entry::new(Span::new(10, 21), 5), // "b": [1, 2]
132			Entry::new(Span::new(10, 13), 1), // "b"
133			Entry::new(Span::new(15, 21), 3), // [1, 2]
134			Entry::new(Span::new(16, 17), 1), // 1
135			Entry::new(Span::new(19, 20), 1), // 2
136		];
137
138		assert_eq!(code_map.len(), expected.len());
139		assert_eq!(value.traverse().count(), expected.len());
140		for (i, entry) in code_map {
141			assert_eq!(entry, expected[i])
142		}
143	}
144
145	#[test]
146	fn code_map_t2() {
147		let (value, code_map) =
148			Value::parse_str(r#"{ "a": 0, "b": { "c": 1, "d": [2, 3] }, "e": [4, [5, 6]] }"#)
149				.unwrap();
150		let expected = [
151			Entry::new(Span::new(0, 58), 22), // { "a": 0, "b": { "c": 1, "d": [2, 3] }, "e": [4, [5, 6]] }
152			Entry::new(Span::new(2, 8), 3),   // "a": 0
153			Entry::new(Span::new(2, 5), 1),   // "a"
154			Entry::new(Span::new(7, 8), 1),   // 0
155			Entry::new(Span::new(10, 38), 11), // "b": { "c": 1, "d": [2, 3] }
156			Entry::new(Span::new(10, 13), 1), // "b"
157			Entry::new(Span::new(15, 38), 9), // { "c": 1, "d": [2, 3] }
158			Entry::new(Span::new(17, 23), 3), // "c": 1
159			Entry::new(Span::new(17, 20), 1), // "c"
160			Entry::new(Span::new(22, 23), 1), // 1
161			Entry::new(Span::new(25, 36), 5), // "d": [2, 3]
162			Entry::new(Span::new(25, 28), 1), // "d"
163			Entry::new(Span::new(30, 36), 3), // [2, 3]
164			Entry::new(Span::new(31, 32), 1), // 2
165			Entry::new(Span::new(34, 35), 1), // 3
166			Entry::new(Span::new(40, 56), 7), // "e": [4, [5, 6]]
167			Entry::new(Span::new(40, 43), 1), // "e"
168			Entry::new(Span::new(45, 56), 5), // [4, [5, 6]]
169			Entry::new(Span::new(46, 47), 1), // 4
170			Entry::new(Span::new(49, 55), 3), // [5, 6]
171			Entry::new(Span::new(50, 51), 1), // 5
172			Entry::new(Span::new(53, 54), 1), // 6
173		];
174
175		assert_eq!(code_map.len(), expected.len());
176		assert_eq!(value.traverse().count(), expected.len());
177		for (i, entry) in code_map {
178			assert_eq!(entry, expected[i])
179		}
180	}
181}