@@ -20,6 +20,7 @@ use std::os::windows::process::CommandExt;
2020const CREATE_NO_WINDOW : u32 = 0x0800_0000 ;
2121
2222use crate :: async_runtime:: { block_on as block_on_task, channel, Receiver , Sender } ;
23+ pub use encoding_rs:: Encoding ;
2324use os_pipe:: { pipe, PipeReader , PipeWriter } ;
2425use serde:: Serialize ;
2526use shared_child:: SharedChild ;
@@ -95,6 +96,7 @@ pub struct Command {
9596 env_clear : bool ,
9697 env : HashMap < String , String > ,
9798 current_dir : Option < PathBuf > ,
99+ encoding : Option < & ' static Encoding > ,
98100}
99101
100102/// Spawned child process.
@@ -171,6 +173,7 @@ impl Command {
171173 env_clear : false ,
172174 env : Default :: default ( ) ,
173175 current_dir : None ,
176+ encoding : None ,
174177 }
175178 }
176179
@@ -216,6 +219,13 @@ impl Command {
216219 self
217220 }
218221
222+ /// Sets the character encoding for stdout/stderr.
223+ #[ must_use]
224+ pub fn encoding ( mut self , encoding : & ' static Encoding ) -> Self {
225+ self . encoding . replace ( encoding) ;
226+ self
227+ }
228+
219229 /// Spawns the command.
220230 ///
221231 /// # Examples
@@ -264,12 +274,14 @@ impl Command {
264274 guard. clone ( ) ,
265275 stdout_reader,
266276 CommandEvent :: Stdout ,
277+ self . encoding ,
267278 ) ;
268279 spawn_pipe_reader (
269280 tx. clone ( ) ,
270281 guard. clone ( ) ,
271282 stderr_reader,
272283 CommandEvent :: Stderr ,
284+ self . encoding ,
273285 ) ;
274286
275287 spawn ( move || {
@@ -378,6 +390,7 @@ fn spawn_pipe_reader<F: Fn(String) -> CommandEvent + Send + Copy + 'static>(
378390 guard : Arc < RwLock < ( ) > > ,
379391 pipe_reader : PipeReader ,
380392 wrapper : F ,
393+ character_encoding : Option < & ' static Encoding > ,
381394) {
382395 spawn ( move || {
383396 let _lock = guard. read ( ) . unwrap ( ) ;
@@ -392,7 +405,10 @@ fn spawn_pipe_reader<F: Fn(String) -> CommandEvent + Send + Copy + 'static>(
392405 break ;
393406 }
394407 let tx_ = tx. clone ( ) ;
395- let line = String :: from_utf8 ( buf. clone ( ) ) ;
408+ let line = match character_encoding {
409+ Some ( encoding) => Ok ( encoding. decode_with_bom_removal ( & buf) . 0 . into ( ) ) ,
410+ None => String :: from_utf8 ( buf. clone ( ) ) ,
411+ } ;
396412 block_on_task ( async move {
397413 let _ = match line {
398414 Ok ( line) => tx_. send ( wrapper ( line) ) . await ,
0 commit comments