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()); }
135 void updateStatus(
bool force =
false)
const {
136 if (!_status.hasValue() || force) {
137 _status = std::filesystem::status(_path);
147 Status status(
bool forceUpdate =
false)
const {
148 updateStatus(forceUpdate);
149 return _status.value();
162 Result<int64_t> size()
const {
163 if (!isFile())
return makeError<int64_t>(Error::NotExist);
165 auto sz = std::filesystem::file_size(_path, ec);
166 if (ec)
return makeError<int64_t>(Error::syserr(ec));
167 return makeResult(
static_cast<int64_t
>(sz));
181 bool isReadable()
const {
return ownerHasPerm(std::filesystem::perms::owner_read); }
190 bool isWritable()
const {
return ownerHasPerm(std::filesystem::perms::owner_write); }
199 bool isExecutable()
const {
return ownerHasPerm(std::filesystem::perms::owner_exec); }
214 DateTime lastModified()
const {
216 auto t = std::filesystem::last_write_time(_path, ec);
217 if (ec)
return DateTime();
226 const auto now_fc =
decltype(t)::clock::now();
227 const auto now_sc = std::chrono::system_clock::now();
229 std::chrono::time_point_cast<std::chrono::system_clock::duration>(t - now_fc + now_sc);
234 std::filesystem::path _path;
235 mutable Optional<Status> _status;
237 bool ownerHasPerm(std::filesystem::perms bit)
const {
239 auto perms = std::filesystem::status(_path, ec).permissions();
240 if (ec)
return false;
241 return (perms & bit) != std::filesystem::perms::none;