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