\brief Expected POSIX semantics for the rename operation on multiple scenarios. If the src doesn't exist, the error is always ENOENT, otherwise we are left with the following combinations: 1. src's type a. File b. Directory 2. dest's existence a. NotFound b. File c. Directory - empty - non-empty 3. src path has a trailing slash (or not) 4. dest path has a trailing slash (or not) Limitations: th
| 1822 | /// \return std::nullopt if success is expected in the scenario or the errno |
| 1823 | /// if failure is expected. |
| 1824 | static std::optional<int> RenameSemantics(FileType src_type, bool src_trailing_slash, |
| 1825 | FileType dest_type, bool dest_trailing_slash, |
| 1826 | bool dest_is_empty_dir = false, |
| 1827 | bool paths_are_equal = false) { |
| 1828 | DCHECK(src_type != FileType::Unknown && dest_type != FileType::Unknown); |
| 1829 | DCHECK(!dest_is_empty_dir || dest_type == FileType::Directory) |
| 1830 | << "dest_is_empty_dir must imply dest_type == FileType::Directory"; |
| 1831 | switch (src_type) { |
| 1832 | case FileType::Unknown: |
| 1833 | break; |
| 1834 | case FileType::NotFound: |
| 1835 | return {ENOENT}; |
| 1836 | case FileType::File: |
| 1837 | switch (dest_type) { |
| 1838 | case FileType::Unknown: |
| 1839 | break; |
| 1840 | case FileType::NotFound: |
| 1841 | if (src_trailing_slash) { |
| 1842 | return {ENOTDIR}; |
| 1843 | } |
| 1844 | if (dest_trailing_slash) { |
| 1845 | // A slash on the destination path requires that it exists, |
| 1846 | // so a confirmation that it's a directory can be performed. |
| 1847 | return {ENOENT}; |
| 1848 | } |
| 1849 | return {}; |
| 1850 | case FileType::File: |
| 1851 | if (src_trailing_slash || dest_trailing_slash) { |
| 1852 | return {ENOTDIR}; |
| 1853 | } |
| 1854 | // The existing file is replaced successfuly. |
| 1855 | return {}; |
| 1856 | case FileType::Directory: |
| 1857 | if (src_trailing_slash) { |
| 1858 | return {ENOTDIR}; |
| 1859 | } |
| 1860 | return EISDIR; |
| 1861 | } |
| 1862 | break; |
| 1863 | case FileType::Directory: |
| 1864 | switch (dest_type) { |
| 1865 | case FileType::Unknown: |
| 1866 | break; |
| 1867 | case FileType::NotFound: |
| 1868 | // We don't have to care about the slashes when the source is a directory. |
| 1869 | return {}; |
| 1870 | case FileType::File: |
| 1871 | return {ENOTDIR}; |
| 1872 | case FileType::Directory: |
| 1873 | if (!paths_are_equal && !dest_is_empty_dir) { |
| 1874 | return {ENOTEMPTY}; |
| 1875 | } |
| 1876 | return {}; |
| 1877 | } |
| 1878 | break; |
| 1879 | } |
| 1880 | Unreachable("Invalid parameters passed to RenameSemantics"); |
| 1881 | } |
nothing calls this directly
no test coverage detected