1
+ mod format;
2
+
3
+ use crate :: format:: format_mqtt_log_entry;
1
4
use aws_iot_device_sdk_rust:: settings:: MQTTOptionsOverrides ;
2
5
use aws_iot_device_sdk_rust:: {
3
6
async_event_loop_listener, AWSIoTAsyncClient , AWSIoTSettings , Packet , QoS ,
@@ -8,7 +11,6 @@ use log::debug;
8
11
use regex:: Regex ;
9
12
use serde_json:: Value ;
10
13
use std:: error:: Error ;
11
- use std:: hash:: { Hash , Hasher } ;
12
14
use std:: sync:: Arc ;
13
15
use tokio:: signal;
14
16
use tokio:: sync:: Mutex ;
@@ -24,7 +26,7 @@ use tokio::time::{sleep, Duration};
24
26
MQTT CLI for AWS IoT
25
27
26
28
This tool allows you to subscribe to or publish messages to AWS IoT topics.
27
- You can filter messages using regex patterns for inclusion or exclusion.
29
+ You can filter messages from topics using regex patterns for inclusion or exclusion.
28
30
29
31
Examples:
30
32
aws-iot-mqtt-cli sub --topics test/1234/health,test/2345/data
@@ -225,7 +227,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
225
227
continue ;
226
228
}
227
229
}
228
- format_mqtt_log_entry ( & topic, & payload) ;
230
+ let formatted_output = format_mqtt_log_entry ( & topic, & payload) ;
231
+ println ! ( "{}" , formatted_output) ;
229
232
}
230
233
}
231
234
} ) ;
@@ -295,87 +298,3 @@ async fn main() -> Result<(), Box<dyn Error>> {
295
298
296
299
Ok ( ( ) )
297
300
}
298
-
299
- fn format_mqtt_log_entry ( topic : & str , payload : & str ) {
300
- let color = derive_color_from_string ( topic) ;
301
- let timestamp = chrono:: Utc :: now ( ) . to_rfc3339 ( ) ;
302
- let pretty_output = match serde_json:: from_str :: < Value > ( payload) {
303
- Ok ( value) => serde_json:: to_string_pretty ( & value) . unwrap_or_else ( |_| payload. to_string ( ) ) ,
304
- Err ( _) => payload. to_string ( ) ,
305
- } ;
306
-
307
- let terminal_width = term_size:: dimensions ( )
308
- . map ( |( width, _) | width)
309
- . unwrap_or ( 96 ) ;
310
-
311
- let timestamp_width = timestamp. len ( ) ;
312
- let max_topic_width = terminal_width. saturating_sub ( timestamp_width + 1 ) ;
313
-
314
- let truncated_topic = if topic. len ( ) > max_topic_width {
315
- format ! ( "{}…" , & topic[ ..max_topic_width. saturating_sub( 1 ) ] )
316
- } else {
317
- topic. to_string ( )
318
- } ;
319
-
320
- let header_text = if topic. len ( ) <= max_topic_width {
321
- let spacer_width = terminal_width. saturating_sub ( truncated_topic. len ( ) + timestamp_width) ;
322
- let spacer = " " . repeat ( spacer_width) ;
323
- format ! ( "{}{}{}" , truncated_topic, spacer, timestamp)
324
- } else if topic. len ( ) <= terminal_width {
325
- truncated_topic
326
- } else {
327
- format ! ( "{}…" , & topic[ ..terminal_width. saturating_sub( 1 ) ] )
328
- } ;
329
-
330
- let divider = "─" . repeat ( header_text. len ( ) ) ;
331
- let styled_divider = divider. color ( color) . bold ( ) ;
332
- let styled_header = header_text. color ( color) . bold ( ) ;
333
- let styled_json = pretty_output. bright_white ( ) ;
334
-
335
- print_log_section ( & styled_divider, & styled_header) ;
336
- println ! ( "{}" , styled_json) ;
337
- print_log_section ( & styled_divider, & styled_header) ;
338
- println ! ( ) ;
339
- }
340
-
341
- /// Helper function to print header/footer sections
342
- fn print_log_section ( divider : & ColoredString , header : & ColoredString ) {
343
- println ! ( "{}" , divider) ;
344
- println ! ( "{}" , header) ;
345
- println ! ( "{}" , divider) ;
346
- }
347
-
348
- fn derive_color_from_string ( topic : & str ) -> Color {
349
- let mut hasher = std:: collections:: hash_map:: DefaultHasher :: new ( ) ;
350
- topic. hash ( & mut hasher) ;
351
- let hash = hasher. finish ( ) ;
352
-
353
- // Generate vibrant colors using golden ratio distribution
354
- let hue = ( hash as f64 ) * 0.618033988749895 % 360.0 ;
355
- let saturation = 75.0 + ( ( hash >> 8 ) % 25 ) as f64 ; // 75-100%
356
- let lightness = 45.0 + ( ( hash >> 16 ) % 15 ) as f64 ; // 45-60%
357
-
358
- let ( r, g, b) = hsl_to_rgb ( hue, saturation / 100.0 , lightness / 100.0 ) ;
359
- Color :: TrueColor { r, g, b }
360
- }
361
-
362
- fn hsl_to_rgb ( h : f64 , s : f64 , l : f64 ) -> ( u8 , u8 , u8 ) {
363
- let c = ( 1.0 - ( 2.0 * l - 1.0 ) . abs ( ) ) * s;
364
- let x = c * ( 1.0 - ( ( h / 60.0 ) % 2.0 - 1.0 ) . abs ( ) ) ;
365
- let m = l - c / 2.0 ;
366
-
367
- let ( r, g, b) = match h {
368
- h if h < 60.0 => ( c, x, 0.0 ) ,
369
- h if h < 120.0 => ( x, c, 0.0 ) ,
370
- h if h < 180.0 => ( 0.0 , c, x) ,
371
- h if h < 240.0 => ( 0.0 , x, c) ,
372
- h if h < 300.0 => ( x, 0.0 , c) ,
373
- _ => ( c, 0.0 , x) ,
374
- } ;
375
-
376
- (
377
- ( ( r + m) * 255.0 ) . round ( ) as u8 ,
378
- ( ( g + m) * 255.0 ) . round ( ) as u8 ,
379
- ( ( b + m) * 255.0 ) . round ( ) as u8 ,
380
- )
381
- }
0 commit comments