@@ -7,13 +7,24 @@ use crate::errors::{JsonError, LinePosition};
77#[ derive( Debug , Clone ) ]
88pub struct JsonParseError {
99 json_error : JsonError ,
10+ path : Vec < PathItem > ,
1011 position : LinePosition ,
1112}
1213
1314impl JsonParseError {
14- pub fn new_err ( py : Python , json_error : JsonError , json_data : & [ u8 ] ) -> PyErr {
15- let position = json_error. get_position ( json_data) ;
16- let slf = Self { json_error, position } ;
15+ pub ( crate ) fn new_err ( py : Python , py_json_error : PythonJsonError , json_data : & [ u8 ] ) -> PyErr {
16+ let position = py_json_error. error . get_position ( json_data) ;
17+ let slf = Self {
18+ json_error : py_json_error. error ,
19+ path : match py_json_error. path {
20+ Some ( mut v) => {
21+ v. reverse ( ) ;
22+ v
23+ }
24+ None => vec ! [ ] ,
25+ } ,
26+ position,
27+ } ;
1728 match Py :: new ( py, slf) {
1829 Ok ( err) => PyErr :: from_value_bound ( err. into_bound ( py) . into_any ( ) ) ,
1930 Err ( err) => err,
@@ -31,6 +42,10 @@ impl JsonParseError {
3142 self . json_error . error_type . to_string ( )
3243 }
3344
45+ fn path ( & self , py : Python ) -> PyObject {
46+ self . path . to_object ( py)
47+ }
48+
3449 fn index ( & self ) -> usize {
3550 self . json_error . index
3651 }
@@ -51,3 +66,136 @@ impl JsonParseError {
5166 format ! ( "JsonParseError({:?})" , self . __str__( ) )
5267 }
5368}
69+
70+ pub ( crate ) trait MaybeBuildArrayPath : MaybeBuildPath {
71+ fn incr_index ( & mut self ) ;
72+ fn set_index_path ( & self , err : PythonJsonError ) -> PythonJsonError ;
73+ }
74+
75+ pub ( crate ) trait MaybeBuildObjectPath : MaybeBuildPath {
76+ fn set_key ( & mut self , key : & str ) ;
77+
78+ fn set_key_path ( & self , err : PythonJsonError ) -> PythonJsonError ;
79+ }
80+
81+ pub ( crate ) trait MaybeBuildPath {
82+ fn new_array ( ) -> impl MaybeBuildArrayPath ;
83+ fn new_object ( ) -> impl MaybeBuildObjectPath ;
84+ }
85+
86+ pub ( crate ) struct NoopBuildPath ;
87+
88+ impl MaybeBuildPath for NoopBuildPath {
89+ fn new_array ( ) -> NoopBuildPath {
90+ NoopBuildPath
91+ }
92+
93+ fn new_object ( ) -> NoopBuildPath {
94+ NoopBuildPath
95+ }
96+ }
97+
98+ impl MaybeBuildArrayPath for NoopBuildPath {
99+ fn incr_index ( & mut self ) { }
100+
101+ fn set_index_path ( & self , err : PythonJsonError ) -> PythonJsonError {
102+ err
103+ }
104+ }
105+
106+ impl MaybeBuildObjectPath for NoopBuildPath {
107+ fn set_key ( & mut self , _: & str ) { }
108+
109+ fn set_key_path ( & self , err : PythonJsonError ) -> PythonJsonError {
110+ err
111+ }
112+ }
113+
114+ #[ derive( Default ) ]
115+ pub ( crate ) struct ActiveBuildPath {
116+ index : usize ,
117+ }
118+
119+ impl MaybeBuildPath for ActiveBuildPath {
120+ fn new_array ( ) -> ActiveBuildPath {
121+ ActiveBuildPath :: default ( )
122+ }
123+
124+ fn new_object ( ) -> ActiveObjectBuildPath {
125+ ActiveObjectBuildPath :: default ( )
126+ }
127+ }
128+
129+ impl MaybeBuildArrayPath for ActiveBuildPath {
130+ fn incr_index ( & mut self ) {
131+ self . index += 1 ;
132+ }
133+
134+ fn set_index_path ( & self , mut err : PythonJsonError ) -> PythonJsonError {
135+ err. add ( PathItem :: Index ( self . index ) ) ;
136+ err
137+ }
138+ }
139+
140+ #[ derive( Default ) ]
141+ pub ( crate ) struct ActiveObjectBuildPath {
142+ key : String ,
143+ }
144+
145+ impl MaybeBuildPath for ActiveObjectBuildPath {
146+ fn new_array ( ) -> ActiveBuildPath {
147+ ActiveBuildPath :: default ( )
148+ }
149+
150+ fn new_object ( ) -> ActiveObjectBuildPath {
151+ ActiveObjectBuildPath :: default ( )
152+ }
153+ }
154+
155+ impl MaybeBuildObjectPath for ActiveObjectBuildPath {
156+ fn set_key ( & mut self , key : & str ) {
157+ self . key = key. to_string ( ) ;
158+ }
159+
160+ fn set_key_path ( & self , mut err : PythonJsonError ) -> PythonJsonError {
161+ err. add ( PathItem :: Key ( self . key . clone ( ) ) ) ;
162+ err
163+ }
164+ }
165+
166+ #[ derive( Debug , Clone ) ]
167+ enum PathItem {
168+ Index ( usize ) ,
169+ Key ( String ) ,
170+ }
171+
172+ impl ToPyObject for PathItem {
173+ fn to_object ( & self , py : Python < ' _ > ) -> PyObject {
174+ match self {
175+ Self :: Index ( index) => index. to_object ( py) ,
176+ Self :: Key ( str) => str. to_object ( py) ,
177+ }
178+ }
179+ }
180+
181+ pub struct PythonJsonError {
182+ pub error : JsonError ,
183+ path : Option < Vec < PathItem > > ,
184+ }
185+
186+ pub ( crate ) type PythonJsonResult < T > = Result < T , PythonJsonError > ;
187+
188+ impl From < JsonError > for PythonJsonError {
189+ fn from ( error : JsonError ) -> Self {
190+ Self { error, path : None }
191+ }
192+ }
193+
194+ impl PythonJsonError {
195+ fn add ( & mut self , path_item : PathItem ) {
196+ match self . path . as_mut ( ) {
197+ Some ( path) => path. push ( path_item) ,
198+ None => self . path = Some ( vec ! [ path_item] ) ,
199+ }
200+ }
201+ }
0 commit comments