44use anyhow:: { Context , Result } ;
55use clap:: Args ;
66use expand_tilde:: expand_tilde;
7+ use std:: ffi:: OsString ;
78use std:: fs;
89use std:: path:: { Path , PathBuf } ;
910
@@ -28,19 +29,21 @@ pub struct BuildArgs {
2829/// the parent becomes the output directory (or `.` if none) and the file name
2930/// becomes the protocol filename. Otherwise `out` is treated as a directory and
3031/// the default `protocol.bin` filename is used.
31- fn resolve_out ( out : & Path ) -> ( PathBuf , String ) {
32+ ///
33+ /// The filename is kept as an `OsString` so non-UTF8 paths round-trip unchanged.
34+ fn resolve_out ( out : & Path ) -> ( PathBuf , OsString ) {
3235 if out. extension ( ) . and_then ( |e| e. to_str ( ) ) == Some ( "bin" ) {
3336 let name = out
3437 . file_name ( )
35- . map ( |n| n . to_string_lossy ( ) . into_owned ( ) )
36- . unwrap_or_else ( || "protocol.bin" . to_string ( ) ) ;
38+ . map ( OsString :: from )
39+ . unwrap_or_else ( || OsString :: from ( "protocol.bin" ) ) ;
3740 let dir = match out. parent ( ) {
3841 Some ( p) if !p. as_os_str ( ) . is_empty ( ) => p. to_path_buf ( ) ,
3942 _ => PathBuf :: from ( "." ) ,
4043 } ;
4144 ( dir, name)
4245 } else {
43- ( out. to_path_buf ( ) , "protocol.bin" . to_string ( ) )
46+ ( out. to_path_buf ( ) , OsString :: from ( "protocol.bin" ) )
4447 }
4548}
4649
@@ -72,11 +75,12 @@ fn run(args: &BuildArgs) -> Result<()> {
7275 . with_context ( || format ! ( "App folder not found: {}" , args. app_args. app. display( ) ) ) ?;
7376
7477 let ( out_dir, protocol_name) = resolve_out ( & out) ;
78+ let protocol_path = out_dir. join ( & protocol_name) ;
7579
7680 output:: header ( "WebUI Build" ) ;
7781 output:: field ( "App" , & app. display ( ) ) ;
7882 output:: field ( "Entry" , & args. app_args . entry ) ;
79- output:: field ( "Output" , & out_dir . join ( & protocol_name ) . display ( ) ) ;
83+ output:: field ( "Output" , & protocol_path . display ( ) ) ;
8084 output:: field ( "CSS" , & args. app_args . css ) ;
8185 if let Some ( ref plugin_name) = args. app_args . plugin {
8286 output:: field ( "Plugin" , plugin_name) ;
@@ -91,8 +95,8 @@ fn run(args: &BuildArgs) -> Result<()> {
9195
9296 fs:: create_dir_all ( & out_dir)
9397 . with_context ( || format ! ( "Failed to create {}" , out_dir. display( ) ) ) ?;
94- fs:: write ( out_dir . join ( & protocol_name ) , & result. protocol_bytes )
95- . with_context ( || format ! ( "Failed to write {} to {} " , protocol_name , out_dir . display( ) ) ) ?;
98+ fs:: write ( & protocol_path , & result. protocol_bytes )
99+ . with_context ( || format ! ( "Failed to write {}" , protocol_path . display( ) ) ) ?;
96100 for ( name, content) in & result. css_files {
97101 fs:: write ( out_dir. join ( name) , content)
98102 . with_context ( || format ! ( "Failed to write {name} to {}" , out_dir. display( ) ) ) ?;
@@ -121,7 +125,10 @@ fn run(args: &BuildArgs) -> Result<()> {
121125 }
122126
123127 let files_written = 1 + stats. css_file_count ;
124- output:: success ( & format ! ( "Wrote {}" , console:: style( & protocol_name) . bold( ) ) ) ;
128+ output:: success ( & format ! (
129+ "Wrote {}" ,
130+ console:: style( Path :: new( & protocol_name) . display( ) ) . bold( )
131+ ) ) ;
125132
126133 output:: finish ( & format ! (
127134 "Build complete ({} file{} written) {}" ,
0 commit comments