@@ -94,9 +94,61 @@ pub fn bytes_as_os_str(b: &[u8]) -> Result<&std::ffi::OsStr, Utf8Error> {
9494
9595#[ cfg( unix) ]
9696pub use std:: os:: unix:: ffi;
97- #[ cfg( target_os = "wasi" ) ]
97+
98+ // WASIp1 uses stable std::os::wasi::ffi
99+ #[ cfg( all( target_os = "wasi" , not( target_env = "p2" ) ) ) ]
98100pub use std:: os:: wasi:: ffi;
99101
102+ // WASIp2: std::os::wasip2::ffi is unstable, so we provide a stable implementation
103+ // leveraging WASI's UTF-8 string guarantee
104+ #[ cfg( all( target_os = "wasi" , target_env = "p2" ) ) ]
105+ pub mod ffi {
106+ use std:: ffi:: { OsStr , OsString } ;
107+
108+ pub trait OsStrExt : sealed:: Sealed {
109+ fn as_bytes ( & self ) -> & [ u8 ] ;
110+ fn from_bytes ( slice : & [ u8 ] ) -> & Self ;
111+ }
112+
113+ impl OsStrExt for OsStr {
114+ fn as_bytes ( & self ) -> & [ u8 ] {
115+ // WASI strings are guaranteed to be UTF-8
116+ self . to_str ( ) . expect ( "wasip2 strings are UTF-8" ) . as_bytes ( )
117+ }
118+
119+ fn from_bytes ( slice : & [ u8 ] ) -> & OsStr {
120+ // WASI strings are guaranteed to be UTF-8
121+ OsStr :: new ( std:: str:: from_utf8 ( slice) . expect ( "wasip2 strings are UTF-8" ) )
122+ }
123+ }
124+
125+ pub trait OsStringExt : sealed:: Sealed {
126+ fn from_vec ( vec : Vec < u8 > ) -> Self ;
127+ fn into_vec ( self ) -> Vec < u8 > ;
128+ }
129+
130+ impl OsStringExt for OsString {
131+ fn from_vec ( vec : Vec < u8 > ) -> OsString {
132+ // WASI strings are guaranteed to be UTF-8
133+ OsString :: from ( String :: from_utf8 ( vec) . expect ( "wasip2 strings are UTF-8" ) )
134+ }
135+
136+ fn into_vec ( self ) -> Vec < u8 > {
137+ // WASI strings are guaranteed to be UTF-8
138+ self . to_str ( )
139+ . expect ( "wasip2 strings are UTF-8" )
140+ . as_bytes ( )
141+ . to_vec ( )
142+ }
143+ }
144+
145+ mod sealed {
146+ pub trait Sealed { }
147+ impl Sealed for std:: ffi:: OsStr { }
148+ impl Sealed for std:: ffi:: OsString { }
149+ }
150+ }
151+
100152#[ cfg( windows) ]
101153pub fn errno_to_winerror ( errno : i32 ) -> i32 {
102154 use libc:: * ;
0 commit comments