@@ -730,6 +730,7 @@ pub struct Args {
730
730
#[ arg( long, action = clap:: ArgAction :: Count , default_value_t = 0u8 , ) ]
731
731
verbose : u8 ,
732
732
733
+ // Todo
733
734
/// Disable encryption for a specific action. By default encryption is
734
735
/// turned on wherever possible. E.g. rooms created will be created
735
736
/// by default with encryption enabled. To turn encryption off for a
@@ -967,6 +968,20 @@ pub struct Args {
967
968
/// i.e. -m 'start' '-' 'end'
968
969
/// will send 3 messages out of which the second one is read from stdin.
969
970
/// The stdin indicator '-' may appear only once overall in all arguments.
971
+ /// '-' reads everything that is in the pipe in one swoop and
972
+ /// sends a single message.
973
+ /// Similar to '-', another shortcut character
974
+ /// is '_'. The special character '_' is used for
975
+ /// streaming data via a pipe on stdin. With '_' the stdin
976
+ /// pipe is read line-by-line and each line is treated as
977
+ /// a separate message and sent right away. The program
978
+ /// waits for pipe input until the pipe is closed. E.g.
979
+ /// Imagine a tool that generates output sporadically
980
+ /// 24x7. It can be piped, i.e. streamed, into matrix-
981
+ /// commander, and matrix-commander stays active, sending
982
+ /// all input instantly. If you want to send the literal
983
+ /// letter '_' then escape it and send '\_'. '_' can be
984
+ /// used only once. And either '-' or '_' can be used.
970
985
#[ arg( short, long, num_args( 0 ..) , ) ]
971
986
message : Vec < String > ,
972
987
@@ -2449,6 +2464,16 @@ pub(crate) async fn cli_verify(client: &Client, ap: &Args) -> Result<(), Error>
2449
2464
crate :: verify ( client) . await
2450
2465
}
2451
2466
2467
+ fn trim_newline ( s : & mut String ) -> & mut String {
2468
+ if s. ends_with ( '\n' ) {
2469
+ s. pop ( ) ;
2470
+ if s. ends_with ( '\r' ) {
2471
+ s. pop ( ) ;
2472
+ }
2473
+ }
2474
+ return s;
2475
+ }
2476
+
2452
2477
/// Handle the --message CLI argument
2453
2478
pub ( crate ) async fn cli_message ( client : & Client , ap : & Args ) -> Result < ( ) , Error > {
2454
2479
info ! ( "Message chosen." ) ;
@@ -2479,16 +2504,64 @@ pub(crate) async fn cli_message(client: &Client, ap: &Args) -> Result<(), Error>
2479
2504
io:: stdin ( ) . read_to_string ( & mut line) ?;
2480
2505
}
2481
2506
line
2507
+ } else if msg == r"_" {
2508
+ let mut eof = false ;
2509
+ while !eof {
2510
+ let mut line = String :: new ( ) ;
2511
+ match io:: stdin ( ) . read_line ( & mut line) {
2512
+ // If this function returns Ok(0), the stream has reached EOF.
2513
+ Ok ( n) => {
2514
+ if n == 0 {
2515
+ eof = true ;
2516
+ debug ! ( "Reached EOF of pipe stream." ) ;
2517
+ } else {
2518
+ debug ! (
2519
+ "Read {n} bytes containing \" {}\\ n\" from pipe stream." ,
2520
+ trim_newline( & mut line. clone( ) )
2521
+ ) ;
2522
+ match message (
2523
+ client,
2524
+ & [ line] ,
2525
+ & ap. room ,
2526
+ ap. code ,
2527
+ ap. markdown ,
2528
+ ap. notice ,
2529
+ ap. emote ,
2530
+ )
2531
+ . await
2532
+ {
2533
+ Ok ( ( ) ) => {
2534
+ debug ! ( "message from pipe stream sent successfully" ) ;
2535
+ }
2536
+ Err ( ref e) => {
2537
+ error ! (
2538
+ "Error: sending message from pipe stream reported {}" ,
2539
+ e
2540
+ ) ;
2541
+ }
2542
+ }
2543
+ }
2544
+ }
2545
+ Err ( ref e) => {
2546
+ error ! ( "Error: reading from pipe stream reported {}" , e) ;
2547
+ }
2548
+ }
2549
+ }
2550
+ "" . to_owned ( )
2482
2551
} else if msg == r"\-" {
2483
2552
"-" . to_string ( )
2553
+ } else if msg == r"\_" {
2554
+ "_" . to_string ( )
2484
2555
} else if msg == r"\-\-" {
2485
2556
"--" . to_string ( )
2486
2557
} else if msg == r"\-\-\-" {
2487
2558
"---" . to_string ( )
2488
2559
} else {
2489
2560
msg. to_string ( )
2490
2561
} ;
2491
- fmsgs. push ( fmsg) ;
2562
+ if !fmsg. is_empty ( ) {
2563
+ fmsgs. push ( fmsg) ;
2564
+ }
2492
2565
}
2493
2566
if fmsgs. is_empty ( ) {
2494
2567
return Ok ( ( ) ) ; // nothing to do
@@ -2860,7 +2933,9 @@ async fn main() -> Result<(), Error> {
2860
2933
2861
2934
eprintln ! ( "WARNING: Incompatible change between version v0.1.20 and v0.1.21." ) ;
2862
2935
eprintln ! ( "If your credentials file was created with Python, don't do anything." ) ;
2863
- eprintln ! ( "If your credentials file was created with Rust, follow either Option 1 or Option 2." ) ;
2936
+ eprintln ! (
2937
+ "If your credentials file was created with Rust, follow either Option 1 or Option 2."
2938
+ ) ;
2864
2939
eprintln ! ( "Option 1: Please edit your Rust-created credentials file (usually at $HOME/.local/share/matrix-commander-rs/credentials.json)." ) ;
2865
2940
eprintln ! ( "Replace \" room_default\" with \" room_id\" ." ) ;
2866
2941
eprintln ! ( "Option 2: Alternatively you can delete the credentials file and create a new one by logging in again. " ) ;
0 commit comments