28
28
//! let symbol_manager = SymbolManager::with_helper(helper);
29
29
//! let api = samply_api::Api::new(&symbol_manager);
30
30
//!
31
- //! api.query_api(
31
+ //! let api_result = api.query_api(
32
32
//! "/symbolicate/v5",
33
33
//! r#"{
34
34
//! "memoryMap": [
46
46
//! ]
47
47
//! ]
48
48
//! }"#,
49
- //! ).await
49
+ //! ).await;
50
+ //! serde_json::to_string(&api_result).unwrap()
50
51
//! }
51
52
//!
52
53
//! struct ExampleHelper {
@@ -147,7 +148,7 @@ use debugid::DebugId;
147
148
pub use samply_symbols;
148
149
pub use samply_symbols:: debugid;
149
150
use samply_symbols:: { FileAndPathHelper , SymbolManager } ;
150
- use serde_json :: json ;
151
+ use serde :: Serialize ;
151
152
use source:: SourceApi ;
152
153
use symbolicate:: SymbolicateApi ;
153
154
@@ -158,6 +159,8 @@ mod hex;
158
159
mod source;
159
160
mod symbolicate;
160
161
162
+ pub use error:: Error ;
163
+
161
164
pub ( crate ) fn to_debug_id ( breakpad_id : & str ) -> Result < DebugId , samply_symbols:: Error > {
162
165
// Only accept breakpad IDs with the right syntax, and which aren't all-zeros.
163
166
match DebugId :: from_breakpad ( breakpad_id) {
@@ -168,12 +171,57 @@ pub(crate) fn to_debug_id(breakpad_id: &str) -> Result<DebugId, samply_symbols::
168
171
}
169
172
}
170
173
174
+ pub enum QueryApiJsonResult < H : FileAndPathHelper > {
175
+ SymbolicateResponse ( symbolicate:: response_json:: Response < H > ) ,
176
+ SourceResponse ( source:: response_json:: Response ) ,
177
+ AsmResponse ( asm:: response_json:: Response ) ,
178
+ Err ( Error ) ,
179
+ }
180
+
181
+ impl < H : FileAndPathHelper > From < symbolicate:: response_json:: Response < H > > for QueryApiJsonResult < H > {
182
+ fn from ( value : symbolicate:: response_json:: Response < H > ) -> Self {
183
+ QueryApiJsonResult :: SymbolicateResponse ( value)
184
+ }
185
+ }
186
+
187
+ impl < H : FileAndPathHelper > From < source:: response_json:: Response > for QueryApiJsonResult < H > {
188
+ fn from ( value : source:: response_json:: Response ) -> Self {
189
+ QueryApiJsonResult :: SourceResponse ( value)
190
+ }
191
+ }
192
+
193
+ impl < H : FileAndPathHelper > From < asm:: response_json:: Response > for QueryApiJsonResult < H > {
194
+ fn from ( value : asm:: response_json:: Response ) -> Self {
195
+ QueryApiJsonResult :: AsmResponse ( value)
196
+ }
197
+ }
198
+
199
+ impl < H : FileAndPathHelper > From < Error > for QueryApiJsonResult < H > {
200
+ fn from ( value : Error ) -> Self {
201
+ QueryApiJsonResult :: Err ( value)
202
+ }
203
+ }
204
+
205
+ impl < H : FileAndPathHelper > Serialize for QueryApiJsonResult < H > {
206
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
207
+ where
208
+ S : serde:: Serializer ,
209
+ {
210
+ match self {
211
+ QueryApiJsonResult :: SymbolicateResponse ( response) => response. serialize ( serializer) ,
212
+ QueryApiJsonResult :: SourceResponse ( response) => response. serialize ( serializer) ,
213
+ QueryApiJsonResult :: AsmResponse ( response) => response. serialize ( serializer) ,
214
+ QueryApiJsonResult :: Err ( error) => error. serialize ( serializer) ,
215
+ }
216
+ }
217
+ }
218
+
171
219
#[ derive( Clone , Copy ) ]
172
220
pub struct Api < ' a , H : FileAndPathHelper > {
173
221
symbol_manager : & ' a SymbolManager < H > ,
174
222
}
175
223
176
- impl < ' a , H : FileAndPathHelper > Api < ' a , H > {
224
+ impl < ' a , H : FileAndPathHelper + ' static > Api < ' a , H > {
177
225
/// Create a [`Api`] instance which uses the provided [`SymbolManager`].
178
226
pub fn new ( symbol_manager : & ' a SymbolManager < H > ) -> Self {
179
227
Self { symbol_manager }
@@ -194,18 +242,34 @@ impl<'a, H: FileAndPathHelper> Api<'a, H> {
194
242
/// symbol information for that address.
195
243
/// - `/asm/v1`: Experimental API. Symbolicates an address and lets you read one of the files in the
196
244
/// symbol information for that address.
197
- pub async fn query_api ( self , request_url : & str , request_json_data : & str ) -> String {
245
+ pub async fn query_api (
246
+ self ,
247
+ request_url : & str ,
248
+ request_json_data : & str ,
249
+ ) -> QueryApiJsonResult < H > {
250
+ self . query_api_fallible ( request_url, request_json_data)
251
+ . await
252
+ . unwrap_or_else ( |e| e. into ( ) )
253
+ }
254
+ pub async fn query_api_fallible (
255
+ self ,
256
+ request_url : & str ,
257
+ request_json_data : & str ,
258
+ ) -> Result < QueryApiJsonResult < H > , Error > {
198
259
if request_url == "/symbolicate/v5" {
199
260
let symbolicate_api = SymbolicateApi :: new ( self . symbol_manager ) ;
200
- symbolicate_api. query_api_json ( request_json_data) . await
261
+ Ok ( symbolicate_api
262
+ . query_api_json ( request_json_data)
263
+ . await ?
264
+ . into ( ) )
201
265
} else if request_url == "/source/v1" {
202
266
let source_api = SourceApi :: new ( self . symbol_manager ) ;
203
- source_api. query_api_json ( request_json_data) . await
267
+ Ok ( source_api. query_api_json ( request_json_data) . await ? . into ( ) )
204
268
} else if request_url == "/asm/v1" {
205
269
let asm_api = AsmApi :: new ( self . symbol_manager ) ;
206
- asm_api. query_api_json ( request_json_data) . await
270
+ Ok ( asm_api. query_api_json ( request_json_data) . await ? . into ( ) )
207
271
} else {
208
- json ! ( { "error" : format! ( "Unrecognized URL { request_url}" ) } ) . to_string ( )
272
+ Err ( Error :: UnrecognizedUrl ( request_url. into ( ) ) )
209
273
}
210
274
}
211
275
}
0 commit comments