@@ -153,6 +153,33 @@ pub enum TryLockError {
153
153
WouldBlock ,
154
154
}
155
155
156
+ /// An object providing access to a directory on the filesystem.
157
+ ///
158
+ /// Files are automatically closed when they go out of scope. Errors detected
159
+ /// on closing are ignored by the implementation of `Drop`.
160
+ ///
161
+ /// # Examples
162
+ ///
163
+ /// Opens a directory and then a file inside it.
164
+ ///
165
+ /// ```no_run
166
+ /// #![feature(dirfd)]
167
+ /// use std::{fs::Dir, io::Read};
168
+ ///
169
+ /// fn main() -> std::io::Result<()> {
170
+ /// let dir = Dir::new("foo")?;
171
+ /// let mut file = dir.open("bar.txt")?;
172
+ /// let mut s = String::new();
173
+ /// file.read_to_string(&mut s)?;
174
+ /// println!("{}", s);
175
+ /// Ok(())
176
+ /// }
177
+ /// ```
178
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
179
+ pub struct Dir {
180
+ inner : fs_imp:: Dir ,
181
+ }
182
+
156
183
/// Metadata information about a file.
157
184
///
158
185
/// This structure is returned from the [`metadata`] or
@@ -1474,6 +1501,89 @@ impl Seek for Arc<File> {
1474
1501
}
1475
1502
}
1476
1503
1504
+ impl Dir {
1505
+ /// Attempts to open a directory at `path` in read-only mode.
1506
+ ///
1507
+ /// See [`new_with`] for more options.
1508
+ ///
1509
+ /// # Errors
1510
+ ///
1511
+ /// This function will return an error if `path` does not point to an existing directory.
1512
+ /// Other errors may also be returned according to [`OpenOptions::open`].
1513
+ ///
1514
+ /// # Examples
1515
+ ///
1516
+ /// ```no_run
1517
+ /// #![feature(dirfd)]
1518
+ /// use std::{fs::Dir, io::Read};
1519
+ ///
1520
+ /// fn main() -> std::io::Result<()> {
1521
+ /// let dir = Dir::new("foo")?;
1522
+ /// let mut f = dir.open("bar.txt")?;
1523
+ /// let mut data = vec![];
1524
+ /// f.read_to_end(&mut data)?;
1525
+ /// Ok(())
1526
+ /// }
1527
+ /// ```
1528
+ ///
1529
+ /// [`new_with`]: Dir::new_with
1530
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1531
+ pub fn open < P : AsRef < Path > > ( path : P ) -> io:: Result < Self > {
1532
+ fs_imp:: Dir :: open ( path) . map ( |inner| Self { inner } )
1533
+ }
1534
+
1535
+ ///
1536
+ /// Attempts to open a file in read-only mode relative to this directory.
1537
+ ///
1538
+ /// # Errors
1539
+ ///
1540
+ /// This function will return an error if `path` does not point to an existing file.
1541
+ /// Other errors may also be returned according to [`OpenOptions::open`].
1542
+ ///
1543
+ /// # Examples
1544
+ ///
1545
+ /// ```no_run
1546
+ /// #![feature(dirfd)]
1547
+ /// use std::{fs::Dir, io::Read};
1548
+ ///
1549
+ /// fn main() -> std::io::Result<()> {
1550
+ /// let dir = Dir::new("foo")?;
1551
+ /// let mut f = dir.open("bar.txt")?;
1552
+ /// let mut data = vec![];
1553
+ /// f.read_to_end(&mut data)?;
1554
+ /// Ok(())
1555
+ /// }
1556
+ /// ```
1557
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1558
+ pub fn open_file < P : AsRef < Path > > ( & self , path : P ) -> io:: Result < File > {
1559
+ self . inner . open_file ( path) . map ( |f| File { inner : f } )
1560
+ }
1561
+ }
1562
+
1563
+ impl AsInner < fs_imp:: Dir > for Dir {
1564
+ #[ inline]
1565
+ fn as_inner ( & self ) -> & fs_imp:: Dir {
1566
+ & self . inner
1567
+ }
1568
+ }
1569
+ impl FromInner < fs_imp:: Dir > for Dir {
1570
+ fn from_inner ( f : fs_imp:: Dir ) -> File {
1571
+ Dir { inner : f }
1572
+ }
1573
+ }
1574
+ impl IntoInner < fs_imp:: Dir > for Dir {
1575
+ fn into_inner ( self ) -> fs_imp:: Dir {
1576
+ self . inner
1577
+ }
1578
+ }
1579
+
1580
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1581
+ impl fmt:: Debug for Dir {
1582
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1583
+ self . inner . fmt ( f)
1584
+ }
1585
+ }
1586
+
1477
1587
impl OpenOptions {
1478
1588
/// Creates a blank new set of options ready for configuration.
1479
1589
///
@@ -2440,6 +2550,178 @@ impl DirEntry {
2440
2550
pub fn file_name ( & self ) -> OsString {
2441
2551
self . 0 . file_name ( )
2442
2552
}
2553
+
2554
+ /// Attempts to open the file represented by `self` in read-only mode.
2555
+ ///
2556
+ /// # Errors
2557
+ ///
2558
+ /// This function will error whenever [`File::open`] would error, including when `self`
2559
+ /// represents a directory.
2560
+ ///
2561
+ /// # Examples
2562
+ ///
2563
+ /// ```no_run
2564
+ /// #![feature(dirfd)]
2565
+ /// use std::{fs, io::read_to_string};
2566
+ ///
2567
+ /// if let Ok(entries) = fs::read_dir(".") {
2568
+ /// for entry in entries {
2569
+ /// if let Ok(entry) = entry {
2570
+ /// // Here, `entry` is a `DirEntry`.
2571
+ /// if let Ok(file) = entry.open_file() && let Ok(text) = read_to_string(file) {
2572
+ /// println!("{}", text);
2573
+ /// }
2574
+ /// }
2575
+ /// }
2576
+ /// }
2577
+ /// ```
2578
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
2579
+ pub fn open_file ( & self ) -> io:: Result < File > {
2580
+ self . 0 . open_file ( ) . map ( |inner| File { inner } )
2581
+ }
2582
+
2583
+ /// Attempts to open the file represented by `self` with the options specified by `opts`.
2584
+ ///
2585
+ /// # Errors
2586
+ ///
2587
+ /// This function will error whenever [`OpenOptions::open`] would error, including when `self`
2588
+ /// represents a directory.
2589
+ ///
2590
+ /// # Examples
2591
+ ///
2592
+ /// ```no_run
2593
+ /// #![feature(dirfd)]
2594
+ /// use std::{fs, io::Write};
2595
+ ///
2596
+ /// if let Ok(entries) = fs::read_dir(".") {
2597
+ /// for entry in entries {
2598
+ /// if let Ok(entry) = entry {
2599
+ /// // Here, `entry` is a `DirEntry`.
2600
+ /// if let Ok(mut file) = entry.open_file_with(fs::OpenOptions::new().write(true)) {
2601
+ /// let _ = file.write(b"foo");
2602
+ /// }
2603
+ /// }
2604
+ /// }
2605
+ /// }
2606
+ /// ```
2607
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
2608
+ pub fn open_file_with ( & self , opts : & OpenOptions ) -> io:: Result < File > {
2609
+ self . 0 . open_file_with ( & opts. 0 ) . map ( |inner| File { inner } )
2610
+ }
2611
+
2612
+ /// Attempts to open the directory represented by `self` in read-only mode.
2613
+ ///
2614
+ /// # Errors
2615
+ ///
2616
+ /// This function will error whenever [`Dir::new`] would error, including when `self`
2617
+ /// represents a file.
2618
+ ///
2619
+ /// # Examples
2620
+ ///
2621
+ /// ```no_run
2622
+ /// #![feature(dirfd)]
2623
+ /// use std::{fs, io::read_to_string};
2624
+ ///
2625
+ /// if let Ok(entries) = fs::read_dir(".") {
2626
+ /// for entry in entries {
2627
+ /// if let Ok(entry) = entry {
2628
+ /// // Here, `entry` is a `DirEntry`.
2629
+ /// if let Ok(dir) = entry.open_dir() && let Ok(file) = dir.open("foo") && let Ok(text) = read_to_string(file) {
2630
+ /// println!("{}", text);
2631
+ /// }
2632
+ /// }
2633
+ /// }
2634
+ /// }
2635
+ /// ```
2636
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
2637
+ pub fn open_dir ( & self ) -> io:: Result < Dir > {
2638
+ self . 0 . open_dir ( ) . map ( |inner| Dir { inner } )
2639
+ }
2640
+
2641
+ /// Attempts to open the directory represented by `self` with the options specified by `opts`.
2642
+ ///
2643
+ /// # Errors
2644
+ ///
2645
+ /// This function will error whenever [`Dir::new_with`] would error, including when `self`
2646
+ /// represents a file.
2647
+ ///
2648
+ /// # Examples
2649
+ ///
2650
+ /// ```no_run
2651
+ /// #![feature(dirfd)]
2652
+ /// use std::fs;
2653
+ ///
2654
+ /// if let Ok(entries) = fs::read_dir(".") {
2655
+ /// for entry in entries {
2656
+ /// if let Ok(entry) = entry {
2657
+ /// // Here, `entry` is a `DirEntry`.
2658
+ /// if let Ok(dir) = entry.open_dir_with(fs::OpenOptions::new().write(true)) {
2659
+ /// let _ = dir.remove_file("foo");
2660
+ /// }
2661
+ /// }
2662
+ /// }
2663
+ /// }
2664
+ /// ```
2665
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
2666
+ pub fn open_dir_with ( & self , opts : & OpenOptions ) -> io:: Result < Dir > {
2667
+ self . 0 . open_dir_with ( & opts. 0 ) . map ( |inner| Dir { inner } )
2668
+ }
2669
+
2670
+ /// Attempts to remove the file represented by `self`.
2671
+ ///
2672
+ /// # Errors
2673
+ ///
2674
+ /// This function will return an error whenever [`remove_file`] would error.
2675
+ ///
2676
+ /// # Examples
2677
+ ///
2678
+ /// ```no_run
2679
+ /// #![feature(dirfd)]
2680
+ /// use std::fs;
2681
+ ///
2682
+ /// if let Ok(entries) = fs::read_dir(".") {
2683
+ /// for entry in entries {
2684
+ /// if let Ok(entry) = entry {
2685
+ /// // Here, `entry` is a `DirEntry`.
2686
+ /// if let Ok(ty) = entry.file_type() && ty.is_file() {
2687
+ /// let _ = entry.remove_file();
2688
+ /// }
2689
+ /// }
2690
+ /// }
2691
+ /// }
2692
+ /// ```
2693
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
2694
+ pub fn remove_file ( & self ) -> io:: Result < ( ) > {
2695
+ self . 0 . remove_file ( )
2696
+ }
2697
+
2698
+ /// Attempts to remove the directory represented by `self`.
2699
+ ///
2700
+ /// # Errors
2701
+ ///
2702
+ /// This function will return an error whenever [`remove_dir`] would error.
2703
+ ///
2704
+ /// # Examples
2705
+ ///
2706
+ /// ```no_run
2707
+ /// #![feature(dirfd)]
2708
+ /// use std::fs;
2709
+ ///
2710
+ /// if let Ok(entries) = fs::read_dir(".") {
2711
+ /// for entry in entries {
2712
+ /// if let Ok(entry) = entry {
2713
+ /// // Here, `entry` is a `DirEntry`.
2714
+ /// if let Ok(ty) = entry.file_type() && ty.is_dir() {
2715
+ /// let _ = entry.remove_dir();
2716
+ /// }
2717
+ /// }
2718
+ /// }
2719
+ /// }
2720
+ /// ```
2721
+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
2722
+ pub fn remove_dir ( & self ) -> io:: Result < ( ) > {
2723
+ self . 0 . remove_dir ( )
2724
+ }
2443
2725
}
2444
2726
2445
2727
#[ stable( feature = "dir_entry_debug" , since = "1.13.0" ) ]
0 commit comments