Skip to main content

ocpi_tariffs/json/
parser.rs

1//! A JSON parse built to keep track of where each element came from in the input.
2#[cfg(test)]
3pub(crate) mod test;
4
5#[cfg(test)]
6mod test_basic_happy_structure;
7
8#[cfg(test)]
9mod test_error_reporting;
10
11#[cfg(test)]
12mod test_type_sizes;
13
14#[cfg(test)]
15mod test_line_col;
16
17#[cfg(test)]
18mod test_raw_str;
19
20#[cfg(test)]
21mod test_parser;
22
23use std::borrow::{Borrow, Cow};
24use std::fmt;
25use std::iter::Peekable;
26use std::num::TryFromIntError;
27use std::str::Bytes;
28use std::sync::atomic::AtomicUsize;
29use std::sync::Arc;
30
31use json_tools::{Buffer, BufferType};
32use tracing::{debug, trace};
33
34use crate::{warning, Caveat, ReasonableStr};
35
36use super::{
37    decode::{self, unescape_str},
38    Element, Field, ObjectKind, PathNode, PathNodeRef, Value, ValueKind,
39};
40use super::{ElemId, Path};
41
42/// We peek at the next `Token` when asserting on trailing commas.
43type Lexer<'buf> = Peekable<json_tools::Lexer<Bytes<'buf>>>;
44
45/// Parse the JSON into a tree of [`Element`]s.
46pub(crate) fn parse(json: ReasonableStr<'_>) -> Result<Element<'_>, Error> {
47    let parser = Parser::new(json.into_inner());
48
49    // When just parsing the JSON into an `Element` we only care about the final event
50    // when the JSON has been completely transformed into a root element.
51    for event in parser {
52        if let Event::Complete(element) = event? {
53            return Ok(element);
54        }
55    }
56
57    Err(ErrorKind::UnexpectedEOF
58        .into_partial_error_without_token()
59        .with_root_path())
60}
61
62/// A parsing event emitted for each call to the `<Parser as Iterator>::next` function.
63#[derive(Debug)]
64pub(crate) enum Event<'buf> {
65    /// An [`Element`] has been opened and it's construction is in progress.
66    Open {
67        kind: ObjectKind,
68        parent_path: PathNodeRef<'buf>,
69    },
70
71    /// An [`Element`] has been created and added to its parent [`Element`].
72    ///
73    /// If the kind is `Array` or `Object` that means that this element is closed: its construction is complete.
74    Element {
75        /// The kind of JSON value the [`Element`] is.
76        kind: ValueKind,
77        /// The path to the parent [`Element`].
78        parent_path: PathNodeRef<'buf>,
79    },
80
81    /// The parse has completed creating the tree of [`Element`]s.
82    Complete(Element<'buf>),
83}
84
85/// The context needed to parse a single chunk of JSON.
86pub(crate) struct Parser<'buf> {
87    /// Used to assign a unique [`ElemId`] to each [`Element`].
88    elem_count: AtomicUsize,
89
90    /// True if the `Parser` is complete.
91    ///
92    /// Any further calls to [`Parser::next`] will return `None`.
93    complete: bool,
94
95    /// The source JSON we're parsing.
96    json: &'buf str,
97
98    /// The JSON lexer.
99    lexer: Lexer<'buf>,
100
101    /// The pool with pre-allocated `Path`s.
102    path_pool: PathPool<'buf>,
103
104    /// The stack to track nested objects.
105    stack: Stack<'buf>,
106
107    /// The previous token seen.
108    token: Option<Token>,
109}
110
111/// Define our own `TokenType` so Clone can be defined on it.
112///
113/// This can be removed when `json_tools::TokenType` impls `Clone`.
114#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
115pub enum TokenType {
116    /// `false`.
117    BooleanFalse,
118    /// `true`.
119    BooleanTrue,
120
121    /// `]`.
122    BracketClose,
123    /// `[`.
124    BracketOpen,
125
126    /// `:`.
127    Colon,
128
129    /// `,`.
130    Comma,
131
132    /// `}`.
133    CurlyClose,
134    /// `{`.
135    CurlyOpen,
136
137    /// The type of the token could not be identified.
138    /// Should be removed if this lexer is ever to be feature complete.
139    Invalid,
140
141    /// `null`.
142    Null,
143
144    /// A Number, like `1.1234` or `123` or `-0.0` or `-1` or `.0` or `.`.
145    Number,
146
147    /// A JSON string, like `"foo"`.
148    String,
149}
150
151impl TokenType {
152    fn as_str(self) -> &'static str {
153        match self {
154            TokenType::BooleanFalse => "false",
155            TokenType::BooleanTrue => "true",
156            TokenType::BracketClose => "]",
157            TokenType::BracketOpen => "[",
158            TokenType::Colon => ":",
159            TokenType::Comma => ",",
160            TokenType::CurlyClose => "}",
161            TokenType::CurlyOpen => "{",
162            TokenType::Invalid => "<invalid>",
163            TokenType::Null => "null",
164            TokenType::Number => "<number>",
165            TokenType::String => "<string>",
166        }
167    }
168}
169
170impl fmt::Display for TokenType {
171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172        f.write_str(self.as_str())
173    }
174}
175
176impl From<json_tools::TokenType> for TokenType {
177    fn from(value: json_tools::TokenType) -> Self {
178        match value {
179            json_tools::TokenType::BooleanFalse => TokenType::BooleanFalse,
180            json_tools::TokenType::BooleanTrue => TokenType::BooleanTrue,
181            json_tools::TokenType::BracketClose => TokenType::BracketClose,
182            json_tools::TokenType::BracketOpen => TokenType::BracketOpen,
183            json_tools::TokenType::CurlyClose => TokenType::CurlyClose,
184            json_tools::TokenType::CurlyOpen => TokenType::CurlyOpen,
185            json_tools::TokenType::Colon => TokenType::Colon,
186            json_tools::TokenType::Comma => TokenType::Comma,
187            json_tools::TokenType::Invalid => TokenType::Invalid,
188            json_tools::TokenType::Null => TokenType::Null,
189            json_tools::TokenType::Number => TokenType::Number,
190            json_tools::TokenType::String => TokenType::String,
191        }
192    }
193}
194
195/// A lexical token, identifying its kind and span.
196///
197/// We define our own `Token` as the `json_tools::Token` defines a `Buffer` that can be heap allocated
198/// or a `Span`. We only use the `Span` variant.
199///
200/// Our `Token` can also impl `Copy` and `Clone` as the size and semantics are acceptable.
201#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
202pub struct Token {
203    /// The exact type of the token.
204    pub kind: TokenType,
205
206    /// The span allows the caller to reference back into the source byte stream
207    /// to obtain the string making up the token.
208    pub span: Span,
209}
210
211impl Token {
212    /// Return true is the token is an opening brace.
213    fn is_opening(&self) -> bool {
214        matches!(self.kind, TokenType::CurlyOpen | TokenType::BracketOpen)
215    }
216
217    /// Return true is the token is a closing brace.
218    fn is_closing(&self) -> bool {
219        matches!(self.kind, TokenType::CurlyClose | TokenType::BracketClose)
220    }
221
222    /// Return true is the token is a comma.
223    fn is_comma(&self) -> bool {
224        matches!(self.kind, TokenType::Comma)
225    }
226}
227
228impl fmt::Display for Token {
229    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230        write!(
231            f,
232            "token: {}, ({},{})",
233            self.kind, self.span.start, self.span.end
234        )
235    }
236}
237
238impl TryFrom<json_tools::Token> for Token {
239    type Error = PartialError;
240
241    fn try_from(token: json_tools::Token) -> Result<Self, Self::Error> {
242        let json_tools::Token { kind, buf } = token;
243        let kind = kind.into();
244        let Buffer::Span(span) = &buf else {
245            return Err(InternalError::BufferType.into_partial_error(None));
246        };
247
248        let span = span
249            .try_into()
250            .map_err(|err| InternalError::from(err).into_partial_error(None))?;
251
252        Ok(Self { kind, span })
253    }
254}
255
256impl TryFrom<&json_tools::Token> for Token {
257    type Error = PartialError;
258
259    fn try_from(token: &json_tools::Token) -> Result<Self, Self::Error> {
260        let json_tools::Token { kind, buf } = token;
261        let kind = kind.clone().into();
262        let Buffer::Span(span) = &buf else {
263            return Err(InternalError::BufferType.into_partial_error(None));
264        };
265
266        let span = span
267            .try_into()
268            .map_err(|err| InternalError::from(err).into_partial_error(None))?;
269
270        Ok(Self { kind, span })
271    }
272}
273
274impl<'buf> Parser<'buf> {
275    pub fn new(json: &'buf str) -> Self {
276        let lexer = json_tools::Lexer::new(json.bytes(), BufferType::Span).peekable();
277
278        Self {
279            elem_count: AtomicUsize::new(0),
280            complete: false,
281            json,
282            lexer,
283            path_pool: PathPool::default(),
284            stack: Stack::new(),
285            token: None,
286        }
287    }
288
289    fn next_elem_id(&self) -> ElemId {
290        let id = self
291            .elem_count
292            .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
293
294        ElemId(id)
295    }
296
297    fn expect_next(&mut self) -> Result<Token, PartialError> {
298        let Some(token) = self.lexer.next() else {
299            return Err(ErrorKind::UnexpectedEOF.into_partial_error(self.token.take()));
300        };
301
302        let token = token.try_into()?;
303
304        Ok(token)
305    }
306
307    /// Return an `Err` if the next token is not the expected.
308    fn expect_token(&mut self, token_type: TokenType) -> Result<(), PartialError> {
309        let Some(token) = self.lexer.next() else {
310            return Err(ErrorKind::UnexpectedEOF.into_partial_error(self.token.take()));
311        };
312
313        let token: Token = token.try_into()?;
314
315        if token.kind == token_type {
316            Ok(())
317        } else {
318            Err(unexpected_token(token))
319        }
320    }
321
322    #[expect(
323        clippy::cognitive_complexity,
324        reason = "Lifetimes make splitting this function more effort than it's worth"
325    )]
326    fn next_event(&mut self) -> Result<Option<Event<'buf>>, Error> {
327        if self.complete {
328            return Ok(None);
329        }
330
331        let head = self.stack.pop_head();
332
333        match head {
334            None => {
335                let token = self.expect_next().with_root_path()?;
336
337                trace!(?token);
338                self.comma_checks(&token).with_root_path()?;
339
340                match token.kind {
341                    TokenType::CurlyOpen => {
342                        let parent_path = self.path_pool.root();
343                        self.stack.push_new_object(
344                            self.next_elem_id(),
345                            Arc::clone(&parent_path),
346                            &token,
347                        );
348                        Ok(Some(Event::Open {
349                            kind: ObjectKind::Object,
350                            parent_path,
351                        }))
352                    }
353                    TokenType::BracketOpen => {
354                        let parent_path = self.path_pool.root();
355                        self.stack.push_new_array(
356                            self.next_elem_id(),
357                            Arc::clone(&parent_path),
358                            &token,
359                        );
360                        Ok(Some(Event::Open {
361                            kind: ObjectKind::Array,
362                            parent_path,
363                        }))
364                    }
365                    TokenType::Number => {
366                        let value = Value::Number(token_str(self.json, &token).with_root_path()?);
367                        self.exit_with_value(token, value).with_root_path()
368                    }
369                    TokenType::Null => self.exit_with_value(token, Value::Null).with_root_path(),
370                    TokenType::String => {
371                        let value =
372                            Value::String(token_str_as_string(self.json, token).with_root_path()?);
373                        self.exit_with_value(token, value).with_root_path()
374                    }
375                    TokenType::BooleanTrue => {
376                        self.exit_with_value(token, Value::True).with_root_path()
377                    }
378                    TokenType::BooleanFalse => {
379                        self.exit_with_value(token, Value::False).with_root_path()
380                    }
381                    TokenType::BracketClose
382                    | TokenType::Colon
383                    | TokenType::Comma
384                    | TokenType::CurlyClose
385                    | TokenType::Invalid => Err(unexpected_token(token).with_root_path()),
386                }
387            }
388            Some(mut head) => {
389                let token = self.expect_next().with_head(&head)?;
390
391                trace!(?token, head = ?head.elem_type);
392                let token = if self.comma_checks(&token).with_head(&head)? {
393                    self.expect_next().with_head(&head)?
394                } else {
395                    token
396                };
397
398                let (value, token, path) = match head.elem_type {
399                    ObjectKind::Object => {
400                        let key = match token.kind {
401                            TokenType::String => {
402                                token_str_as_string(self.json, token).with_head(&head)?
403                            }
404                            TokenType::CurlyClose => {
405                                let event = self.close_element(head, &token)?;
406                                return Ok(event);
407                            }
408                            TokenType::BooleanFalse
409                            | TokenType::BooleanTrue
410                            | TokenType::BracketClose
411                            | TokenType::BracketOpen
412                            | TokenType::Colon
413                            | TokenType::Comma
414                            | TokenType::CurlyOpen
415                            | TokenType::Invalid
416                            | TokenType::Null
417                            | TokenType::Number => {
418                                return Err(unexpected_token(token).with_root_path())
419                            }
420                        };
421
422                        self.expect_token(TokenType::Colon).with_head(&head)?;
423                        let token = self.expect_next().with_head(&head)?;
424
425                        let value = match token.kind {
426                            TokenType::CurlyOpen => {
427                                let Some(parent_path) =
428                                    head.parent_is_object(&mut self.path_pool, key)
429                                else {
430                                    return Ok(None);
431                                };
432                                self.stack.push_head(head);
433                                self.stack.push_new_object(
434                                    self.next_elem_id(),
435                                    Arc::clone(&parent_path),
436                                    &token,
437                                );
438                                return Ok(Some(Event::Open {
439                                    kind: ObjectKind::Object,
440                                    parent_path,
441                                }));
442                            }
443                            TokenType::BracketOpen => {
444                                let Some(parent_path) =
445                                    head.parent_is_object(&mut self.path_pool, key)
446                                else {
447                                    return Ok(None);
448                                };
449                                self.stack.push_head(head);
450                                self.stack.push_new_array(
451                                    self.next_elem_id(),
452                                    Arc::clone(&parent_path),
453                                    &token,
454                                );
455                                return Ok(Some(Event::Open {
456                                    kind: ObjectKind::Array,
457                                    parent_path,
458                                }));
459                            }
460                            TokenType::CurlyClose => {
461                                let event = self.close_element(head, &token)?;
462                                return Ok(event);
463                            }
464                            TokenType::String => Value::String(
465                                token_str_as_string(self.json, token).with_head(&head)?,
466                            ),
467                            TokenType::Number => {
468                                Value::Number(token_str(self.json, &token).with_head(&head)?)
469                            }
470                            TokenType::Null => Value::Null,
471                            TokenType::BooleanTrue => Value::True,
472                            TokenType::BooleanFalse => Value::False,
473                            TokenType::BracketClose
474                            | TokenType::Colon
475                            | TokenType::Comma
476                            | TokenType::Invalid => {
477                                return Err(unexpected_token(token).with_head(&head))
478                            }
479                        };
480
481                        let Some(path) = head.parent_is_object(&mut self.path_pool, key) else {
482                            return Ok(None);
483                        };
484                        (value, token, path)
485                    }
486                    ObjectKind::Array => {
487                        let value = match token.kind {
488                            TokenType::CurlyOpen => {
489                                let Some(parent_path) = head.parent_is_array(&mut self.path_pool)
490                                else {
491                                    return Ok(None);
492                                };
493                                self.stack.push_head(head);
494                                self.stack.push_new_object(
495                                    self.next_elem_id(),
496                                    Arc::clone(&parent_path),
497                                    &token,
498                                );
499                                return Ok(Some(Event::Open {
500                                    kind: ObjectKind::Object,
501                                    parent_path,
502                                }));
503                            }
504                            TokenType::BracketOpen => {
505                                let Some(parent_path) = head.parent_is_array(&mut self.path_pool)
506                                else {
507                                    return Ok(None);
508                                };
509                                self.stack.push_head(head);
510                                self.stack.push_new_array(
511                                    self.next_elem_id(),
512                                    Arc::clone(&parent_path),
513                                    &token,
514                                );
515                                return Ok(Some(Event::Open {
516                                    kind: ObjectKind::Array,
517                                    parent_path,
518                                }));
519                            }
520                            TokenType::BracketClose => {
521                                let event = self.close_element(head, &token)?;
522                                return Ok(event);
523                            }
524
525                            TokenType::String => Value::String(
526                                token_str_as_string(self.json, token).with_head(&head)?,
527                            ),
528                            TokenType::Number => {
529                                Value::Number(token_str(self.json, &token).with_head(&head)?)
530                            }
531                            TokenType::Null => Value::Null,
532                            TokenType::BooleanTrue => Value::True,
533                            TokenType::BooleanFalse => Value::False,
534                            TokenType::Invalid
535                            | TokenType::CurlyClose
536                            | TokenType::Colon
537                            | TokenType::Comma => {
538                                return Err(unexpected_token(token).with_head(&head))
539                            }
540                        };
541                        let Some(path) = head.parent_is_array(&mut self.path_pool) else {
542                            return Ok(None);
543                        };
544                        (value, token, path)
545                    }
546                };
547
548                let event = Event::Element {
549                    kind: value.kind(),
550                    parent_path: Arc::clone(&path),
551                };
552                head.push_field(self.next_elem_id(), path, value, &token);
553
554                let peek_token = self.peek(&token).with_head(&head)?;
555
556                if !(peek_token.is_comma() || peek_token.is_closing()) {
557                    return Err(unexpected_token(peek_token).with_head(&head));
558                }
559
560                self.token.replace(token);
561                self.stack.push_head(head);
562
563                Ok(Some(event))
564            }
565        }
566    }
567
568    /// Close a [`PartialElement`] which creates an [`Element`] and returns an [`Event`].
569    fn close_element(
570        &mut self,
571        head: PartialElement<'buf>,
572        token: &Token,
573    ) -> Result<Option<Event<'buf>>, Error> {
574        let event = self.stack.head_into_element(head, token);
575
576        match event {
577            Pop::Element { kind, parent_path } => Ok(Some(Event::Element { kind, parent_path })),
578            Pop::Complete(element) => {
579                if let Some(token) = self.lexer.next() {
580                    let token = token.try_into().with_root_path()?;
581                    return Err(unexpected_token(token).with_root_path());
582                }
583
584                Ok(Some(Event::Complete(element)))
585            }
586        }
587    }
588
589    fn exit_with_value(
590        &mut self,
591        token: Token,
592        value: Value<'buf>,
593    ) -> Result<Option<Event<'buf>>, PartialError> {
594        self.complete = true;
595        let span = element_span(&token, 0);
596        let elem = Element::new(self.next_elem_id(), Arc::new(PathNode::Root), span, value);
597
598        if let Some(token) = self.lexer.next() {
599            let token = token.try_into()?;
600            return Err(unexpected_token(token));
601        }
602
603        Ok(Some(Event::Complete(elem)))
604    }
605
606    fn peek(&mut self, token: &Token) -> Result<Token, PartialError> {
607        let Some(peek_token) = self.lexer.peek() else {
608            return Err(ErrorKind::UnexpectedEOF.into_partial_error(Some(*token)));
609        };
610
611        let peek_token = peek_token.try_into()?;
612        Ok(peek_token)
613    }
614
615    /// Perform comma position checks.
616    ///
617    /// Return `Err(unexpected)` if a trailing or rogue comma is found.
618    fn comma_checks(&mut self, token: &Token) -> Result<bool, PartialError> {
619        trace!(?token, "comma_checks");
620        let is_comma = token.is_comma();
621
622        if is_comma {
623            let peek_token = self.peek(token)?;
624
625            // A comma can only be followed by an opening brace or a value.
626            if peek_token.is_closing() {
627                return Err(unexpected_token(*token));
628            }
629
630            if peek_token.is_comma() {
631                return Err(unexpected_token(peek_token));
632            }
633        } else if token.is_opening() {
634            let peek_token = self.peek(token)?;
635
636            // An opening brace should not be followed by a comma.
637            if peek_token.is_comma() {
638                return Err(unexpected_token(peek_token));
639            }
640        }
641
642        Ok(is_comma)
643    }
644}
645
646/// Create an [`PartialError`] with [`ErrorKind::UnexpectedToken`].
647#[track_caller]
648fn unexpected_token(token: Token) -> PartialError {
649    ErrorKind::UnexpectedToken.into_partial_error(Some(token))
650}
651
652impl<'buf> Iterator for Parser<'buf> {
653    type Item = Result<Event<'buf>, Error>;
654
655    fn next(&mut self) -> Option<Self::Item> {
656        match self.next_event() {
657            Ok(event) => event.map(Ok),
658            Err(err) => {
659                self.complete = true;
660                Some(Err(err))
661            }
662        }
663    }
664}
665
666/// A partial `Element` that we descend into and parse it's child `Element`s.
667#[derive(Debug)]
668struct PartialElement<'buf> {
669    /// The Id of the [`Element`] to be created.
670    elem_id: ElemId,
671
672    /// The type of [`Element`].
673    elem_type: ObjectKind,
674
675    /// The child [`Element`]s.
676    ///
677    /// This is filled as we parse the current JSON [`Element`].
678    elements: Vec<Element<'buf>>,
679
680    /// The path up to the [`Element`].
681    path: PathNodeRef<'buf>,
682
683    /// The index of the [`Element`]'s first byte.
684    span_start: usize,
685}
686
687impl<'buf> PartialElement<'buf> {
688    fn parent_is_object(
689        &self,
690        path_pool: &mut PathPool<'buf>,
691        key: RawStr<'buf>,
692    ) -> Option<PathNodeRef<'buf>> {
693        path_pool.object(Arc::clone(&self.path), key)
694    }
695
696    fn parent_is_array(&self, path_pool: &mut PathPool<'buf>) -> Option<PathNodeRef<'buf>> {
697        path_pool.array(Arc::clone(&self.path), self.elements.len())
698    }
699
700    fn push_field(
701        &mut self,
702        elem_id: ElemId,
703        path: PathNodeRef<'buf>,
704        value: Value<'buf>,
705        token: &Token,
706    ) {
707        let span = element_span(token, token.span.start);
708        let elem = Element::new(elem_id, path, span, value);
709        self.elements.push(elem);
710    }
711
712    /// Resolve the `PartialElement` to an `Element`.
713    fn into_element(self, token: &Token) -> Element<'buf> {
714        let span = element_span(token, self.span_start);
715
716        let PartialElement {
717            elem_type,
718            span_start: _,
719            elements,
720            path,
721            elem_id,
722        } = self;
723
724        let value = match elem_type {
725            ObjectKind::Object => {
726                let fields = elements.into_iter().map(Field).collect();
727                Value::Object(fields)
728            }
729            ObjectKind::Array => Value::Array(elements),
730        };
731
732        Element::new(elem_id, path, span, value)
733    }
734}
735
736/// `Path`s are added and never removed.
737struct PathPool<'buf> {
738    index: usize,
739    items: Vec<PathNodeRef<'buf>>,
740}
741
742impl Default for PathPool<'_> {
743    fn default() -> Self {
744        Self::with_capacity(1000)
745    }
746}
747
748impl<'buf> PathPool<'buf> {
749    fn with_capacity(capacity: usize) -> Self {
750        let capacity = capacity.max(1);
751        let mut items = Vec::with_capacity(capacity);
752        items.resize_with(capacity, Default::default);
753
754        Self { index: 0, items }
755    }
756
757    #[expect(
758        clippy::indexing_slicing,
759        reason = "The root Path is added in the constructor and the capacity is always at least 1"
760    )]
761    fn root(&self) -> PathNodeRef<'buf> {
762        Arc::clone(&self.items[0])
763    }
764
765    /// Add a new `Path::Array` with the given index.
766    fn array(&mut self, parent: PathNodeRef<'buf>, index: usize) -> Option<PathNodeRef<'buf>> {
767        self.push(PathNode::Array { parent, index })
768    }
769
770    /// Add a new `Path::Object` with the given index.
771    fn object(
772        &mut self,
773        parent: PathNodeRef<'buf>,
774        key: RawStr<'buf>,
775    ) -> Option<PathNodeRef<'buf>> {
776        self.push(PathNode::Object { parent, key })
777    }
778
779    fn push(&mut self, new_path: PathNode<'buf>) -> Option<PathNodeRef<'buf>> {
780        const GROWTH_FACTOR: usize = 2;
781
782        let Self { index, items } = self;
783        let next_index = index.checked_add(1)?;
784
785        if next_index >= items.len() {
786            items.reserve(items.len().saturating_mul(GROWTH_FACTOR));
787            items.resize_with(items.capacity(), Default::default);
788        }
789
790        let path = items.get_mut(next_index)?;
791        debug_assert_eq!(Arc::strong_count(path), 1, "Paths are only added");
792        let path = Arc::get_mut(path)?;
793        *path = new_path;
794
795        let path = items.get_mut(next_index)?;
796        let path_result = Arc::clone(path);
797
798        *index = next_index;
799        Some(path_result)
800    }
801}
802
803/// The `Span` defines the range of bytes that delimits a JSON `Element`.
804#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
805pub struct Span {
806    /// Index of the first the byte.
807    pub start: usize,
808
809    /// Index one past the last byte.
810    pub end: usize,
811}
812
813impl TryFrom<&json_tools::Span> for Span {
814    type Error = TryFromIntError;
815
816    fn try_from(span: &json_tools::Span) -> Result<Self, Self::Error> {
817        let json_tools::Span { first, end } = span;
818        let start = usize::try_from(*first)?;
819        let end = usize::try_from(*end)?;
820        Ok(Span { start, end })
821    }
822}
823
824struct Stack<'buf>(Vec<PartialElement<'buf>>);
825
826enum Pop<'buf> {
827    /// An [`Element`] has been created and added to its parent [`Element`].
828    Element {
829        kind: ValueKind,
830        parent_path: PathNodeRef<'buf>,
831    },
832
833    /// The parse has completed creating the tree of [`Element`]s.
834    Complete(Element<'buf>),
835}
836
837impl<'buf> Stack<'buf> {
838    fn new() -> Self {
839        Self(vec![])
840    }
841
842    /// The head `PartialElement` is popped off the stack temporarily to avoid lifetime issues if the
843    /// stack `Vec` contains it.
844    fn pop_head(&mut self) -> Option<PartialElement<'buf>> {
845        self.0.pop()
846    }
847
848    /// The head `PartialElement` is popped off the stack temporarily to avoid lifetime issues if the
849    /// stack `Vec` contains it.
850    fn push_head(&mut self, head: PartialElement<'buf>) {
851        self.0.push(head);
852    }
853
854    /// Convert the head `PartialElement` into an `Element` using the parent to form the path.
855    fn head_into_element(&mut self, head: PartialElement<'buf>, token: &Token) -> Pop<'buf> {
856        let elem = head.into_element(token);
857
858        if let Some(parent) = self.0.last_mut() {
859            let event = Pop::Element {
860                kind: elem.value.kind(),
861                parent_path: elem.path_node(),
862            };
863            parent.elements.push(elem);
864            event
865        } else {
866            Pop::Complete(elem)
867        }
868    }
869
870    fn push_new_object(&mut self, elem_id: ElemId, parent_path: PathNodeRef<'buf>, token: &Token) {
871        self.push_new_elem(elem_id, parent_path, token, ObjectKind::Object);
872    }
873
874    fn push_new_array(&mut self, elem_id: ElemId, parent_path: PathNodeRef<'buf>, token: &Token) {
875        self.push_new_elem(elem_id, parent_path, token, ObjectKind::Array);
876    }
877
878    fn push_new_elem(
879        &mut self,
880        elem_id: ElemId,
881        parent_path: PathNodeRef<'buf>,
882        token: &Token,
883        elem_type: ObjectKind,
884    ) {
885        let partial = PartialElement {
886            elements: vec![],
887            elem_type,
888            path: parent_path,
889            span_start: token.span.start,
890            elem_id,
891        };
892        self.0.push(partial);
893    }
894}
895
896/// A parsing Error that keeps track of the token being parsed when the Error occurred and
897/// the slice of JSON surrounding the Error location.
898pub struct Error(Box<ErrorImpl>);
899
900impl crate::Warning for Error {
901    fn id(&self) -> warning::Id {
902        match self.0.kind {
903            ErrorKind::Internal(_) => warning::Id::from_static("internal"),
904            ErrorKind::UnexpectedEOF => warning::Id::from_static("unexpected_eof"),
905            ErrorKind::UnexpectedToken => warning::Id::from_static("unexpected_token"),
906        }
907    }
908}
909
910impl fmt::Debug for Error {
911    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
912        fmt::Debug::fmt(&self.0, f)
913    }
914}
915
916impl From<ErrorImpl> for Error {
917    fn from(err: ErrorImpl) -> Self {
918        Self(err.into())
919    }
920}
921
922struct ErrorImpl {
923    /// The kind of error that occurred.
924    kind: ErrorKind,
925
926    /// The location the [`Error`] happened in the source code.
927    loc: &'static std::panic::Location<'static>,
928
929    /// The path to the [`Element`] the error occurred in.
930    path: Path,
931
932    /// The span of the JSON string the error occurred in.
933    span: Span,
934
935    /// The token being parsed at the time of the [`Error`].
936    token: Option<Token>,
937}
938
939impl fmt::Debug for ErrorImpl {
940    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
941        f.debug_struct("Error")
942            .field("kind", &self.kind)
943            .field("loc", &self.loc)
944            .field("path", &self.path)
945            .field("span", &self.span)
946            .field("token", &self.token)
947            .finish()
948    }
949}
950
951impl Error {
952    /// The kind of error that occurred.
953    pub fn kind(&self) -> &ErrorKind {
954        &self.0.kind
955    }
956
957    /// The path to the element the error occurred in.
958    pub fn path(&self) -> &Path {
959        &self.0.path
960    }
961
962    /// The span of the [`Element`] the error occurred in.
963    pub fn span(&self) -> Span {
964        self.0.span
965    }
966
967    pub fn token(&self) -> Option<&Token> {
968        self.0.token.as_ref()
969    }
970
971    /// Break the Error into its constituent parts.
972    pub fn into_parts(self) -> (ErrorKind, Path, Span) {
973        let ErrorImpl {
974            kind,
975            loc: _,
976            path,
977            span,
978            token: _,
979        } = *self.0;
980        (kind, path, span)
981    }
982
983    /// Convert the Error into a more comprehensive report using the source JSON to provide
984    /// human readable context.
985    pub fn into_report(self, json: &str) -> ErrorReport<'_> {
986        ErrorReport::from_error(self, json)
987    }
988}
989
990/// A more comprehensive report on the [`Error`] using the source JSON `&str` to provide
991/// human readable context.
992#[derive(Debug)]
993pub struct ErrorReport<'buf> {
994    /// The [`Error`] that occurred.
995    error: Error,
996
997    /// The slice of JSON as defined by the `Error::span`.
998    json_context: &'buf str,
999
1000    /// The slice of JSON as defined by the `Error::span` and expanded out to the
1001    /// start and end of the line.
1002    expanded_json_context: &'buf str,
1003
1004    /// The line and col indices of the start and end of the span.
1005    span_bounds: SpanBounds,
1006}
1007
1008impl<'buf> ErrorReport<'buf> {
1009    /// Create the `ErrorReport` from the `Error` and source `&str`.
1010    fn from_error(error: Error, json: &'buf str) -> Self {
1011        let span = error.span();
1012        debug!(?error, ?span, json, "from_error");
1013        let json_context = &json.get(span.start..span.end).unwrap_or(json);
1014
1015        let start = {
1016            let s = &json.get(0..span.start).unwrap_or_default();
1017            line_col(s)
1018        };
1019        let end = {
1020            let relative_end = line_col(json_context);
1021            let line = start.line.saturating_add(relative_end.line);
1022
1023            if start.line == line {
1024                LineCol {
1025                    line,
1026                    col: start.col.saturating_add(relative_end.col),
1027                }
1028            } else {
1029                LineCol {
1030                    line,
1031                    col: relative_end.col,
1032                }
1033            }
1034        };
1035        let (prev, next) = find_expanded_newlines(json, span.start);
1036        let expanded_json_context = &json.get(prev..next).unwrap_or(json_context);
1037
1038        let span_bounds = SpanBounds { start, end };
1039
1040        Self {
1041            error,
1042            json_context,
1043            expanded_json_context,
1044            span_bounds,
1045        }
1046    }
1047
1048    /// Return the slice of JSON as defined by the `Error::span`.
1049    pub fn json_context(&self) -> &'buf str {
1050        self.json_context
1051    }
1052
1053    /// Return the slice of JSON as defined by the `Error::span` and expanded out to the
1054    /// start and end of the line.
1055    pub fn expand_json_context(&self) -> &'buf str {
1056        self.expanded_json_context
1057    }
1058
1059    /// Return the line and col number of each end of the span.
1060    pub fn span_bounds(&self) -> &SpanBounds {
1061        &self.span_bounds
1062    }
1063
1064    /// Discard the `Report` and take ownership of the `Error`.
1065    pub fn into_error(self) -> Error {
1066        self.error
1067    }
1068}
1069
1070fn find_expanded_newlines(json: &str, byte_index: usize) -> (usize, usize) {
1071    let pre = json.get(..byte_index).unwrap_or(json);
1072    let post = json.get(byte_index..).unwrap_or(json);
1073
1074    let mut bytes = pre.as_bytes().iter().rev();
1075    let prev = pre
1076        .len()
1077        .saturating_sub(bytes.position(|b| *b == b'\n').unwrap_or_default());
1078
1079    let mut bytes = post.as_bytes().iter();
1080    let next = bytes
1081        .position(|b| *b == b'\n')
1082        .map(|idx| idx.saturating_add(byte_index))
1083        .unwrap_or(prev.saturating_add(post.len()));
1084
1085    (prev, next)
1086}
1087
1088/// The line and col indices of the start and end of the span.
1089#[derive(Clone, Debug)]
1090pub struct SpanBounds {
1091    /// The start of the `Span` expressed as line and column index.
1092    pub start: LineCol,
1093
1094    /// The end of the `Span` expressed as line and column index.
1095    pub end: LineCol,
1096}
1097
1098/// A file location expressed as line and column.
1099#[derive(Clone, Debug)]
1100pub struct LineCol {
1101    /// The line index is 0 based.
1102    pub line: u32,
1103
1104    /// The col index is 0 based.
1105    pub col: u32,
1106}
1107
1108impl From<(u32, u32)> for LineCol {
1109    fn from(value: (u32, u32)) -> Self {
1110        Self {
1111            line: value.0,
1112            col: value.1,
1113        }
1114    }
1115}
1116
1117impl From<LineCol> for (u32, u32) {
1118    fn from(value: LineCol) -> Self {
1119        (value.line, value.col)
1120    }
1121}
1122
1123impl PartialEq<(u32, u32)> for LineCol {
1124    fn eq(&self, other: &(u32, u32)) -> bool {
1125        self.line == other.0 && self.col == other.1
1126    }
1127}
1128
1129impl fmt::Display for LineCol {
1130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1131        write!(f, "{}:{}", self.line, self.col)
1132    }
1133}
1134
1135/// Return the line and column indices of the end of the slice.
1136///
1137/// The line and column indices are zero based.
1138pub fn line_col(s: &str) -> LineCol {
1139    let mut chars = s.chars().rev();
1140    let mut line = 0_u32;
1141    let mut col = 0_u32;
1142
1143    // The col only needs to be calculated on the final line so we iterate from the last char
1144    // back to the start of the line and then only continue to count the lines after that.
1145    //
1146    // This is less work than continuously counting chars from the front of the slice.
1147    for c in chars.by_ref() {
1148        // If the `&str` is multiline, we count the line and stop accumulating the col count too.
1149        if c == '\n' {
1150            let Some(n) = line.checked_add(1) else {
1151                break;
1152            };
1153            line = n;
1154            break;
1155        }
1156        let Some(n) = col.checked_add(1) else {
1157            break;
1158        };
1159        col = n;
1160    }
1161
1162    // The col is now known, continue to the start of the str counting newlines as we go.
1163    for c in chars {
1164        if c == '\n' {
1165            let Some(n) = line.checked_add(1) else {
1166                break;
1167            };
1168            line = n;
1169        }
1170    }
1171
1172    LineCol { line, col }
1173}
1174
1175/// An error that has yet to be resolved with a [`Span`].
1176#[derive(Debug)]
1177pub struct PartialError {
1178    /// The location the [`PartialError`] happened in the source code.
1179    kind: ErrorKind,
1180
1181    /// The location the [`PartialError`] happened in the source code.
1182    loc: &'static std::panic::Location<'static>,
1183
1184    /// The token being parsed at the time of the [`PartialError`].
1185    token: Option<Token>,
1186}
1187
1188/// Convert a [`PartialError`] into an [`Error`] by providing a [`PartialElement`].
1189trait PartialIntoError<T> {
1190    /// Convert a [`PartialError`] into an [`Error`] with a path based on the given [`PartialElement`].
1191    fn with_head(self, head: &PartialElement<'_>) -> Result<T, Error>;
1192
1193    /// Converts a [`PartialError`] into an [`Error`] with a root path.
1194    ///
1195    /// This can be used If the path is unknown or the [`Error`] occurred at the root.
1196    fn with_root_path(self) -> Result<T, Error>;
1197}
1198
1199impl<T> PartialIntoError<T> for Result<T, PartialError> {
1200    fn with_head(self, head: &PartialElement<'_>) -> Result<T, Error> {
1201        match self {
1202            Ok(v) => Ok(v),
1203            Err(err) => Err(err.with_head(head)),
1204        }
1205    }
1206
1207    fn with_root_path(self) -> Result<T, Error> {
1208        match self {
1209            Ok(v) => Ok(v),
1210            Err(err) => Err(err.with_root_path()),
1211        }
1212    }
1213}
1214
1215impl PartialError {
1216    /// Convert a [`PartialError`] into an [`Error`] with a path based on the given [`PartialElement`].
1217    fn with_head(self, parent: &PartialElement<'_>) -> Error {
1218        let Self { loc, kind, token } = self;
1219        let span_end = token.map(|t| t.span.end).unwrap_or_default();
1220
1221        let (path, span) = if let Some(elem) = parent.elements.last() {
1222            (
1223                Path::from_node(Arc::clone(&elem.path_node)),
1224                Span {
1225                    start: elem.span.start,
1226                    end: span_end,
1227                },
1228            )
1229        } else {
1230            (
1231                Path::from_node(Arc::clone(&parent.path)),
1232                Span {
1233                    start: parent.span_start,
1234                    end: span_end,
1235                },
1236            )
1237        };
1238
1239        ErrorImpl {
1240            kind,
1241            loc,
1242            path,
1243            span,
1244            token,
1245        }
1246        .into()
1247    }
1248
1249    /// Converts a `PartialError` into an `Error` with a root path.
1250    ///
1251    /// This can be used If the path is unknown or the `Error` occurred at the root.
1252    pub fn with_root_path(self) -> Error {
1253        let Self { loc, kind, token } = self;
1254        let (span_start, span_end) = match (&kind, token) {
1255            (ErrorKind::UnexpectedToken, Some(t)) => (t.span.start, t.span.end),
1256            (_, Some(t)) => (0, t.span.end),
1257            (_, None) => (0, 0),
1258        };
1259        ErrorImpl {
1260            loc,
1261            kind,
1262            path: Path::root(),
1263            span: Span {
1264                start: span_start,
1265                end: span_end,
1266            },
1267            token,
1268        }
1269        .into()
1270    }
1271}
1272
1273/// The kind of Errors that can occur while parsing JSON.
1274#[derive(Debug)]
1275pub enum ErrorKind {
1276    /// An internal programming error.
1277    Internal(Box<dyn std::error::Error + Send + Sync + 'static>),
1278
1279    /// The `Lexer` had no more tokens when more were expected.
1280    UnexpectedEOF,
1281
1282    /// An unexpected token was emitted by the `Lexer`.
1283    UnexpectedToken,
1284}
1285
1286impl ErrorKind {
1287    #[track_caller]
1288    fn into_partial_error(self, token: Option<Token>) -> PartialError {
1289        PartialError {
1290            kind: self,
1291            loc: std::panic::Location::caller(),
1292            token,
1293        }
1294    }
1295
1296    #[track_caller]
1297    pub fn into_partial_error_without_token(self) -> PartialError {
1298        PartialError {
1299            kind: self,
1300            loc: std::panic::Location::caller(),
1301            token: None,
1302        }
1303    }
1304}
1305
1306impl std::error::Error for Error {}
1307
1308impl fmt::Display for Error {
1309    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1310        let ErrorImpl {
1311            kind,
1312            loc,
1313            path,
1314            span: _,
1315            token,
1316        } = &*self.0;
1317
1318        write!(
1319            f,
1320            "Error: code location: {loc}; while parsing element at `{path}`"
1321        )?;
1322
1323        if let Some(token) = token {
1324            write!(f, " token: `{}`", token.kind)?;
1325        }
1326
1327        match kind {
1328            ErrorKind::Internal(err) => write!(f, "Internal: {err}"),
1329            ErrorKind::UnexpectedEOF => f.write_str("Unexpected EOF"),
1330            ErrorKind::UnexpectedToken => write!(f, "unexpected token"),
1331        }
1332    }
1333}
1334
1335/// A programming Error resulting from faulty logic.
1336///
1337/// This should not be exposed on the public API.
1338#[derive(Debug)]
1339enum InternalError {
1340    /// Slicing into the JSON buf failed.
1341    ///
1342    /// This should not happen during parsing, as the parsing and `Span` calculations are all
1343    /// contained within the same callstack of functions.
1344    ///
1345    /// This can only happen if there's a mistake in the `Span` offset/range calculations.
1346    BufferSlice(Span),
1347
1348    /// The type of `Buffer` is invalid.
1349    ///
1350    /// The `json_tools::Lexer::next` is called in a few places and the `json_tools::Token` it
1351    /// emits is converted into a local `Token` with only a `Span` based buffer to avoid checking
1352    /// the buffer type each time it's used.
1353    ///
1354    /// The lexer is configured to only use a `Span` based buffer so the only way this Error can
1355    /// occur is if the code is changed so that the lexer uses a `String` based buffer.
1356    BufferType,
1357
1358    /// The `json_tools::Span` uses `u64` for the `start` and `end` indices which would involve
1359    /// conversion to `usize` each time they are used. To avoid this the `json_tools::Span` is
1360    /// converted to the locally defined `Span` that uses `usize` based fields.
1361    ///
1362    /// This conversion can fail if the binary is built for architectures other than `64` bit pointer width.
1363    FromInt(TryFromIntError),
1364
1365    /// A String was parsed without surrounding double quotes.
1366    ///
1367    /// This is only possible if the `json_tools` crate changes the implementation details of
1368    /// how they parse JSON strings.
1369    StringWithoutQuotes,
1370
1371    /// A `RawStr` was made using a token that is not a `String`.
1372    ///
1373    /// `RawStr`s are only creatable from inside the crate so the only way this can occur is
1374    /// through a programming error.
1375    RawStringFromInvalidToken,
1376}
1377
1378impl InternalError {
1379    #[track_caller]
1380    fn into_partial_error(self, token: Option<Token>) -> PartialError {
1381        ErrorKind::Internal(Box::new(self)).into_partial_error(token)
1382    }
1383}
1384
1385impl std::error::Error for InternalError {}
1386
1387/// The `json_tools::Span` uses `u64` for the `start` and `end` indices which would involve
1388/// conversion to `usize` each time they are used. To avoid this the `json_tools::Span` is
1389/// converted to the locally defined `Span` that uses `usize` based fields.
1390///
1391/// This conversion can fail if the binary is built for architectures other than `64` bit pointer width.
1392impl From<TryFromIntError> for InternalError {
1393    fn from(err: TryFromIntError) -> Self {
1394        InternalError::FromInt(err)
1395    }
1396}
1397
1398impl From<InternalError> for Error {
1399    #[track_caller]
1400    fn from(err: InternalError) -> Self {
1401        ErrorImpl {
1402            kind: ErrorKind::Internal(Box::new(err)),
1403            loc: std::panic::Location::caller(),
1404            path: Path::root(),
1405            span: Span { start: 0, end: 0 },
1406            token: None,
1407        }
1408        .into()
1409    }
1410}
1411
1412impl fmt::Display for InternalError {
1413    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1414        match self {
1415            InternalError::BufferSlice(span) => {
1416                write!(f, "Slice into buffer failed; span: {span:?}")
1417            }
1418            InternalError::BufferType => write!(f, "The tokens buffer is not a `Span`"),
1419            InternalError::FromInt(err) => write!(f, "{err}"),
1420            InternalError::StringWithoutQuotes => {
1421                write!(f, "A String was parsed without surrounding double quotes.")
1422            }
1423
1424            InternalError::RawStringFromInvalidToken => {
1425                write!(
1426                    f,
1427                    "A `RawString` was created using a `Token` that's not a `String`"
1428                )
1429            }
1430        }
1431    }
1432}
1433
1434trait InternalErrorIntoPartial<T> {
1435    #[track_caller]
1436    fn into_partial_error<F>(self, f: F) -> Result<T, PartialError>
1437    where
1438        F: FnOnce() -> Token;
1439}
1440
1441impl<T> InternalErrorIntoPartial<T> for Result<T, InternalError> {
1442    fn into_partial_error<F>(self, f: F) -> Result<T, PartialError>
1443    where
1444        F: FnOnce() -> Token,
1445    {
1446        match self {
1447            Ok(v) => Ok(v),
1448            Err(err) => {
1449                let token = f();
1450                Err(err.into_partial_error(Some(token)))
1451            }
1452        }
1453    }
1454}
1455
1456/// Create the `Span` of an `Element` given the start and the closing token.
1457fn element_span(token_end: &Token, start: usize) -> Span {
1458    Span {
1459        start,
1460        end: token_end.span.end,
1461    }
1462}
1463
1464/// Return the content of the `Token` as a `&str`.
1465///
1466/// This in only useful for `Token`'s that contain variable data, such as `String`, `Number` etc.
1467#[track_caller]
1468fn token_str<'buf>(json: &'buf str, token: &Token) -> Result<&'buf str, PartialError> {
1469    let start = token.span.start;
1470    let end = token.span.end;
1471    let s = &json
1472        .get(start..end)
1473        .ok_or(InternalError::BufferSlice(Span { start, end }))
1474        .into_partial_error(|| *token)?;
1475    Ok(s)
1476}
1477
1478/// A `&str` with surrounding quotes removed and it hasn't been analyzed for escapes codes.
1479#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Default)]
1480pub struct RawStr<'buf> {
1481    /// An unescaped `&str` with surrounding quotes removed.
1482    source: &'buf str,
1483
1484    /// The `String` token that produced the source `&str`.
1485    span: Span,
1486}
1487
1488/// Impl `Borrow` so `RawStr` plays well with hashed collections.
1489impl Borrow<str> for RawStr<'_> {
1490    fn borrow(&self) -> &str {
1491        self.source
1492    }
1493}
1494
1495/// Impl `Borrow` so `RawStr` plays well with hashed collections.
1496impl Borrow<str> for &RawStr<'_> {
1497    fn borrow(&self) -> &str {
1498        self.source
1499    }
1500}
1501
1502impl<'buf> RawStr<'buf> {
1503    pub(super) fn from_str(source: &'buf str, span: Span) -> Self {
1504        Self { source, span }
1505    }
1506
1507    /// Create new `RawStr` from a string with surrounding quotes.
1508    #[track_caller]
1509    pub(super) fn from_quoted_str(
1510        s: &'buf str,
1511        token: Token,
1512    ) -> Result<RawStr<'buf>, PartialError> {
1513        const QUOTE: char = '"';
1514
1515        if token.kind != TokenType::String {
1516            return Err(InternalError::RawStringFromInvalidToken.into_partial_error(Some(token)));
1517        }
1518
1519        // remove double quotes
1520        let (_, s) = s
1521            .split_once(QUOTE)
1522            .ok_or(InternalError::StringWithoutQuotes)
1523            .into_partial_error(|| token)?;
1524
1525        let (source, _) = s
1526            .rsplit_once(QUOTE)
1527            .ok_or(InternalError::StringWithoutQuotes)
1528            .into_partial_error(|| token)?;
1529
1530        Ok(Self {
1531            source,
1532            span: token.span,
1533        })
1534    }
1535
1536    /// Return the raw unescaped `&str`.
1537    pub(crate) fn as_raw(&self) -> &'buf str {
1538        self.source
1539    }
1540
1541    /// Return the `&str` with all escapes decoded.
1542    pub(crate) fn decode_escapes(
1543        &self,
1544        elem: &Element<'buf>,
1545    ) -> Caveat<Cow<'_, str>, decode::Warning> {
1546        unescape_str(self.source, elem)
1547    }
1548
1549    /// Return a `&str` marked as either having escapes or not.
1550    pub(crate) fn has_escapes(
1551        &self,
1552        elem: &Element<'buf>,
1553    ) -> Caveat<decode::PendingStr<'buf>, decode::Warning> {
1554        decode::analyze(self.source, elem)
1555    }
1556
1557    /// Return the [`Span`] of the [`Token`] that generated this string.
1558    pub fn span(&self) -> Span {
1559        self.span
1560    }
1561}
1562
1563impl fmt::Display for RawStr<'_> {
1564    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1565        fmt::Display::fmt(self.source, f)
1566    }
1567}
1568
1569#[track_caller]
1570fn token_str_as_string(json: &str, token: Token) -> Result<RawStr<'_>, PartialError> {
1571    let s = token_str(json, &token)?;
1572    let raw = RawStr::from_quoted_str(s, token)?;
1573    Ok(raw)
1574}