1use std::cmp::Ordering;
2use std::fmt;
3
4pub const MAX_SAFE_INTEGER: i64 = 9_007_199_254_740_991;
5const MAX_DEPTH: usize = 512;
6
7#[derive(Clone, Debug, PartialEq, Eq)]
8pub enum Value {
9 Null,
10 Bool(bool),
11 Integer(i64),
12 String(String),
13 Array(Vec<Value>),
14 Object(Vec<(String, Value)>),
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19pub enum ErrorKind {
20 InvalidUtf8,
21 ByteOrderMark,
22 UnexpectedEnd,
23 UnexpectedByte,
24 TrailingContent,
25 DepthLimit,
26 DuplicateKey,
27 ControlCharacter,
28 InvalidEscape,
29 LoneSurrogate,
30 NegativeZero,
31 FractionOrExponent,
32 IntegerOutOfRange,
33}
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq)]
36pub struct Error {
37 pub kind: ErrorKind,
38 pub offset: usize,
39}
40
41pub fn parse(bytes: &[u8]) -> Result<Value, Error> {
51 if bytes.get(..3) == Some(&[0xEF, 0xBB, 0xBF]) {
52 return Err(Error {
53 kind: ErrorKind::ByteOrderMark,
54 offset: 0,
55 });
56 }
57 let text = std::str::from_utf8(bytes).map_err(|invalid| Error {
58 kind: ErrorKind::InvalidUtf8,
59 offset: invalid.valid_up_to(),
60 })?;
61 let mut parser = Parser {
62 bytes,
63 text,
64 pos: 0,
65 };
66 parser.skip_whitespace();
67 let value = parser.value(0)?;
68 parser.skip_whitespace();
69 if parser.pos == bytes.len() {
70 Ok(value)
71 } else {
72 Err(parser.error(ErrorKind::TrailingContent))
73 }
74}
75
76#[must_use]
77pub fn canonical(value: &Value) -> Vec<u8> {
78 let mut out = String::new();
79 stream(value, &mut out);
80 out.into_bytes()
81}
82
83#[must_use]
86pub fn canonical_length(value: &Value) -> u64 {
87 let mut count = ByteCount(0);
88 stream(value, &mut count);
89 count.0
90}
91
92pub trait Sink {
95 fn write(&mut self, piece: &str);
96}
97
98impl Sink for String {
99 fn write(&mut self, piece: &str) {
100 self.push_str(piece);
101 }
102}
103
104pub struct ByteCount(pub u64);
106
107impl Sink for ByteCount {
108 fn write(&mut self, piece: &str) {
109 self.0 = self
110 .0
111 .saturating_add(u64::try_from(piece.len()).unwrap_or(u64::MAX));
112 }
113}
114
115pub fn stream<S: Sink + ?Sized>(value: &Value, sink: &mut S) {
119 let mut scratch = Scratch::new();
120 scratch.stream(value, sink);
121}
122
123pub struct Scratch {
128 order: Vec<Vec<usize>>,
129 number: String,
130}
131
132impl Scratch {
133 #[must_use]
134 pub fn new() -> Self {
135 Self {
136 order: Vec::new(),
137 number: String::with_capacity(24),
138 }
139 }
140
141 pub fn stream<S: Sink + ?Sized>(&mut self, value: &Value, sink: &mut S) {
142 self.write_value(value, sink, 0);
143 }
144
145 fn write_value<S: Sink + ?Sized>(&mut self, value: &Value, sink: &mut S, depth: usize) {
146 match value {
147 Value::Null => sink.write("null"),
148 Value::Bool(true) => sink.write("true"),
149 Value::Bool(false) => sink.write("false"),
150 Value::Integer(n) => {
151 self.number.clear();
152 let _infallible = fmt::Write::write_fmt(&mut self.number, format_args!("{n}"));
153 sink.write(&self.number);
154 }
155 Value::String(s) => write_string(sink, s),
156 Value::Array(items) => {
157 sink.write("[");
158 for (i, item) in items.iter().enumerate() {
159 if i > 0 {
160 sink.write(",");
161 }
162 self.write_value(item, sink, depth.saturating_add(1));
163 }
164 sink.write("]");
165 }
166 Value::Object(members) => {
167 self.order_members(members, depth);
168 sink.write("{");
169 let mut position = 0_usize;
170 loop {
171 let member = self
172 .order
173 .get(depth)
174 .and_then(|level| level.get(position))
175 .and_then(|&index| members.get(index));
176 let Some((key, value)) = member else { break };
177 if position > 0 {
178 sink.write(",");
179 }
180 write_string(sink, key);
181 sink.write(":");
182 self.write_value(value, sink, depth.saturating_add(1));
183 position = position.saturating_add(1);
184 }
185 sink.write("}");
186 }
187 }
188 }
189
190 fn order_members(&mut self, members: &[(String, Value)], depth: usize) {
191 while self.order.len() <= depth {
192 self.order.push(Vec::new());
193 }
194 let Some(level) = self.order.get_mut(depth) else {
195 return;
196 };
197 level.clear();
198 level.extend(0..members.len());
199 level.sort_by(|&a, &b| {
200 let left = members.get(a).map_or("", |(key, _)| key.as_str());
201 let right = members.get(b).map_or("", |(key, _)| key.as_str());
202 utf16_cmp(left, right)
203 });
204 }
205}
206
207impl Default for Scratch {
208 fn default() -> Self {
209 Self::new()
210 }
211}
212
213fn utf16_cmp(a: &str, b: &str) -> Ordering {
214 a.encode_utf16().cmp(b.encode_utf16())
215}
216
217fn write_string<S: Sink + ?Sized>(sink: &mut S, s: &str) {
218 sink.write("\"");
219 let mut plain = 0_usize;
220 for (index, c) in s.char_indices() {
221 let escape: Option<&str> = match c {
222 '"' => Some("\\\""),
223 '\\' => Some("\\\\"),
224 '\u{8}' => Some("\\b"),
225 '\t' => Some("\\t"),
226 '\n' => Some("\\n"),
227 '\u{c}' => Some("\\f"),
228 '\r' => Some("\\r"),
229 c if u32::from(c) < 0x20 => Some(control_escape(c)),
230 _ => None,
231 };
232 if let Some(text) = escape {
233 if let Some(run) = s.get(plain..index) {
234 sink.write(run);
235 }
236 sink.write(text);
237 plain = index.saturating_add(c.len_utf8());
238 }
239 }
240 if let Some(run) = s.get(plain..) {
241 sink.write(run);
242 }
243 sink.write("\"");
244}
245
246fn control_escape(c: char) -> &'static str {
249 const FORMS: [&str; 32] = [
250 "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
251 "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011",
252 "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019",
253 "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f",
254 ];
255 FORMS
256 .get(usize::try_from(u32::from(c)).unwrap_or(0))
257 .copied()
258 .unwrap_or("\\u0000")
259}
260
261struct Parser<'a> {
262 bytes: &'a [u8],
263 text: &'a str,
264 pos: usize,
265}
266
267impl Parser<'_> {
268 fn error(&self, kind: ErrorKind) -> Error {
269 Error {
270 kind,
271 offset: self.pos,
272 }
273 }
274
275 fn end_or_unexpected(&self) -> Error {
276 if self.peek().is_none() {
277 self.error(ErrorKind::UnexpectedEnd)
278 } else {
279 self.error(ErrorKind::UnexpectedByte)
280 }
281 }
282
283 fn peek(&self) -> Option<u8> {
284 self.bytes.get(self.pos).copied()
285 }
286
287 fn advance(&mut self) {
288 self.pos = self.pos.saturating_add(1);
289 }
290
291 fn skip_whitespace(&mut self) {
292 while matches!(self.peek(), Some(b' ' | b'\t' | b'\n' | b'\r')) {
293 self.advance();
294 }
295 }
296
297 fn expect(&mut self, byte: u8) -> Result<(), Error> {
298 if self.peek() == Some(byte) {
299 self.advance();
300 Ok(())
301 } else {
302 Err(self.end_or_unexpected())
303 }
304 }
305
306 fn literal(&mut self, text: &[u8]) -> Result<(), Error> {
307 for &byte in text {
308 self.expect(byte)?;
309 }
310 Ok(())
311 }
312
313 fn deeper(&self, depth: usize) -> Result<usize, Error> {
314 let next = depth.saturating_add(1);
315 if next > MAX_DEPTH {
316 Err(self.error(ErrorKind::DepthLimit))
317 } else {
318 Ok(next)
319 }
320 }
321
322 fn value(&mut self, depth: usize) -> Result<Value, Error> {
323 match self.peek() {
324 None => Err(self.error(ErrorKind::UnexpectedEnd)),
325 Some(b'n') => self.literal(b"null").map(|()| Value::Null),
326 Some(b't') => self.literal(b"true").map(|()| Value::Bool(true)),
327 Some(b'f') => self.literal(b"false").map(|()| Value::Bool(false)),
328 Some(b'"') => self.string().map(Value::String),
329 Some(b'{') => self.object(depth),
330 Some(b'[') => self.array(depth),
331 Some(b'-' | b'0'..=b'9') => self.number(),
332 Some(_) => Err(self.error(ErrorKind::UnexpectedByte)),
333 }
334 }
335
336 fn array(&mut self, depth: usize) -> Result<Value, Error> {
337 let depth = self.deeper(depth)?;
338 self.expect(b'[')?;
339 self.skip_whitespace();
340 let mut items = Vec::new();
341 if self.peek() == Some(b']') {
342 self.advance();
343 return Ok(Value::Array(items));
344 }
345 loop {
346 self.skip_whitespace();
347 items.push(self.value(depth)?);
348 self.skip_whitespace();
349 match self.peek() {
350 Some(b',') => self.advance(),
351 Some(b']') => {
352 self.advance();
353 return Ok(Value::Array(items));
354 }
355 _ => return Err(self.end_or_unexpected()),
356 }
357 }
358 }
359
360 fn object(&mut self, depth: usize) -> Result<Value, Error> {
361 let depth = self.deeper(depth)?;
362 self.expect(b'{')?;
363 self.skip_whitespace();
364 if self.peek() == Some(b'}') {
365 self.advance();
366 return Ok(Value::Object(Vec::new()));
367 }
368 let mut members: Vec<(String, Value, usize)> = Vec::new();
369 loop {
370 self.skip_whitespace();
371 let key_offset = self.pos;
372 if self.peek() != Some(b'"') {
373 return Err(self.end_or_unexpected());
374 }
375 let key = self.string()?;
376 self.skip_whitespace();
377 self.expect(b':')?;
378 self.skip_whitespace();
379 let value = self.value(depth)?;
380 members.push((key, value, key_offset));
381 self.skip_whitespace();
382 match self.peek() {
383 Some(b',') => self.advance(),
384 Some(b'}') => {
385 self.advance();
386 break;
387 }
388 _ => return Err(self.end_or_unexpected()),
389 }
390 }
391 members.sort_by(|a, b| utf16_cmp(&a.0, &b.0));
392 for pair in members.windows(2) {
393 if let [left, right] = pair
394 && left.0 == right.0
395 {
396 return Err(Error {
397 kind: ErrorKind::DuplicateKey,
398 offset: right.2,
399 });
400 }
401 }
402 Ok(Value::Object(
403 members.into_iter().map(|(k, v, _)| (k, v)).collect(),
404 ))
405 }
406
407 fn string(&mut self) -> Result<String, Error> {
408 self.expect(b'"')?;
409 let mut out = String::new();
410 let mut segment_start = self.pos;
411 loop {
412 match self.peek() {
413 None => return Err(self.error(ErrorKind::UnexpectedEnd)),
414 Some(b'"') => {
415 self.flush(segment_start, &mut out)?;
416 self.advance();
417 return Ok(out);
418 }
419 Some(b'\\') => {
420 self.flush(segment_start, &mut out)?;
421 self.advance();
422 self.escape(&mut out)?;
423 segment_start = self.pos;
424 }
425 Some(byte) if byte < 0x20 => return Err(self.error(ErrorKind::ControlCharacter)),
426 Some(_) => self.advance(),
427 }
428 }
429 }
430
431 fn flush(&self, from: usize, out: &mut String) -> Result<(), Error> {
432 let segment = self
433 .text
434 .get(from..self.pos)
435 .ok_or_else(|| self.error(ErrorKind::InvalidUtf8))?;
436 out.push_str(segment);
437 Ok(())
438 }
439
440 fn escape(&mut self, out: &mut String) -> Result<(), Error> {
441 let byte = self
442 .peek()
443 .ok_or_else(|| self.error(ErrorKind::UnexpectedEnd))?;
444 self.advance();
445 let simple = match byte {
446 b'"' => Some('"'),
447 b'\\' => Some('\\'),
448 b'/' => Some('/'),
449 b'b' => Some('\u{8}'),
450 b'f' => Some('\u{c}'),
451 b'n' => Some('\n'),
452 b'r' => Some('\r'),
453 b't' => Some('\t'),
454 b'u' => None,
455 _ => {
456 self.pos = self.pos.saturating_sub(1);
457 return Err(self.error(ErrorKind::InvalidEscape));
458 }
459 };
460 if let Some(c) = simple {
461 out.push(c);
462 return Ok(());
463 }
464 let unit = self.hex4()?;
465 let code = match unit {
466 0xD800..=0xDBFF => {
467 if self.peek() != Some(b'\\') {
468 return Err(self.error(ErrorKind::LoneSurrogate));
469 }
470 self.advance();
471 if self.peek() != Some(b'u') {
472 return Err(self.error(ErrorKind::LoneSurrogate));
473 }
474 self.advance();
475 let low = self.hex4()?;
476 if !(0xDC00..=0xDFFF).contains(&low) {
477 return Err(self.error(ErrorKind::LoneSurrogate));
478 }
479 combine_surrogates(unit, low)
480 }
481 0xDC00..=0xDFFF => return Err(self.error(ErrorKind::LoneSurrogate)),
482 unit => unit,
483 };
484 let c = char::from_u32(code).ok_or_else(|| self.error(ErrorKind::LoneSurrogate))?;
485 out.push(c);
486 Ok(())
487 }
488
489 fn hex4(&mut self) -> Result<u32, Error> {
490 let mut code = 0_u32;
491 for _ in 0_u8..4 {
492 let byte = self
493 .peek()
494 .ok_or_else(|| self.error(ErrorKind::UnexpectedEnd))?;
495 let digit = match byte {
496 b'0'..=b'9' => u32::from(byte.wrapping_sub(b'0')),
497 b'a'..=b'f' => u32::from(byte.wrapping_sub(b'a')).wrapping_add(10),
498 b'A'..=b'F' => u32::from(byte.wrapping_sub(b'A')).wrapping_add(10),
499 _ => return Err(self.error(ErrorKind::InvalidEscape)),
500 };
501 code = code.wrapping_shl(4) | digit;
502 self.advance();
503 }
504 Ok(code)
505 }
506
507 fn number(&mut self) -> Result<Value, Error> {
508 let negative = self.peek() == Some(b'-');
509 if negative {
510 self.advance();
511 }
512 let first = self
513 .peek()
514 .ok_or_else(|| self.error(ErrorKind::UnexpectedEnd))?;
515 let mut magnitude: i64 = match first {
516 b'0'..=b'9' => i64::from(first.wrapping_sub(b'0')),
517 _ => return Err(self.error(ErrorKind::UnexpectedByte)),
518 };
519 self.advance();
520 if magnitude == 0 {
521 if matches!(self.peek(), Some(b'0'..=b'9')) {
522 return Err(self.error(ErrorKind::UnexpectedByte));
523 }
524 } else {
525 while let Some(byte @ b'0'..=b'9') = self.peek() {
526 let digit = i64::from(byte.wrapping_sub(b'0'));
527 magnitude = magnitude
528 .checked_mul(10)
529 .and_then(|v| v.checked_add(digit))
530 .ok_or_else(|| self.error(ErrorKind::IntegerOutOfRange))?;
531 self.advance();
532 }
533 }
534 if matches!(self.peek(), Some(b'.' | b'e' | b'E')) {
535 return Err(self.error(ErrorKind::FractionOrExponent));
536 }
537 if magnitude > MAX_SAFE_INTEGER {
538 return Err(self.error(ErrorKind::IntegerOutOfRange));
539 }
540 if negative {
541 if magnitude == 0 {
542 return Err(self.error(ErrorKind::NegativeZero));
543 }
544 magnitude = magnitude.wrapping_neg();
545 }
546 Ok(Value::Integer(magnitude))
547 }
548}
549
550#[expect(clippy::arithmetic_side_effects, reason = "operands are range-checked")]
551fn combine_surrogates(high: u32, low: u32) -> u32 {
552 0x10000 + ((high - 0xD800) << 10) + (low - 0xDC00)
553}