dius 0.1.0
Loading...
Searching...
No Matches
directory_entry.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/container/path/prelude.h"
4#include "di/function/prelude.h"
5#include "di/util/prelude.h"
6#include "di/vocab/error/prelude.h"
8#include "dius/filesystem/file_type.h"
10
12
14public:
15 DirectoryEntry() = default;
16
18
20
21 constexpr auto path() const& -> di::Path const& { return m_path; }
22 constexpr auto path() && -> di::Path&& { return di::move(m_path); }
23 constexpr auto path_view() const -> di::PathView { return m_path.view(); }
24 constexpr auto filename() const -> di::Optional<di::PathView> { return path_view().filename(); }
25
26 constexpr operator di::Path const&() const& { return path(); }
27 constexpr operator di::Path&&() && { return di::move(*this).path(); }
28 constexpr operator di::PathView() const { return path_view(); }
29
30 auto exists() const -> di::Result<bool> {
31 if (has_cached_type()) {
32 return filesystem::exists(FileStatus(m_cached_type));
33 }
35 }
36
37 auto is_block_file() const -> di::Result<bool> {
38 if (has_cached_type()) {
39 return filesystem::is_block_file(FileStatus(m_cached_type));
40 }
42 }
43
44 auto is_character_file() const -> di::Result<bool> {
45 if (has_cached_type()) {
46 return filesystem::is_character_file(FileStatus(m_cached_type));
47 }
49 }
50
51 auto is_directory() const -> di::Result<bool> {
52 if (has_cached_type()) {
53 return filesystem::is_directory(FileStatus(m_cached_type));
54 }
56 }
57
58 auto is_fifo() const -> di::Result<bool> {
59 if (has_cached_type()) {
60 return filesystem::is_fifo(FileStatus(m_cached_type));
61 }
63 }
64
65 auto is_other() const -> di::Result<bool> {
66 if (has_cached_type()) {
67 return filesystem::is_other(FileStatus(m_cached_type));
68 }
70 }
71
72 auto is_regular_file() const -> di::Result<bool> {
73 if (has_cached_type()) {
74 return filesystem::is_regular_file(FileStatus(m_cached_type));
75 }
77 }
78
79 auto is_socket() const -> di::Result<bool> {
80 if (has_cached_type()) {
81 return filesystem::is_socket(FileStatus(m_cached_type));
82 }
84 }
85
86 auto is_symlink() const -> di::Result<bool> {
87 if (m_cached_type != FileType::Unknown) {
88 return filesystem::is_symlink(FileStatus(m_cached_type));
89 }
91 }
92
93 auto file_size() const -> di::Result<umax> { return filesystem::file_size(path_view()); }
94 auto hard_link_count() const -> di::Result<umax> { return filesystem::hard_link_count(path_view()); }
95
96 auto status() const -> di::Result<FileStatus> { return filesystem::status(path_view()); }
97 auto symlink_status() const -> di::Result<FileStatus> { return filesystem::symlink_status(path_view()); }
98
99private:
100 friend class DirectoryIterator;
102
103 constexpr friend auto operator==(DirectoryEntry const& a, DirectoryEntry const& b) -> bool {
104 return a.path_view() == b.path_view();
105 }
106 constexpr friend auto operator<=>(DirectoryEntry const& a, DirectoryEntry const& b) -> di::strong_ordering {
107 return a.path_view() <=> b.path_view();
108 }
109
110 explicit DirectoryEntry(di::Path&& path, FileType cached_type)
111 : m_path(di::move(path)), m_cached_type(cached_type) {}
112
113 auto is_non_symlink_directory() const -> di::Expected<bool, di::GenericCode> {
114 if (m_cached_type != FileType::Unknown) {
115 return m_cached_type == FileType::Directory;
116 }
117 // FIXME: this cast seems extremely dubious, and most likely
118 // is not performing the intended behavior.
119 return di::Expected<bool, di::GenericCode>(is_directory());
120 }
121
122 constexpr auto has_cached_type() const -> bool {
123 // NOTE: if the file type is a symlink, then we have to follow that symlink when
124 // answering all queries other than is_symlink(), which will require calling
125 // `status()`.
126 return m_cached_type != FileType::Unknown && m_cached_type != FileType::Symlink;
127 }
128
129 template<di::concepts::Encoding Enc>
130 constexpr friend auto tag_invoke(di::Tag<di::formatter_in_place>, di::InPlaceType<DirectoryEntry>,
131 di::FormatParseContext<Enc>& context) {
132 return di::format::formatter<di::PathView, Enc>(context) % [](di::concepts::CopyConstructible auto formatter) {
133 return [=](di::FormatContext auto& context, DirectoryEntry const& a) {
134 return formatter(context, a.path_view());
135 };
136 };
137 }
138
139 di::Path m_path;
140 FileType m_cached_type { FileType::None };
141};
142}
auto is_directory() const -> di::Result< bool >
Definition directory_entry.h:51
auto is_regular_file() const -> di::Result< bool >
Definition directory_entry.h:72
constexpr friend auto operator==(DirectoryEntry const &a, DirectoryEntry const &b) -> bool
Definition directory_entry.h:103
auto file_size() const -> di::Result< umax >
Definition directory_entry.h:93
auto is_block_file() const -> di::Result< bool >
Definition directory_entry.h:37
auto is_fifo() const -> di::Result< bool >
Definition directory_entry.h:58
auto operator=(DirectoryEntry &&) -> DirectoryEntry &=default
constexpr operator di::PathView() const
Definition directory_entry.h:28
constexpr friend auto operator<=>(DirectoryEntry const &a, DirectoryEntry const &b) -> di::strong_ordering
Definition directory_entry.h:106
DirectoryEntry(DirectoryEntry &&)=default
auto is_other() const -> di::Result< bool >
Definition directory_entry.h:65
constexpr auto path() const &-> di::Path const &
Definition directory_entry.h:21
auto exists() const -> di::Result< bool >
Definition directory_entry.h:30
friend class RecursiveDirectoryIterator
Definition directory_entry.h:101
auto status() const -> di::Result< FileStatus >
Definition directory_entry.h:96
constexpr auto path_view() const -> di::PathView
Definition directory_entry.h:23
auto is_character_file() const -> di::Result< bool >
Definition directory_entry.h:44
auto hard_link_count() const -> di::Result< umax >
Definition directory_entry.h:94
constexpr friend auto tag_invoke(di::Tag< di::formatter_in_place >, di::InPlaceType< DirectoryEntry >, di::FormatParseContext< Enc > &context)
Definition directory_entry.h:130
auto is_socket() const -> di::Result< bool >
Definition directory_entry.h:79
friend class DirectoryIterator
Definition directory_entry.h:100
constexpr auto path() &&-> di::Path &&
Definition directory_entry.h:22
auto is_symlink() const -> di::Result< bool >
Definition directory_entry.h:86
constexpr auto filename() const -> di::Optional< di::PathView >
Definition directory_entry.h:24
auto symlink_status() const -> di::Result< FileStatus >
Definition directory_entry.h:97
Definition file_status.h:7
Definition error.h:7
Definition directory_entry.h:11
constexpr auto file_size
Definition file_size.h:13
constexpr auto is_socket
Definition is_socket.h:14
constexpr auto is_directory
Definition is_directory.h:14
constexpr auto is_symlink
Definition is_symlink.h:14
constexpr auto is_block_file
Definition is_block_file.h:14
FileType
Definition file_type.h:7
@ Symlink
Definition file_type.h:15
@ None
Definition file_type.h:10
@ Unknown
Definition file_type.h:20
@ Directory
Definition file_type.h:14
constexpr auto is_other
Definition is_other.h:20
constexpr auto symlink_status
Definition symlink_status.h:14
constexpr auto is_character_file
Definition is_character_file.h:14
constexpr auto status
Definition status.h:14
constexpr auto is_fifo
Definition is_fifo.h:14
constexpr auto hard_link_count
Definition hard_link_count.h:13
constexpr auto exists
Definition exists.h:17
constexpr auto is_regular_file
Definition is_regular_file.h:14