1use core::convert::Infallible;
12use decoded_char::DecodedChar;
13use locspan::Span;
14use std::error::Error as StdError;
15use std::fmt;
16
17mod array;
18mod boolean;
19mod null;
20mod number;
21mod object;
22pub(crate) mod slice;
23mod string;
24mod value;
25
26use crate::{CodeMap, Value};
27
28#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
30pub struct Options {
31 pub accept_truncated_surrogate_pair: bool,
37
38 pub accept_invalid_codepoints: bool,
43}
44
45impl Options {
46 #[must_use]
50 pub const fn strict() -> Self {
51 Self {
52 accept_truncated_surrogate_pair: false,
53 accept_invalid_codepoints: false,
54 }
55 }
56
57 #[must_use]
61 pub const fn flexible() -> Self {
62 Self {
63 accept_truncated_surrogate_pair: true,
64 accept_invalid_codepoints: true,
65 }
66 }
67}
68
69impl Default for Options {
70 fn default() -> Self {
71 Self::strict()
72 }
73}
74
75pub fn parse_str_value(content: &str) -> Result<Value, Error> {
85 parse_str_value_with(content, Options::default())
86}
87
88pub fn parse_str_value_with(content: &str, options: Options) -> Result<Value, Error> {
94 let (value, _) = slice::parse_value_str_with(content, options, slice::NoOp)?;
95 Ok(value)
96}
97
98pub fn parse_slice_value(content: &[u8]) -> Result<Value, Error> {
106 parse_slice_value_with(content, Options::default())
107}
108
109pub fn parse_slice_value_with(content: &[u8], options: Options) -> Result<Value, Error> {
115 let (value, _) = slice::parse_value_slice_with(content, options, slice::NoOp)?;
116 Ok(value)
117}
118
119pub trait Parse: Sized {
134 fn parse_slice(content: &[u8]) -> Result<(Self, CodeMap), Error> {
140 Self::parse_utf8(utf8_decode::Decoder::new(content.iter().copied()))
141 .map_err(Error::io_into_utf8)
142 }
143
144 fn parse_slice_with(content: &[u8], options: Options) -> Result<(Self, CodeMap), Error> {
150 Self::parse_utf8_with(utf8_decode::Decoder::new(content.iter().copied()), options)
151 .map_err(Error::io_into_utf8)
152 }
153
154 fn parse_str(content: &str) -> Result<(Self, CodeMap), Error> {
160 Self::parse_utf8(content.chars().map(Ok))
161 }
162
163 fn parse_str_with(content: &str, options: Options) -> Result<(Self, CodeMap), Error> {
169 Self::parse_utf8_with(content.chars().map(Ok), options)
170 }
171
172 fn parse_infallible_utf8<C>(chars: C) -> Result<(Self, CodeMap), Error>
178 where
179 C: Iterator<Item = char>,
180 {
181 Self::parse_infallible(chars.map(DecodedChar::from_utf8))
182 }
183
184 fn parse_utf8_infallible_with<C>(chars: C, options: Options) -> Result<(Self, CodeMap), Error>
191 where
192 C: Iterator<Item = char>,
193 {
194 Self::parse_infallible_with(chars.map(DecodedChar::from_utf8), options)
195 }
196
197 fn parse_utf8<C, E>(chars: C) -> Result<(Self, CodeMap), Error<E>>
206 where
207 C: Iterator<Item = Result<char, E>>,
208 {
209 Self::parse(chars.map(|c| c.map(DecodedChar::from_utf8)))
210 }
211
212 fn parse_utf8_with<C, E>(chars: C, options: Options) -> Result<(Self, CodeMap), Error<E>>
220 where
221 C: Iterator<Item = Result<char, E>>,
222 {
223 Self::parse_with(chars.map(|c| c.map(DecodedChar::from_utf8)), options)
224 }
225
226 fn parse_infallible<C>(chars: C) -> Result<(Self, CodeMap), Error>
236 where
237 C: Iterator<Item = DecodedChar>,
238 {
239 let mut parser = Parser::new(chars.map(Ok));
240 let value = Self::parse_in(&mut parser, Context::None)?.0;
241 Ok((value, parser.code_map))
242 }
243
244 fn parse_infallible_with<C>(chars: C, options: Options) -> Result<(Self, CodeMap), Error>
251 where
252 C: Iterator<Item = DecodedChar>,
253 {
254 let mut parser = Parser::new_with(chars.map(Ok), options);
255 let value = Self::parse_in(&mut parser, Context::None)?.0;
256 Ok((value, parser.code_map))
257 }
258
259 fn parse<C, E>(chars: C) -> Result<(Self, CodeMap), Error<E>>
266 where
267 C: Iterator<Item = Result<DecodedChar, E>>,
268 {
269 let mut parser = Parser::new(chars);
270 let value = Self::parse_in(&mut parser, Context::None)?.0;
271 Ok((value, parser.code_map))
272 }
273
274 fn parse_with<C, E>(chars: C, options: Options) -> Result<(Self, CodeMap), Error<E>>
282 where
283 C: Iterator<Item = Result<DecodedChar, E>>,
284 {
285 let mut parser = Parser::new_with(chars, options);
286 let value = Self::parse_in(&mut parser, Context::None)?.0;
287 Ok((value, parser.code_map))
288 }
289
290 fn parse_in<C, E>(
302 parser: &mut Parser<C, E>,
303 context: Context,
304 ) -> Result<(Self, usize), Error<E>>
305 where
306 C: Iterator<Item = Result<DecodedChar, E>>;
307}
308
309pub struct Parser<C: Iterator<Item = Result<DecodedChar, E>>, E> {
311 chars: C,
313
314 pending: Option<DecodedChar>,
316
317 position: usize,
319
320 options: Options,
322
323 code_map: CodeMap,
325}
326
327#[inline(always)]
329#[must_use]
330pub const fn is_whitespace(c: char) -> bool {
331 matches!(c, ' ' | '\t' | '\r' | '\n')
332}
333
334impl<C: Iterator<Item = Result<DecodedChar, E>>, E> Parser<C, E> {
335 pub fn new(chars: C) -> Self {
337 Self {
338 chars,
339 pending: None,
340 position: 0,
341 options: Options::default(),
342 code_map: CodeMap::default(),
343 }
344 }
345
346 pub fn new_with(chars: C, options: Options) -> Self {
348 Self {
349 chars,
350 pending: None,
351 position: 0,
352 options,
353 code_map: CodeMap::default(),
354 }
355 }
356
357 fn begin_fragment(&mut self) -> usize {
358 self.code_map.reserve(self.position)
359 }
360
361 fn end_fragment(&mut self, i: usize) {
362 let entry_count = self.code_map.len();
363 let Some(entry) = self.code_map.get_mut(i) else {
364 return;
365 };
366 entry.span.end = self.position;
367 entry.volume = entry_count - i;
368 }
369
370 fn peek_char(&mut self) -> Result<Option<char>, Error<E>> {
371 match self.pending {
372 Some(c) => Ok(Some(c.chr())),
373 None => match self.chars.next() {
374 Some(Ok(c)) => {
375 self.pending = Some(c);
376 Ok(Some(c.chr()))
377 }
378 Some(Err(e)) => Err(Error::Stream(self.position, e)),
379 None => Ok(None),
380 },
381 }
382 }
383
384 fn next_char(&mut self) -> Result<(usize, Option<char>), Error<E>> {
385 let c = match self.pending.take() {
386 Some(c) => Some(c),
387 None => self
388 .chars
389 .next()
390 .transpose()
391 .map_err(|e| Error::Stream(self.position, e))?,
392 };
393
394 let p = self.position;
395 let c = c.map(|c| {
396 self.position += c.len();
397 c.chr()
398 });
399
400 Ok((p, c))
401 }
402
403 fn skip_whitespaces(&mut self) -> Result<(), Error<E>> {
404 while let Some(c) = self.peek_char()? {
405 if is_whitespace(c) {
406 self.next_char()?;
407 } else {
408 break;
409 }
410 }
411
412 Ok(())
413 }
414}
415
416#[derive(Debug)]
418pub enum Error<E = Infallible> {
419 Stream(usize, E),
423
424 Unexpected(usize, Option<char>),
428
429 InvalidUnicodeCodePoint(Span, u32),
433
434 MissingLowSurrogate(Span, u32),
438
439 InvalidLowSurrogate(Span, u32, u32),
443
444 InvalidUtf8(usize),
446}
447
448impl<E> Error<E> {
449 #[inline(always)]
451 const fn unexpected(position: usize, c: Option<char>) -> Self {
452 Self::Unexpected(position, c)
454 }
455
456 pub const fn position(&self) -> usize {
458 match self {
459 Self::Stream(p, _) | Self::Unexpected(p, _) | Self::InvalidUtf8(p) => *p,
460 Self::InvalidUnicodeCodePoint(span, _)
461 | Self::MissingLowSurrogate(span, _)
462 | Self::InvalidLowSurrogate(span, _, _) => span.start,
463 }
464 }
465
466 pub fn span(&self) -> Span {
470 match self {
471 Self::Stream(p, _) | Self::Unexpected(p, _) | Self::InvalidUtf8(p) => Span::new(*p, *p),
472 Self::InvalidUnicodeCodePoint(span, _)
473 | Self::MissingLowSurrogate(span, _)
474 | Self::InvalidLowSurrogate(span, _, _) => *span,
475 }
476 }
477}
478
479impl Error<utf8_decode::Utf8Error> {
480 const fn io_into_utf8(self) -> Error {
481 match self {
482 Self::Stream(p, _) | Self::InvalidUtf8(p) => Error::InvalidUtf8(p),
483 Self::Unexpected(p, e) => Error::Unexpected(p, e),
484 Self::InvalidUnicodeCodePoint(s, e) => Error::InvalidUnicodeCodePoint(s, e),
485 Self::MissingLowSurrogate(s, e) => Error::MissingLowSurrogate(s, e),
486 Self::InvalidLowSurrogate(s, a, b) => Error::InvalidLowSurrogate(s, a, b),
487 }
488 }
489}
490
491impl<E: fmt::Display> fmt::Display for Error<E> {
492 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
493 match self {
494 Self::Stream(_, e) => e.fmt(f),
495 Self::Unexpected(_, Some(c)) => write!(f, "unexpected character `{c}`"),
496 Self::Unexpected(_, None) => write!(f, "unexpected end of file"),
497 Self::InvalidUnicodeCodePoint(_, c) => write!(f, "invalid Unicode code point {:x}", *c),
498 Self::MissingLowSurrogate(_, _) => write!(f, "missing low surrogate"),
499 Self::InvalidLowSurrogate(_, _, _) => write!(f, "invalid low surrogate"),
500 Self::InvalidUtf8(_) => write!(f, "invalid UTF-8"),
501 }
502 }
503}
504
505impl<E: 'static + StdError> StdError for Error<E> {
506 fn source(&self) -> Option<&(dyn StdError + 'static)> {
507 match self {
508 Self::Stream(_, e) => Some(e),
509 Self::Unexpected(..)
510 | Self::InvalidUnicodeCodePoint(..)
511 | Self::MissingLowSurrogate(..)
512 | Self::InvalidLowSurrogate(..)
513 | Self::InvalidUtf8(..) => None,
514 }
515 }
516}
517
518#[derive(Clone, Copy, PartialEq, Eq, Debug)]
522pub enum Context {
523 None,
525
526 Array,
528
529 ObjectKey,
531
532 ObjectValue,
534}
535
536impl Context {
537 #[must_use]
539 pub const fn follows(&self, c: char) -> bool {
540 match self {
541 Self::None => is_whitespace(c),
542 Self::Array => is_whitespace(c) || matches!(c, ',' | ']'),
543 Self::ObjectKey => is_whitespace(c) || matches!(c, ':'),
544 Self::ObjectValue => is_whitespace(c) || matches!(c, ',' | '}'),
545 }
546 }
547}