2828//! let symbol_manager = SymbolManager::with_helper(helper);
2929//! let api = samply_api::Api::new(&symbol_manager);
3030//!
31- //! api.query_api(
31+ //! let api_result = api.query_api(
3232//! "/symbolicate/v5",
3333//! r#"{
3434//! "memoryMap": [
4646//! ]
4747//! ]
4848//! }"#,
49- //! ).await
49+ //! ).await;
50+ //! serde_json::to_string(&api_result).unwrap()
5051//! }
5152//!
5253//! struct ExampleHelper {
@@ -147,7 +148,7 @@ use debugid::DebugId;
147148pub use samply_symbols;
148149pub use samply_symbols:: debugid;
149150use samply_symbols:: { FileAndPathHelper , SymbolManager } ;
150- use serde_json :: json ;
151+ use serde :: Serialize ;
151152use source:: SourceApi ;
152153use symbolicate:: SymbolicateApi ;
153154
@@ -158,6 +159,8 @@ mod hex;
158159mod source;
159160mod symbolicate;
160161
162+ pub use error:: Error ;
163+
161164pub ( crate ) fn to_debug_id ( breakpad_id : & str ) -> Result < DebugId , samply_symbols:: Error > {
162165 // Only accept breakpad IDs with the right syntax, and which aren't all-zeros.
163166 match DebugId :: from_breakpad ( breakpad_id) {
@@ -168,12 +171,57 @@ pub(crate) fn to_debug_id(breakpad_id: &str) -> Result<DebugId, samply_symbols::
168171 }
169172}
170173
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+
171219#[ derive( Clone , Copy ) ]
172220pub struct Api < ' a , H : FileAndPathHelper > {
173221 symbol_manager : & ' a SymbolManager < H > ,
174222}
175223
176- impl < ' a , H : FileAndPathHelper > Api < ' a , H > {
224+ impl < ' a , H : FileAndPathHelper + ' static > Api < ' a , H > {
177225 /// Create a [`Api`] instance which uses the provided [`SymbolManager`].
178226 pub fn new ( symbol_manager : & ' a SymbolManager < H > ) -> Self {
179227 Self { symbol_manager }
@@ -194,18 +242,34 @@ impl<'a, H: FileAndPathHelper> Api<'a, H> {
194242 /// symbol information for that address.
195243 /// - `/asm/v1`: Experimental API. Symbolicates an address and lets you read one of the files in the
196244 /// 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 > {
198259 if request_url == "/symbolicate/v5" {
199260 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 ( ) )
201265 } else if request_url == "/source/v1" {
202266 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 ( ) )
204268 } else if request_url == "/asm/v1" {
205269 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 ( ) )
207271 } else {
208- json ! ( { "error" : format! ( "Unrecognized URL { request_url}" ) } ) . to_string ( )
272+ Err ( Error :: UnrecognizedUrl ( request_url. into ( ) ) )
209273 }
210274 }
211275}
0 commit comments