@@ -152,17 +152,15 @@ impl Command {
152152 . context ( "Failed to get base info" ) ?;
153153
154154 if !m. is_present ( "quiet" ) {
155- println ! ( "State: {}" , info. state) ;
156- println ! ( "Device-Type: {}" , info. device_type) ;
157- println ! ( "ID: {:#04x}" , info. id) ;
158-
159- } else if let sys:: dtx:: DeviceType :: Unknown ( ty) = info. device_type {
160- println ! ( "{{ \" state\" : \" {}\" , \" type\" : {}, \" id\" : {} }}" ,
161- info. state, ty, info. id) ;
155+ println ! ( "State: {}" , info. state) ;
156+ println ! ( "Type: {}" , info. device_type) ;
157+ println ! ( "ID: {:#04x}" , info. id) ;
162158
163159 } else {
164- println ! ( "{{ \" state\" : \" {}\" , \" type\" : \" {}\" , \" id\" : {} }}" ,
165- info. state, info. device_type, info. id) ;
160+ let text = serde_json:: to_string ( & PrettyBaseInfo ( info) )
161+ . context ( "Failed to serialize data" ) ?;
162+
163+ println ! ( "{}" , text) ;
166164 }
167165
168166 Ok ( ( ) )
@@ -198,21 +196,247 @@ impl Command {
198196 Ok ( ( ) )
199197 }
200198
201- fn monitor ( & self , _m : & clap:: ArgMatches ) -> Result < ( ) > {
199+ fn monitor ( & self , m : & clap:: ArgMatches ) -> Result < ( ) > {
202200 let mut device = sys:: dtx:: Device :: open ( )
203201 . context ( "Failed to open DTX device" ) ?;
204202
205203 let events = device. events ( )
206204 . context ( "Failed to set up event stream" ) ?;
207205
206+ let quiet = m. is_present ( "quiet" ) ;
207+
208208 for event in events {
209209 let event = event
210210 . map_err ( |source| sys:: Error :: IoError { source } )
211211 . context ( "Error reading event" ) ?;
212212
213- println ! ( "{:?}" , event) ;
213+ if !quiet {
214+ println ! ( "{}" , PrettyEvent ( event) ) ;
215+
216+ } else {
217+ let text = serde_json:: to_string ( & PrettyEvent ( event) )
218+ . context ( "Failed to serialize data" ) ?;
219+
220+ println ! ( "{}" , text) ;
221+ }
214222 }
215223
216224 Ok ( ( ) )
217225 }
218226}
227+
228+
229+ struct PrettyBaseInfo ( sys:: dtx:: BaseInfo ) ;
230+
231+ impl serde:: Serialize for PrettyBaseInfo {
232+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
233+ where
234+ S : serde:: Serializer
235+ {
236+ use serde:: ser:: SerializeStruct ;
237+
238+ let mut s = serializer. serialize_struct ( "BaseInfo" , 3 ) ?;
239+
240+ match self . 0 . state {
241+ sys:: dtx:: BaseState :: Attached => s. serialize_field ( "state" , "attached" ) ,
242+ sys:: dtx:: BaseState :: Detached => s. serialize_field ( "state" , "detached" ) ,
243+ sys:: dtx:: BaseState :: NotFeasible => s. serialize_field ( "state" , "not-feasible" ) ,
244+ } ?;
245+
246+ match self . 0 . device_type {
247+ sys:: dtx:: DeviceType :: Hid => s. serialize_field ( "type" , "hid" ) ,
248+ sys:: dtx:: DeviceType :: Ssh => s. serialize_field ( "type" , "ssh" ) ,
249+ sys:: dtx:: DeviceType :: Unknown ( x) => s. serialize_field ( "type" , & x) ,
250+ } ?;
251+
252+ s. serialize_field ( "id" , & self . 0 . id ) ?;
253+ s. end ( )
254+ }
255+ }
256+
257+
258+ struct PrettyEvent ( sys:: dtx:: Event ) ;
259+
260+ impl serde:: Serialize for PrettyEvent {
261+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
262+ where
263+ S : serde:: Serializer
264+ {
265+ use serde:: ser:: SerializeStruct ;
266+ use sys:: dtx:: { DeviceType , Event , HardwareError , RuntimeError , uapi} ;
267+ use sys:: dtx:: event:: { BaseState , CancelReason , DeviceMode , LatchStatus } ;
268+
269+ match & self . 0 {
270+ Event :: Request => {
271+ let mut s = serializer. serialize_struct ( "Event" , 1 ) ?;
272+ s. serialize_field ( "type" , "request" ) ?;
273+ s. end ( )
274+ } ,
275+
276+ Event :: Cancel { reason } => {
277+ let mut s = serializer. serialize_struct ( "Event" , 2 ) ?;
278+ s. serialize_field ( "type" , "cancel" ) ?;
279+
280+ match reason {
281+ CancelReason :: Hardware ( err) => match err {
282+ HardwareError :: FailedToOpen => s. serialize_field ( "reason" , "failed-to-open" ) ,
283+ HardwareError :: FailedToRemainOpen => s. serialize_field ( "reason" , "failed-to-remain-open" ) ,
284+ HardwareError :: FailedToClose => s. serialize_field ( "reason" , "failed-to-close" ) ,
285+ HardwareError :: Unknown ( x) => {
286+ s. serialize_field ( "reason" , & ( * x as u16 | uapi:: SDTX_CATEGORY_HARDWARE_ERROR ) )
287+ } ,
288+ } ,
289+ CancelReason :: Runtime ( err) => match err {
290+ RuntimeError :: NotFeasible => s. serialize_field ( "reason" , "not-feasible" ) ,
291+ RuntimeError :: Timeout => s. serialize_field ( "reason" , "timeout" ) ,
292+ RuntimeError :: Unknown ( x) => {
293+ s. serialize_field ( "reason" , & ( * x as u16 | uapi:: SDTX_CATEGORY_RUNTIME_ERROR ) )
294+ } ,
295+ } ,
296+ CancelReason :: Unknown ( x) => s. serialize_field ( "reason" , x) ,
297+ } ?;
298+
299+ s. end ( )
300+ } ,
301+
302+ Event :: BaseConnection { state, device_type, id } => {
303+ let mut s = serializer. serialize_struct ( "Event" , 4 ) ?;
304+ s. serialize_field ( "type" , "base-connection" ) ?;
305+
306+ match state {
307+ BaseState :: Attached => s. serialize_field ( "state" , "attached" ) ,
308+ BaseState :: Detached => s. serialize_field ( "state" , "detached" ) ,
309+ BaseState :: NotFeasible => s. serialize_field ( "state" , "not-feasible" ) ,
310+ BaseState :: Unknown ( x) => s. serialize_field ( "state" , x) ,
311+ } ?;
312+
313+ match device_type {
314+ DeviceType :: Hid => s. serialize_field ( "device-type" , "hid" ) ,
315+ DeviceType :: Ssh => s. serialize_field ( "device-type" , "ssh" ) ,
316+ DeviceType :: Unknown ( x) => s. serialize_field ( "device-type" , & x) ,
317+ } ?;
318+
319+ s. serialize_field ( "id" , id) ?;
320+ s. end ( )
321+ } ,
322+
323+ Event :: LatchStatus { status } => {
324+ let mut s = serializer. serialize_struct ( "Event" , 2 ) ?;
325+ s. serialize_field ( "type" , "latch-status" ) ?;
326+
327+ match status {
328+ LatchStatus :: Closed => s. serialize_field ( "status" , "closed" ) ,
329+ LatchStatus :: Opened => s. serialize_field ( "status" , "opened" ) ,
330+ LatchStatus :: Error ( err) => match err {
331+ HardwareError :: FailedToOpen => s. serialize_field ( "status" , "failed-to-open" ) ,
332+ HardwareError :: FailedToRemainOpen => s. serialize_field ( "status" , "failed-to-remain-open" ) ,
333+ HardwareError :: FailedToClose => s. serialize_field ( "status" , "failed-to-close" ) ,
334+ HardwareError :: Unknown ( x) => {
335+ s. serialize_field ( "status" , & ( * x as u16 | uapi:: SDTX_CATEGORY_HARDWARE_ERROR ) )
336+ } ,
337+ } ,
338+ LatchStatus :: Unknown ( x) => s. serialize_field ( "status" , x) ,
339+ } ?;
340+
341+ s. end ( )
342+ } ,
343+
344+ Event :: DeviceMode { mode } => {
345+ let mut s = serializer. serialize_struct ( "Event" , 2 ) ?;
346+ s. serialize_field ( "type" , "device-mode" ) ?;
347+
348+ match mode {
349+ DeviceMode :: Tablet => s. serialize_field ( "mode" , "tablet" ) ,
350+ DeviceMode :: Laptop => s. serialize_field ( "mode" , "laptop" ) ,
351+ DeviceMode :: Studio => s. serialize_field ( "mode" , "studio" ) ,
352+ DeviceMode :: Unknown ( x) => s. serialize_field ( "mode" , x) ,
353+ } ?;
354+
355+ s. end ( )
356+ } ,
357+
358+ Event :: Unknown { code, data } => {
359+ let mut s = serializer. serialize_struct ( "Event" , 2 ) ?;
360+ s. serialize_field ( "type" , code) ?;
361+ s. serialize_field ( "data" , data) ?;
362+ s. end ( )
363+ } ,
364+ }
365+ }
366+ }
367+
368+ impl std:: fmt:: Display for PrettyEvent {
369+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
370+ use sys:: dtx:: { DeviceType , Event } ;
371+ use sys:: dtx:: event:: { BaseState , CancelReason , DeviceMode , LatchStatus } ;
372+
373+ match & self . 0 {
374+ Event :: Request => {
375+ write ! ( f, "Request" )
376+ } ,
377+
378+ Event :: Cancel { reason } => {
379+ write ! ( f, "Cancel {{ Reason: " ) ?;
380+
381+ match reason {
382+ CancelReason :: Hardware ( err) => write ! ( f, "\" {}\" " , err) ,
383+ CancelReason :: Runtime ( err) => write ! ( f, "\" {}\" " , err) ,
384+ CancelReason :: Unknown ( err) => write ! ( f, "{:#04x}" , err) ,
385+ } ?;
386+
387+ write ! ( f, " }}" )
388+ } ,
389+
390+ Event :: BaseConnection { state, device_type, id } => {
391+ write ! ( f, "BaseConnection {{ State: " ) ?;
392+
393+ match state {
394+ BaseState :: Detached => write ! ( f, "Detached" ) ,
395+ BaseState :: Attached => write ! ( f, "Attached" ) ,
396+ BaseState :: NotFeasible => write ! ( f, "NotFeasible" ) ,
397+ BaseState :: Unknown ( x) => write ! ( f, "{:#04x}" , x) ,
398+ } ?;
399+
400+ write ! ( f, ", DeviceType: " ) ?;
401+
402+ match device_type {
403+ DeviceType :: Hid => write ! ( f, "Hid" ) ,
404+ DeviceType :: Ssh => write ! ( f, "Ssh" ) ,
405+ DeviceType :: Unknown ( x) => write ! ( f, "{:#04x}" , x) ,
406+ } ?;
407+
408+ write ! ( f, ", Id: {:#04x} }}" , id)
409+ } ,
410+
411+ Event :: LatchStatus { status } => {
412+ write ! ( f, "LatchStatus {{ Status: " ) ?;
413+
414+ match status {
415+ LatchStatus :: Closed => write ! ( f, "Closed" ) ,
416+ LatchStatus :: Opened => write ! ( f, "Opened" ) ,
417+ LatchStatus :: Error ( err) => write ! ( f, "\" Error: {}\" " , err) ,
418+ LatchStatus :: Unknown ( x) => write ! ( f, "{:#04x}" , x) ,
419+ } ?;
420+
421+ write ! ( f, " }}" )
422+ } ,
423+
424+ Event :: DeviceMode { mode } => {
425+ write ! ( f, "DeviceMode {{ Status: " ) ?;
426+
427+ match mode {
428+ DeviceMode :: Tablet => write ! ( f, "Tablet" ) ,
429+ DeviceMode :: Laptop => write ! ( f, "Laptop" ) ,
430+ DeviceMode :: Studio => write ! ( f, "Studio" ) ,
431+ DeviceMode :: Unknown ( x) => write ! ( f, "{:#04x}" , x) ,
432+ } ?;
433+
434+ write ! ( f, " }}" )
435+ } ,
436+
437+ Event :: Unknown { code, data } => {
438+ write ! ( f, "Unknown {{ Code: {:#04x}, Data: {:02x?} }}" , code, data)
439+ } ,
440+ }
441+ }
442+ }
0 commit comments