@@ -132,6 +132,33 @@ pub enum TryLockError {
132132 WouldBlock ,
133133}
134134
135+ /// An object providing access to a directory on the filesystem.
136+ ///
137+ /// Files are automatically closed when they go out of scope. Errors detected
138+ /// on closing are ignored by the implementation of `Drop`.
139+ ///
140+ /// # Examples
141+ ///
142+ /// Opens a directory and then a file inside it.
143+ ///
144+ /// ```no_run
145+ /// #![feature(dirfd)]
146+ /// use std::{fs::Dir, io::Read};
147+ ///
148+ /// fn main() -> std::io::Result<()> {
149+ /// let dir = Dir::new("foo")?;
150+ /// let mut file = dir.open("bar.txt")?;
151+ /// let mut s = String::new();
152+ /// file.read_to_string(&mut s)?;
153+ /// println!("{}", s);
154+ /// Ok(())
155+ /// }
156+ /// ```
157+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
158+ pub struct Dir {
159+ inner : fs_imp:: Dir ,
160+ }
161+
135162/// Metadata information about a file.
136163///
137164/// This structure is returned from the [`metadata`] or
@@ -1453,6 +1480,223 @@ impl Seek for Arc<File> {
14531480 }
14541481}
14551482
1483+ impl Dir {
1484+ /// Attempts to open a directory at `path` in read-only mode.
1485+ ///
1486+ /// See [`new_with`] for more options.
1487+ ///
1488+ /// # Errors
1489+ ///
1490+ /// This function will return an error if `path` does not point to an existing directory.
1491+ /// Other errors may also be returned according to [`OpenOptions::open`].
1492+ ///
1493+ /// # Examples
1494+ ///
1495+ /// ```no_run
1496+ /// #![feature(dirfd)]
1497+ /// use std::{fs::Dir, io::Read};
1498+ ///
1499+ /// fn main() -> std::io::Result<()> {
1500+ /// let dir = Dir::new("foo")?;
1501+ /// let mut f = dir.open("bar.txt")?;
1502+ /// let mut data = vec![];
1503+ /// f.read_to_end(&mut data)?;
1504+ /// Ok(())
1505+ /// }
1506+ /// ```
1507+ ///
1508+ /// [`new_with`]: Dir::new_with
1509+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1510+ pub fn new < P : AsRef < Path > > ( path : P ) -> io:: Result < Self > {
1511+ Ok ( Self { inner : fs_imp:: Dir :: new ( path) ? } )
1512+ }
1513+
1514+ /// Attempts to open a directory at `path` with the options specified by `opts`.
1515+ ///
1516+ /// # Errors
1517+ ///
1518+ /// This function may return an error according to [`OpenOptions::open`].
1519+ ///
1520+ /// # Examples
1521+ ///
1522+ /// ```no_run
1523+ /// #![feature(dirfd)]
1524+ /// use std::fs::{Dir, OpenOptions};
1525+ ///
1526+ /// fn main() -> std::io::Result<()> {
1527+ /// let dir = Dir::new_with("foo", OpenOptions::new().write(true))?;
1528+ /// let mut f = dir.remove_file("bar.txt")?;
1529+ /// Ok(())
1530+ /// }
1531+ /// ```
1532+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1533+ pub fn new_with < P : AsRef < Path > > ( path : P , opts : & OpenOptions ) -> io:: Result < Self > {
1534+ Ok ( Self { inner : fs_imp:: Dir :: new_with ( path, & opts. 0 ) ? } )
1535+ }
1536+
1537+ /// Attempts to open a file in read-only mode relative to this directory.
1538+ ///
1539+ /// # Errors
1540+ ///
1541+ /// This function will return an error if `path` does not point to an existing file.
1542+ /// Other errors may also be returned according to [`OpenOptions::open`].
1543+ ///
1544+ /// # Examples
1545+ ///
1546+ /// ```no_run
1547+ /// #![feature(dirfd)]
1548+ /// use std::{fs::Dir, io::Read};
1549+ ///
1550+ /// fn main() -> std::io::Result<()> {
1551+ /// let dir = Dir::new("foo")?;
1552+ /// let mut f = dir.open("bar.txt")?;
1553+ /// let mut data = vec![];
1554+ /// f.read_to_end(&mut data)?;
1555+ /// Ok(())
1556+ /// }
1557+ /// ```
1558+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1559+ pub fn open < P : AsRef < Path > > ( & self , path : P ) -> io:: Result < File > {
1560+ self . inner . open ( path) . map ( |f| File { inner : f } )
1561+ }
1562+
1563+ /// Attempts to open a file relative to this directory with the options specified by `opts`.
1564+ ///
1565+ /// # Errors
1566+ ///
1567+ /// This function may return an error according to [`OpenOptions::open`].
1568+ ///
1569+ /// # Examples
1570+ ///
1571+ /// ```no_run
1572+ /// #![feature(dirfd)]
1573+ /// use std::{fs::{Dir, OpenOptions}, io::Read};
1574+ ///
1575+ /// fn main() -> std::io::Result<()> {
1576+ /// let dir = Dir::new("foo")?;
1577+ /// let mut f = dir.open_with("bar.txt", OpenOptions::new().read(true))?;
1578+ /// let mut data = vec![];
1579+ /// f.read_to_end(&mut data)?;
1580+ /// Ok(())
1581+ /// }
1582+ /// ```
1583+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1584+ pub fn open_with < P : AsRef < Path > > ( & self , path : P , opts : & OpenOptions ) -> io:: Result < File > {
1585+ self . inner . open_with ( path, & opts. 0 ) . map ( |f| File { inner : f } )
1586+ }
1587+
1588+ /// Attempts to create a directory relative to this directory.
1589+ ///
1590+ /// # Errors
1591+ ///
1592+ /// This function will return an error if `path` points to an existing file or directory.
1593+ /// Other errors may also be returned according to [`OpenOptions::open`].
1594+ ///
1595+ /// # Examples
1596+ ///
1597+ /// ```no_run
1598+ /// #![feature(dirfd)]
1599+ /// use std::{fs::{Dir, OpenOptions}, io::Read};
1600+ ///
1601+ /// fn main() -> std::io::Result<()> {
1602+ /// let dir = Dir::new("foo")?;
1603+ /// let mut f = dir.open_with("bar.txt", OpenOptions::new().read(true))?;
1604+ /// let mut data = vec![];
1605+ /// f.read_to_end(&mut data)?;
1606+ /// Ok(())
1607+ /// }
1608+ /// ```
1609+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1610+ pub fn create_dir < P : AsRef < Path > > ( & self , path : P ) -> io:: Result < ( ) > {
1611+ self . inner . create_dir ( path)
1612+ }
1613+
1614+ /// Attempts to remove a file relative to this directory.
1615+ ///
1616+ /// # Errors
1617+ ///
1618+ /// This function will return an error if `path` does not point to an existing file.
1619+ /// Other errors may also be returned according to [`OpenOptions::open`].
1620+ ///
1621+ /// # Examples
1622+ ///
1623+ /// ```no_run
1624+ /// #![feature(dirfd)]
1625+ /// use std::fs::Dir;
1626+ ///
1627+ /// fn main() -> std::io::Result<()> {
1628+ /// let dir = Dir::new("foo")?;
1629+ /// dir.remove_file("bar.txt")?;
1630+ /// Ok(())
1631+ /// }
1632+ /// ```
1633+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1634+ pub fn remove_file < P : AsRef < Path > > ( & self , path : P ) -> io:: Result < ( ) > {
1635+ self . inner . remove_file ( path)
1636+ }
1637+
1638+ /// Attempts to remove a directory relative to this directory.
1639+ ///
1640+ /// # Errors
1641+ ///
1642+ /// This function will return an error if `path` does not point to an existing, non-empty directory.
1643+ /// Other errors may also be returned according to [`OpenOptions::open`].
1644+ ///
1645+ /// # Examples
1646+ ///
1647+ /// ```no_run
1648+ /// #![feature(dirfd)]
1649+ /// use std::fs::Dir;
1650+ ///
1651+ /// fn main() -> std::io::Result<()> {
1652+ /// let dir = Dir::new("foo")?;
1653+ /// dir.remove_dir("baz")?;
1654+ /// Ok(())
1655+ /// }
1656+ /// ```
1657+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1658+ pub fn remove_dir < P : AsRef < Path > > ( & self , path : P ) -> io:: Result < ( ) > {
1659+ self . inner . remove_dir ( path)
1660+ }
1661+
1662+ /// Attempts to rename a file or directory relative to this directory to a new name, replacing
1663+ /// the destination file if present.
1664+ ///
1665+ /// # Errors
1666+ ///
1667+ /// This function will return an error if `from` does not point to an existing file or directory.
1668+ /// Other errors may also be returned according to [`OpenOptions::open`].
1669+ ///
1670+ /// # Examples
1671+ ///
1672+ /// ```no_run
1673+ /// #![feature(dirfd)]
1674+ /// use std::fs::Dir;
1675+ ///
1676+ /// fn main() -> std::io::Result<()> {
1677+ /// let dir = Dir::new("foo")?;
1678+ /// dir.rename("bar.txt", &dir, "quux.txt")?;
1679+ /// Ok(())
1680+ /// }
1681+ /// ```
1682+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1683+ pub fn rename < P : AsRef < Path > , Q : AsRef < Path > > (
1684+ & self ,
1685+ from : P ,
1686+ to_dir : & Self ,
1687+ to : Q ,
1688+ ) -> io:: Result < ( ) > {
1689+ self . inner . rename ( from, & to_dir. inner , to)
1690+ }
1691+ }
1692+
1693+ #[ unstable( feature = "dirfd" , issue = "120426" ) ]
1694+ impl fmt:: Debug for Dir {
1695+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1696+ self . inner . fmt ( f)
1697+ }
1698+ }
1699+
14561700impl OpenOptions {
14571701 /// Creates a blank new set of options ready for configuration.
14581702 ///
0 commit comments