Skip to content

Commit ee4a7fd

Browse files
authored
Make it possible to use Path and friends on wasip2 without the so named feature (#1525)
* refactor(path): delegate implementations where possible * feat(path): enable Path and friends on wasip2 without the feature Unfortunately, `OsStrExt` and `OsStringExt` require the wasip2 feature on wasip2 so we can't use `as_bytes()` on `OsStr` and friends. However, the recommendation on the upstream issue [1] is to just use `to_str` as WASI paths are unicode. [1]: rust-lang/rust#130323 (comment)
1 parent 7f5d939 commit ee4a7fd

File tree

1 file changed

+45
-92
lines changed

1 file changed

+45
-92
lines changed

src/path/arg.rs

Lines changed: 45 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ impl Arg for String {
229229
}
230230

231231
#[cfg(feature = "std")]
232-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
233232
impl Arg for &OsStr {
234233
#[inline]
235234
fn as_str(&self) -> io::Result<&str> {
@@ -243,19 +242,18 @@ impl Arg for &OsStr {
243242

244243
#[inline]
245244
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
246-
Ok(Cow::Owned(
247-
CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
248-
))
245+
self.into_c_str()
249246
}
250247

251248
#[inline]
252249
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
253250
where
254251
Self: 'b,
255252
{
256-
Ok(Cow::Owned(
257-
CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
258-
))
253+
#[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
254+
return self.to_str().ok_or(io::Errno::INVAL)?.into_c_str();
255+
#[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
256+
return self.as_bytes().into_c_str();
259257
}
260258

261259
#[inline]
@@ -264,12 +262,15 @@ impl Arg for &OsStr {
264262
Self: Sized,
265263
F: FnOnce(&CStr) -> io::Result<T>,
266264
{
267-
with_c_str(self.as_bytes(), f)
265+
#[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
266+
return self.as_str()?.into_with_c_str(f);
267+
268+
#[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
269+
return self.as_bytes().into_with_c_str(f);
268270
}
269271
}
270272

271273
#[cfg(feature = "std")]
272-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
273274
impl Arg for &OsString {
274275
#[inline]
275276
fn as_str(&self) -> io::Result<&str> {
@@ -283,10 +284,7 @@ impl Arg for &OsString {
283284

284285
#[inline]
285286
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
286-
Ok(Cow::Owned(
287-
CString::new(OsString::as_os_str(self).as_bytes())
288-
.map_err(|_cstr_err| io::Errno::INVAL)?,
289-
))
287+
self.as_os_str().into_c_str()
290288
}
291289

292290
#[inline]
@@ -303,12 +301,11 @@ impl Arg for &OsString {
303301
Self: Sized,
304302
F: FnOnce(&CStr) -> io::Result<T>,
305303
{
306-
with_c_str(self.as_bytes(), f)
304+
self.as_os_str().into_with_c_str(f)
307305
}
308306
}
309307

310308
#[cfg(feature = "std")]
311-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
312309
impl Arg for OsString {
313310
#[inline]
314311
fn as_str(&self) -> io::Result<&str> {
@@ -322,19 +319,21 @@ impl Arg for OsString {
322319

323320
#[inline]
324321
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
325-
Ok(Cow::Owned(
326-
CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
327-
))
322+
self.as_os_str().into_c_str()
328323
}
329324

330325
#[inline]
331326
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
332327
where
333328
Self: 'b,
334329
{
335-
Ok(Cow::Owned(
336-
CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?,
337-
))
330+
#[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
331+
return self
332+
.into_string()
333+
.map_err(|_strng_err| io::Errno::INVAL)?
334+
.into_c_str();
335+
#[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
336+
self.into_vec().into_c_str()
338337
}
339338

340339
#[inline]
@@ -343,12 +342,11 @@ impl Arg for OsString {
343342
Self: Sized,
344343
F: FnOnce(&CStr) -> io::Result<T>,
345344
{
346-
f(&CString::new(self.into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?)
345+
f(&self.into_c_str()?)
347346
}
348347
}
349348

350349
#[cfg(feature = "std")]
351-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
352350
impl Arg for &Path {
353351
#[inline]
354352
fn as_str(&self) -> io::Result<&str> {
@@ -362,19 +360,15 @@ impl Arg for &Path {
362360

363361
#[inline]
364362
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
365-
Ok(Cow::Owned(
366-
CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
367-
))
363+
self.as_os_str().into_c_str()
368364
}
369365

370366
#[inline]
371367
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
372368
where
373369
Self: 'b,
374370
{
375-
Ok(Cow::Owned(
376-
CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
377-
))
371+
self.as_os_str().into_c_str()
378372
}
379373

380374
#[inline]
@@ -383,19 +377,15 @@ impl Arg for &Path {
383377
Self: Sized,
384378
F: FnOnce(&CStr) -> io::Result<T>,
385379
{
386-
with_c_str(self.as_os_str().as_bytes(), f)
380+
self.as_os_str().into_with_c_str(f)
387381
}
388382
}
389383

390384
#[cfg(feature = "std")]
391-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
392385
impl Arg for &PathBuf {
393386
#[inline]
394387
fn as_str(&self) -> io::Result<&str> {
395-
PathBuf::as_path(self)
396-
.as_os_str()
397-
.to_str()
398-
.ok_or(io::Errno::INVAL)
388+
self.as_os_str().to_str().ok_or(io::Errno::INVAL)
399389
}
400390

401391
#[inline]
@@ -405,10 +395,7 @@ impl Arg for &PathBuf {
405395

406396
#[inline]
407397
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
408-
Ok(Cow::Owned(
409-
CString::new(PathBuf::as_path(self).as_os_str().as_bytes())
410-
.map_err(|_cstr_err| io::Errno::INVAL)?,
411-
))
398+
self.as_os_str().into_c_str()
412399
}
413400

414401
#[inline]
@@ -425,12 +412,11 @@ impl Arg for &PathBuf {
425412
Self: Sized,
426413
F: FnOnce(&CStr) -> io::Result<T>,
427414
{
428-
with_c_str(self.as_os_str().as_bytes(), f)
415+
self.as_os_str().into_with_c_str(f)
429416
}
430417
}
431418

432419
#[cfg(feature = "std")]
433-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
434420
impl Arg for PathBuf {
435421
#[inline]
436422
fn as_str(&self) -> io::Result<&str> {
@@ -444,19 +430,15 @@ impl Arg for PathBuf {
444430

445431
#[inline]
446432
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
447-
Ok(Cow::Owned(
448-
CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
449-
))
433+
self.as_os_str().into_c_str()
450434
}
451435

452436
#[inline]
453437
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
454438
where
455439
Self: 'b,
456440
{
457-
Ok(Cow::Owned(
458-
CString::new(self.into_os_string().into_vec()).map_err(|_cstr_err| io::Errno::INVAL)?,
459-
))
441+
self.into_os_string().into_c_str()
460442
}
461443

462444
#[inline]
@@ -465,10 +447,7 @@ impl Arg for PathBuf {
465447
Self: Sized,
466448
F: FnOnce(&CStr) -> io::Result<T>,
467449
{
468-
f(
469-
&CString::new(self.into_os_string().into_vec())
470-
.map_err(|_cstr_err| io::Errno::INVAL)?,
471-
)
450+
self.into_os_string().into_with_c_str(f)
472451
}
473452
}
474453

@@ -623,7 +602,6 @@ impl<'a> Arg for Cow<'a, str> {
623602
}
624603

625604
#[cfg(feature = "std")]
626-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
627605
impl<'a> Arg for Cow<'a, OsStr> {
628606
#[inline]
629607
fn as_str(&self) -> io::Result<&str> {
@@ -637,23 +615,18 @@ impl<'a> Arg for Cow<'a, OsStr> {
637615

638616
#[inline]
639617
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
640-
Ok(Cow::Owned(
641-
CString::new(self.as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
642-
))
618+
(&**self).into_c_str()
643619
}
644620

645621
#[inline]
646622
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
647623
where
648624
Self: 'b,
649625
{
650-
Ok(Cow::Owned(
651-
match self {
652-
Cow::Owned(os) => CString::new(os.into_vec()),
653-
Cow::Borrowed(os) => CString::new(os.as_bytes()),
654-
}
655-
.map_err(|_cstr_err| io::Errno::INVAL)?,
656-
))
626+
match self {
627+
Cow::Owned(os) => os.into_c_str(),
628+
Cow::Borrowed(os) => os.into_c_str(),
629+
}
657630
}
658631

659632
#[inline]
@@ -662,7 +635,7 @@ impl<'a> Arg for Cow<'a, OsStr> {
662635
Self: Sized,
663636
F: FnOnce(&CStr) -> io::Result<T>,
664637
{
665-
with_c_str(self.as_bytes(), f)
638+
(&*self).into_with_c_str(f)
666639
}
667640
}
668641

@@ -703,7 +676,6 @@ impl<'a> Arg for Cow<'a, CStr> {
703676
}
704677

705678
#[cfg(feature = "std")]
706-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
707679
impl<'a> Arg for Component<'a> {
708680
#[inline]
709681
fn as_str(&self) -> io::Result<&str> {
@@ -717,19 +689,15 @@ impl<'a> Arg for Component<'a> {
717689

718690
#[inline]
719691
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
720-
Ok(Cow::Owned(
721-
CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
722-
))
692+
self.as_os_str().into_c_str()
723693
}
724694

725695
#[inline]
726696
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
727697
where
728698
Self: 'b,
729699
{
730-
Ok(Cow::Owned(
731-
CString::new(self.as_os_str().as_bytes()).map_err(|_cstr_err| io::Errno::INVAL)?,
732-
))
700+
self.as_os_str().into_c_str()
733701
}
734702

735703
#[inline]
@@ -738,12 +706,11 @@ impl<'a> Arg for Component<'a> {
738706
Self: Sized,
739707
F: FnOnce(&CStr) -> io::Result<T>,
740708
{
741-
with_c_str(self.as_os_str().as_bytes(), f)
709+
self.as_os_str().into_with_c_str(f)
742710
}
743711
}
744712

745713
#[cfg(feature = "std")]
746-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
747714
impl<'a> Arg for Components<'a> {
748715
#[inline]
749716
fn as_str(&self) -> io::Result<&str> {
@@ -757,21 +724,15 @@ impl<'a> Arg for Components<'a> {
757724

758725
#[inline]
759726
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
760-
Ok(Cow::Owned(
761-
CString::new(self.as_path().as_os_str().as_bytes())
762-
.map_err(|_cstr_err| io::Errno::INVAL)?,
763-
))
727+
self.as_path().into_c_str()
764728
}
765729

766730
#[inline]
767731
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
768732
where
769733
Self: 'b,
770734
{
771-
Ok(Cow::Owned(
772-
CString::new(self.as_path().as_os_str().as_bytes())
773-
.map_err(|_cstr_err| io::Errno::INVAL)?,
774-
))
735+
self.as_path().into_c_str()
775736
}
776737

777738
#[inline]
@@ -780,12 +741,11 @@ impl<'a> Arg for Components<'a> {
780741
Self: Sized,
781742
F: FnOnce(&CStr) -> io::Result<T>,
782743
{
783-
with_c_str(self.as_path().as_os_str().as_bytes(), f)
744+
self.as_path().into_with_c_str(f)
784745
}
785746
}
786747

787748
#[cfg(feature = "std")]
788-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
789749
impl<'a> Arg for Iter<'a> {
790750
#[inline]
791751
fn as_str(&self) -> io::Result<&str> {
@@ -799,21 +759,15 @@ impl<'a> Arg for Iter<'a> {
799759

800760
#[inline]
801761
fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
802-
Ok(Cow::Owned(
803-
CString::new(self.as_path().as_os_str().as_bytes())
804-
.map_err(|_cstr_err| io::Errno::INVAL)?,
805-
))
762+
self.as_path().into_c_str()
806763
}
807764

808765
#[inline]
809766
fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
810767
where
811768
Self: 'b,
812769
{
813-
Ok(Cow::Owned(
814-
CString::new(self.as_path().as_os_str().as_bytes())
815-
.map_err(|_cstr_err| io::Errno::INVAL)?,
816-
))
770+
self.as_path().into_c_str()
817771
}
818772

819773
#[inline]
@@ -822,7 +776,7 @@ impl<'a> Arg for Iter<'a> {
822776
Self: Sized,
823777
F: FnOnce(&CStr) -> io::Result<T>,
824778
{
825-
with_c_str(self.as_path().as_os_str().as_bytes(), f)
779+
self.as_path().into_with_c_str(f)
826780
}
827781
}
828782

@@ -910,7 +864,6 @@ impl Arg for &Vec<u8> {
910864
}
911865

912866
#[cfg(feature = "alloc")]
913-
#[cfg(any(not(target_os = "wasi"), not(target_env = "p2"), wasip2))]
914867
impl Arg for Vec<u8> {
915868
#[inline]
916869
fn as_str(&self) -> io::Result<&str> {

0 commit comments

Comments
 (0)