@@ -6,6 +6,7 @@ use super::ast::*;
66use super :: common:: Range ;
77use super :: errors:: * ;
88use super :: scanner:: Scanner ;
9+ use super :: scanner:: ScannerOptions ;
910use super :: tokens:: Token ;
1011use super :: tokens:: TokenAndRange ;
1112
@@ -14,11 +15,25 @@ use super::tokens::TokenAndRange;
1415/// next token start or end of the file.
1516pub type CommentMap < ' a > = HashMap < usize , Rc < Vec < Comment < ' a > > > > ;
1617
18+ /// Strategy for handling comments during parsing.
19+ ///
20+ /// This enum determines how comments in the JSON/JSONC input are collected
21+ /// and represented in the resulting abstract syntax tree (AST).
1722#[ derive( Default , Debug , PartialEq , Clone ) ]
1823pub enum CommentCollectionStrategy {
24+ /// Comments are not collected and are effectively ignored during parsing.
1925 #[ default]
2026 Off ,
27+ /// Comments are collected and stored separately from the main AST structure.
28+ ///
29+ /// When this strategy is used, comments are placed in a [`CommentMap`] where
30+ /// the key is the previous token end or start of file, or the next token start
31+ /// or end of file.
2132 Separate ,
33+ /// Comments are collected and treated as tokens within the AST.
34+ ///
35+ /// When this strategy is used, comments appear alongside other tokens in the
36+ /// token stream when `tokens: true` is set in [`CollectOptions`].
2237 AsTokens ,
2338}
2439
@@ -40,6 +55,12 @@ pub struct ParseOptions {
4055 pub allow_loose_object_property_names : bool ,
4156 /// Allow trailing commas on object literal and array literal values (defaults to `true`).
4257 pub allow_trailing_commas : bool ,
58+ /// Allow single-quoted strings (defaults to `true`).
59+ pub allow_single_quoted_strings : bool ,
60+ /// Allow hexadecimal numbers like 0xFF (defaults to `true`).
61+ pub allow_hexadecimal_numbers : bool ,
62+ /// Allow unary plus sign on numbers like +42 (defaults to `true`).
63+ pub allow_unary_plus_numbers : bool ,
4364}
4465
4566impl Default for ParseOptions {
@@ -48,6 +69,9 @@ impl Default for ParseOptions {
4869 allow_comments : true ,
4970 allow_loose_object_property_names : true ,
5071 allow_trailing_commas : true ,
72+ allow_single_quoted_strings : true ,
73+ allow_hexadecimal_numbers : true ,
74+ allow_unary_plus_numbers : true ,
5175 }
5276 }
5377}
@@ -218,7 +242,14 @@ pub fn parse_to_ast<'a>(
218242 parse_options : & ParseOptions ,
219243) -> Result < ParseResult < ' a > , ParseError > {
220244 let mut context = Context {
221- scanner : Scanner :: new ( text) ,
245+ scanner : Scanner :: new (
246+ text,
247+ & ScannerOptions {
248+ allow_single_quoted_strings : parse_options. allow_single_quoted_strings ,
249+ allow_hexadecimal_numbers : parse_options. allow_hexadecimal_numbers ,
250+ allow_unary_plus_numbers : parse_options. allow_unary_plus_numbers ,
251+ } ,
252+ ) ,
222253 comments : match collect_options. comments {
223254 CommentCollectionStrategy :: Separate => Some ( Default :: default ( ) ) ,
224255 CommentCollectionStrategy :: Off | CommentCollectionStrategy :: AsTokens => None ,
@@ -503,6 +534,30 @@ mod tests {
503534 ) ;
504535 }
505536
537+ #[ test]
538+ fn strict_should_error_single_quoted_string ( ) {
539+ assert_has_strict_error (
540+ r#"{ "key": 'value' }"# ,
541+ "Single-quoted strings are not allowed on line 1 column 10" ,
542+ ) ;
543+ }
544+
545+ #[ test]
546+ fn strict_should_error_hexadecimal_number ( ) {
547+ assert_has_strict_error (
548+ r#"{ "key": 0xFF }"# ,
549+ "Hexadecimal numbers are not allowed on line 1 column 10" ,
550+ ) ;
551+ }
552+
553+ #[ test]
554+ fn strict_should_error_unary_plus_number ( ) {
555+ assert_has_strict_error (
556+ r#"{ "key": +42 }"# ,
557+ "Unary plus on numbers is not allowed on line 1 column 10" ,
558+ ) ;
559+ }
560+
506561 #[ track_caller]
507562 fn assert_has_strict_error ( text : & str , message : & str ) {
508563 let result = parse_to_ast (
@@ -512,6 +567,9 @@ mod tests {
512567 allow_comments : false ,
513568 allow_loose_object_property_names : false ,
514569 allow_trailing_commas : false ,
570+ allow_single_quoted_strings : false ,
571+ allow_hexadecimal_numbers : false ,
572+ allow_unary_plus_numbers : false ,
515573 } ,
516574 ) ;
517575 match result {
0 commit comments