11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
25PROMEKI_NAMESPACE_BEGIN
53 using Status = std::filesystem::file_status;
59 FileInfo(
const String &filePath) : _path(filePath.str()) {}
65 FileInfo(
const char *filePath) : _path(filePath) {}
71 FileInfo(
const FilePath &fp) : _path(fp.toStdPath()) {}
77 FilePath filePath()
const {
return FilePath(_path); }
83 bool exists()
const {
return std::filesystem::exists(status()); }
89 String fileName()
const {
return _path.filename().string(); }
95 String baseName()
const {
return _path.stem().string(); }
101 String suffix()
const {
102 auto ext = _path.extension().string();
103 if (ext.empty())
return String();
104 return ext.substr(1);
111 String absolutePath()
const {
return _path.parent_path().string(); }
117 String absoluteFilePath()
const {
return std::filesystem::absolute(_path).string(); }
123 bool isFile()
const {
return std::filesystem::is_regular_file(status()); }
129 bool isDirectory()
const {
return std::filesystem::is_directory(status()); }
142 bool isSymlink()
const {
144 auto st = std::filesystem::symlink_status(_path, ec);
145 if (ec)
return false;
146 return std::filesystem::is_symlink(st);
157 bool isPseudoSymlink()
const {
return FilePath(_path).isPseudoSymlink(); }
163 bool isLink()
const {
return isSymlink() || isPseudoSymlink(); }
171 void updateStatus(
bool force =
false)
const {
172 if (!_status.hasValue() || force) {
173 _status = std::filesystem::status(_path);
183 Status status(
bool forceUpdate =
false)
const {
184 updateStatus(forceUpdate);
185 return _status.value();
198 Result<int64_t> size()
const {
199 if (!isFile())
return makeError<int64_t>(Error::NotExist);
201 auto sz = std::filesystem::file_size(_path, ec);
202 if (ec)
return makeError<int64_t>(Error::syserr(ec));
203 return makeResult(
static_cast<int64_t
>(sz));
217 bool isReadable()
const {
return ownerHasPerm(std::filesystem::perms::owner_read); }
226 bool isWritable()
const {
return ownerHasPerm(std::filesystem::perms::owner_write); }
235 bool isExecutable()
const {
return ownerHasPerm(std::filesystem::perms::owner_exec); }
250 DateTime lastModified()
const {
252 auto t = std::filesystem::last_write_time(_path, ec);
253 if (ec)
return DateTime();
262 const auto now_fc =
decltype(t)::clock::now();
263 const auto now_sc = std::chrono::system_clock::now();
265 std::chrono::time_point_cast<std::chrono::system_clock::duration>(t - now_fc + now_sc);
270 std::filesystem::path _path;
271 mutable Optional<Status> _status;
273 bool ownerHasPerm(std::filesystem::perms bit)
const {
275 auto perms = std::filesystem::status(_path, ec).permissions();
276 if (ec)
return false;
277 return (perms & bit) != std::filesystem::perms::none;