@@ -16,8 +16,8 @@ use rspack_core::{
16
16
diagnostics:: ModuleParseError ,
17
17
rspack_sources:: { BoxSource , RawStringSource , Source , SourceExt } ,
18
18
BuildMetaDefaultObject , BuildMetaExportsType , ChunkGraph , CompilerOptions , ExportsInfo ,
19
- GenerateContext , Module , ModuleGraph , ParserAndGenerator , Plugin , RuntimeGlobals , RuntimeSpec ,
20
- SourceType , UsageState , NAMESPACE_OBJECT_EXPORT ,
19
+ GenerateContext , Module , ModuleGraph , ParseOption , ParserAndGenerator , Plugin , RuntimeGlobals ,
20
+ RuntimeSpec , SourceType , UsageState , NAMESPACE_OBJECT_EXPORT ,
21
21
} ;
22
22
use rspack_error:: {
23
23
miette:: diagnostic, DiagnosticExt , DiagnosticKind , IntoTWithDiagnosticArray , Result ,
@@ -34,6 +34,7 @@ mod utils;
34
34
#[ derive( Debug ) ]
35
35
struct JsonParserAndGenerator {
36
36
pub exports_depth : u32 ,
37
+ pub parse : ParseOption ,
37
38
}
38
39
39
40
#[ cacheable_dyn]
@@ -55,54 +56,68 @@ impl ParserAndGenerator for JsonParserAndGenerator {
55
56
build_info,
56
57
build_meta,
57
58
loaders,
59
+ module_parser_options,
58
60
..
59
61
} = parse_context;
60
62
let source = box_source. source ( ) ;
61
63
let strip_bom_source = source. strip_prefix ( '\u{feff}' ) ;
62
64
let need_strip_bom = strip_bom_source. is_some ( ) ;
65
+ let strip_bom_source = strip_bom_source. unwrap_or ( & source) ;
63
66
64
- let parse_result = json:: parse ( strip_bom_source. unwrap_or ( & source) ) . map_err ( |e| {
65
- match e {
66
- UnexpectedCharacter { ch, line, column } => {
67
- let rope = ropey:: Rope :: from_str ( & source) ;
68
- let line_offset = rope. try_line_to_byte ( line - 1 ) . expect ( "TODO:" ) ;
69
- let start_offset = source[ line_offset..]
70
- . chars ( )
71
- . take ( column)
72
- . fold ( line_offset, |acc, cur| acc + cur. len_utf8 ( ) ) ;
73
- let start_offset = if need_strip_bom {
74
- start_offset + 1
75
- } else {
76
- start_offset
77
- } ;
78
- TraceableError :: from_file (
79
- source. into_owned ( ) ,
80
- // one character offset
81
- start_offset,
82
- start_offset + 1 ,
83
- "Json parsing error" . to_string ( ) ,
84
- format ! ( "Unexpected character {ch}" ) ,
85
- )
86
- . with_kind ( DiagnosticKind :: Json )
87
- . boxed ( )
67
+ // If there is a custom parse, execute it to obtain the returned string.
68
+ let parse_result_str = module_parser_options
69
+ . and_then ( |p| p. get_json ( ) )
70
+ . and_then ( |p| match & p. parse {
71
+ ParseOption :: Func ( p) => {
72
+ let parse_result = p ( strip_bom_source. to_string ( ) ) ;
73
+ parse_result. ok ( )
88
74
}
89
- ExceededDepthLimit | WrongType ( _) | FailedUtf8Parsing => diagnostic ! ( "{e}" ) . boxed ( ) ,
90
- UnexpectedEndOfJson => {
91
- // End offset of json file
92
- let length = source. len ( ) ;
93
- let offset = if length > 0 { length - 1 } else { length } ;
94
- TraceableError :: from_file (
95
- source. into_owned ( ) ,
96
- offset,
97
- offset,
98
- "Json parsing error" . to_string ( ) ,
99
- format ! ( "{e}" ) ,
100
- )
101
- . with_kind ( DiagnosticKind :: Json )
102
- . boxed ( )
75
+ _ => None ,
76
+ } ) ;
77
+
78
+ let parse_result = json:: parse ( parse_result_str. as_deref ( ) . unwrap_or ( strip_bom_source) )
79
+ . map_err ( |e| {
80
+ match e {
81
+ UnexpectedCharacter { ch, line, column } => {
82
+ let rope = ropey:: Rope :: from_str ( & source) ;
83
+ let line_offset = rope. try_line_to_byte ( line - 1 ) . expect ( "TODO:" ) ;
84
+ let start_offset = source[ line_offset..]
85
+ . chars ( )
86
+ . take ( column)
87
+ . fold ( line_offset, |acc, cur| acc + cur. len_utf8 ( ) ) ;
88
+ let start_offset = if need_strip_bom {
89
+ start_offset + 1
90
+ } else {
91
+ start_offset
92
+ } ;
93
+ TraceableError :: from_file (
94
+ source. into_owned ( ) ,
95
+ // one character offset
96
+ start_offset,
97
+ start_offset + 1 ,
98
+ "Json parsing error" . to_string ( ) ,
99
+ format ! ( "Unexpected character {ch}" ) ,
100
+ )
101
+ . with_kind ( DiagnosticKind :: Json )
102
+ . boxed ( )
103
+ }
104
+ ExceededDepthLimit | WrongType ( _) | FailedUtf8Parsing => diagnostic ! ( "{e}" ) . boxed ( ) ,
105
+ UnexpectedEndOfJson => {
106
+ // End offset of json file
107
+ let length = source. len ( ) ;
108
+ let offset = if length > 0 { length - 1 } else { length } ;
109
+ TraceableError :: from_file (
110
+ source. into_owned ( ) ,
111
+ offset,
112
+ offset,
113
+ "Json parsing error" . to_string ( ) ,
114
+ format ! ( "{e}" ) ,
115
+ )
116
+ . with_kind ( DiagnosticKind :: Json )
117
+ . boxed ( )
118
+ }
103
119
}
104
- }
105
- } ) ;
120
+ } ) ;
106
121
107
122
let ( diagnostics, data) = match parse_result {
108
123
Ok ( data) => ( vec ! [ ] , Some ( data) ) ,
@@ -236,6 +251,7 @@ impl Plugin for JsonPlugin {
236
251
237
252
Box :: new ( JsonParserAndGenerator {
238
253
exports_depth : p. exports_depth . expect ( "should have exports_depth" ) ,
254
+ parse : p. parse . clone ( ) ,
239
255
} )
240
256
} ) ,
241
257
) ;
0 commit comments