2121//! Implements a client to access Agama's storage service.
2222
2323use crate :: config:: Config ;
24+ use agama_utils:: api:: Issue ;
2425use serde_json:: { value:: RawValue , Value } ;
2526use zbus:: { names:: BusName , zvariant:: OwnedObjectPath , Connection , Message } ;
2627
@@ -73,27 +74,27 @@ impl Client {
7374
7475 pub async fn get_system ( & self ) -> Result < Option < Box < RawValue > > , Error > {
7576 let message = self . call ( "GetSystem" , & ( ) ) . await ?;
76- self . json_from ( message)
77+ try_from_message ( message)
7778 }
7879
7980 pub async fn get_config ( & self ) -> Result < Option < Config > , Error > {
8081 let message = self . call ( "GetConfig" , & ( ) ) . await ?;
81- self . json_from ( message)
82+ try_from_message ( message)
8283 }
8384
8485 pub async fn get_config_model ( & self ) -> Result < Option < Box < RawValue > > , Error > {
8586 let message = self . call ( "GetConfigModel" , & ( ) ) . await ?;
86- self . json_from ( message)
87+ try_from_message ( message)
8788 }
8889
8990 pub async fn get_proposal ( & self ) -> Result < Option < Box < RawValue > > , Error > {
9091 let message = self . call ( "GetProposal" , & ( ) ) . await ?;
91- self . json_from ( message)
92+ try_from_message ( message)
9293 }
9394
94- pub async fn get_issues ( & self ) -> Result < Option < Box < RawValue > > , Error > {
95+ pub async fn get_issues ( & self ) -> Result < Vec < Issue > , Error > {
9596 let message = self . call ( "GetIssues" , & ( ) ) . await ?;
96- self . json_from ( message)
97+ try_from_message ( message)
9798 }
9899
99100 //TODO: send a product config instead of an id.
@@ -119,7 +120,7 @@ impl Client {
119120 model : Box < RawValue > ,
120121 ) -> Result < Option < Box < RawValue > > , Error > {
121122 let message = self . call ( "SolveConfigModel" , & ( model. to_string ( ) ) ) . await ?;
122- self . json_from ( message)
123+ try_from_message ( message)
123124 }
124125
125126 pub async fn set_locale ( & self , locale : String ) -> Result < ( ) , Error > {
@@ -139,25 +140,24 @@ impl Client {
139140 . await
140141 . map_err ( |e| e. into ( ) )
141142 }
143+ }
142144
143- fn json_from < T : serde:: de:: DeserializeOwned > (
144- & self ,
145- message : Message ,
146- ) -> Result < Option < T > , Error > {
147- let value: String = message. body ( ) . deserialize ( ) ?;
148- if self . is_null ( value. as_str ( ) ) {
149- return Ok ( None ) ;
150- }
151- let json = serde_json:: from_str ( value. as_str ( ) ) ?;
152- Ok ( Some ( json) )
153- }
154-
155- fn is_null ( & self , value : & str ) -> bool {
156- let value = serde_json:: from_str :: < Value > ( value) ;
157- match value {
158- Ok ( Value :: Null ) => true ,
159- Ok ( _) => false ,
160- Err ( _) => false ,
161- }
145+ fn try_from_message < T : serde:: de:: DeserializeOwned + Default > (
146+ message : Message ,
147+ ) -> Result < T , Error > {
148+ let json: String = message. body ( ) . deserialize ( ) ?;
149+ if is_json_null ( & json) {
150+ return Ok ( T :: default ( ) ) ;
151+ }
152+ let value = serde_json:: from_str ( & json) ?;
153+ Ok ( value)
154+ }
155+
156+ fn is_json_null ( value : & str ) -> bool {
157+ let value = serde_json:: from_str :: < Value > ( value) ;
158+ match value {
159+ Ok ( Value :: Null ) => true ,
160+ Ok ( _) => false ,
161+ Err ( _) => false ,
162162 }
163163}
0 commit comments