1
1
use itertools:: Itertools ;
2
- use miette:: { Diagnostic , SourceCode } ;
2
+ use miette:: Diagnostic ;
3
3
4
4
/// Errors
5
5
#[ derive( thiserror:: Error , Diagnostic , Debug ) ]
@@ -9,7 +9,7 @@ pub enum Error {
9
9
Jsonnet ( #[ from] JsonnetError ) ,
10
10
#[ error( transparent) ]
11
11
#[ diagnostic( transparent) ]
12
- Json ( #[ from] JsonError ) ,
12
+ Json ( #[ from] Box < JsonError > ) ,
13
13
#[ error( transparent) ]
14
14
#[ diagnostic( transparent) ]
15
15
SqlParse ( #[ from] SQLParseError ) ,
@@ -54,16 +54,43 @@ pub struct JsonError {
54
54
pub reason : String ,
55
55
#[ source_code]
56
56
pub src : miette:: NamedSource < String > ,
57
+ #[ help]
58
+ help : String ,
57
59
#[ label]
58
- pub span : miette:: SourceOffset ,
60
+ span : miette:: SourceSpan ,
59
61
}
60
62
impl JsonError {
61
- pub fn from ( json : & str , e : serde_path_to_error:: Error < serde_json:: Error > ) -> Self {
62
- let orig = e. inner ( ) ;
63
+ pub fn from ( json : & str , e : serde_json:: Error ) -> Self {
63
64
Self {
64
- reason : format ! ( "{}; path `{}`" , orig , e . path ( ) ) ,
65
- span : miette:: SourceOffset :: from_location ( json, orig . line ( ) , orig . column ( ) ) ,
65
+ reason : e . to_string ( ) ,
66
+ span : miette:: SourceOffset :: from_location ( json, e . line ( ) , e . column ( ) ) . into ( ) ,
66
67
src : miette:: NamedSource :: new ( "source.json" , json. into ( ) ) ,
68
+ help : "Jsonnet generated invalid JSON" . into ( ) ,
69
+ }
70
+ }
71
+ pub fn from_path (
72
+ value : serde_json:: Value ,
73
+ e : serde_path_to_error:: Error < serde_json:: Error > ,
74
+ ) -> Self {
75
+ let orig = e. inner ( ) ;
76
+
77
+ let pointer = std:: iter:: once ( "" . to_string ( ) )
78
+ . chain ( e. path ( ) . into_iter ( ) . map ( |segment| match segment {
79
+ serde_path_to_error:: Segment :: Seq { index } => index. to_string ( ) ,
80
+ serde_path_to_error:: Segment :: Map { key } => key. into ( ) ,
81
+ serde_path_to_error:: Segment :: Enum { variant } => variant. into ( ) ,
82
+ serde_path_to_error:: Segment :: Unknown => String :: default ( ) ,
83
+ } ) )
84
+ . join ( "/" ) ;
85
+ let element = value
86
+ . pointer ( & pointer)
87
+ . map ( |v| serde_json:: to_string_pretty ( v) . unwrap ( ) )
88
+ . unwrap_or_default ( ) ;
89
+ Self {
90
+ reason : orig. to_string ( ) ,
91
+ span : miette:: SourceSpan :: new ( 0 . into ( ) , 0 ) ,
92
+ src : miette:: NamedSource :: new ( "source.json" , element) ,
93
+ help : format ! ( "at path {}" , e. path( ) ) ,
67
94
}
68
95
}
69
96
}
@@ -121,24 +148,8 @@ impl From<Error> for FormattedError {
121
148
}
122
149
}
123
150
Error :: Json ( json_source) => Self {
124
- message : source. to_string ( ) ,
125
- code : json_source
126
- . src
127
- . read_span ( & miette:: SourceSpan :: new ( json_source. span , 1 ) , 2 , 2 )
128
- . ok ( )
129
- . and_then ( |contents| String :: from_utf8 ( contents. data ( ) . into ( ) ) . ok ( ) )
130
- . map ( |code| {
131
- let indent = code
132
- . lines ( )
133
- . filter ( |l| !l. is_empty ( ) )
134
- . map ( |l| l. chars ( ) . take_while ( |c| c. is_whitespace ( ) ) . count ( ) )
135
- . min ( )
136
- . unwrap_or_default ( ) ;
137
- let indent: String = " " . repeat ( indent) ;
138
- code. lines ( )
139
- . map ( |l| l. strip_prefix ( & indent) . unwrap_or ( l) )
140
- . join ( "\n " )
141
- } ) ,
151
+ message : format ! ( "{} {}" , source, json_source. help) ,
152
+ code : Some ( json_source. src . inner ( ) . clone ( ) ) ,
142
153
location : None ,
143
154
} ,
144
155
0 commit comments