Files
rrr.v2/src/rrr/content/file/file.hpp
2023-03-18 14:03:39 +03:00

131 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "utils/utils.hpp"
#include <filesystem>
#include <vector>
#include <algorithm>
#include "logger/logger.hpp"
namespace rrr
{
// NONE - просто выводится текст. когда пупка пуста и нет контента вообще
// FILE - файл
// DIR - дирректория
enum class file_type
{
NONE, FILE, DIR
};
// класс-тип контента
// т.е. контентом является все, что может поместиться в терминал
// и это все называется файлом. ддиректория - это файл, файл - это файл и т.п.
// просто каждая сущность имеет свой тип см. выше
class file : public hack::utils::counter<int>
{
public:
file() = default;
file(std::filesystem::path, file_type, bool, bool);
file(file&&);
file(const file&);
public:
file& operator=(const file&);
bool operator<(const file&) const;
bool operator==(const file&) const;
friend std::ostream& operator<<(std::ostream&, const file&);
public:
int id;
std::filesystem::path path;
file_type type;
bool is_link = false;
bool is_hidden = false;
bool is_mark = false;
};
}
namespace rrr::file_utils
{
using files = std::vector<file>;
inline bool is_hidden(const std::filesystem::path &p)
{
std::filesystem::path::string_type name = p.filename();
if(name != ".." && name != "." && name[0] == '.')
return true;
return false;
}
struct filesystem_convert
{
file operator()(const std::filesystem::directory_entry& entry) const
{
file_type type = file_type::FILE;
if (std::filesystem::is_directory(entry))
type = file_type::DIR;
auto is_link = std::filesystem::is_symlink(entry);
auto is_hidden = file_utils::is_hidden(entry);
return { entry.path(), type, is_link, is_hidden };
}
};
inline files get_files_struct(const std::filesystem::path& path)
{
files f;
try
{
std::filesystem::directory_iterator start(path);
std::filesystem::directory_iterator end;
std::transform(start, end, std::back_inserter(f), filesystem_convert());
}
catch(...)
{
f.push_back({ path / "no permission", file_type::NONE, false, false });
}
return f;
}
// не нужно тут передавать pwd, как ссылку
// т.к. один фиг копирование в content::fill произойдет из-за
// parent_path() метода, которым мы пользуемся при передачи сюда параметра
// НО пока эта информация уже устарела, т.к. много в коде изменилось
// по этому потом поэкспериментируй с запусками эстов конечно же
// т.е. передай по ссылке и посмотри на поведение
inline files fill(std::filesystem::path pwd)
{
files current_files = get_files_struct(pwd);
if (current_files.size() == 1 && current_files.at(0).path == pwd / "no permission")
{
return current_files;
}
files tmp;
tmp.reserve(current_files.size());
std::sort(current_files.begin(), current_files.end());
files tmp_files;
tmp_files.reserve(current_files.size());
std::copy_if(current_files.begin(), current_files.end(), std::back_inserter(tmp), [](const file& f) -> bool {
if (f.type == file_type::DIR) return true;
return false;
});
std::copy_if(current_files.begin(), current_files.end(), std::back_inserter(tmp_files), [](const file& f) -> bool {
if (f.type != file_type::DIR) return true;
return false;
});
tmp.insert(tmp.end(), tmp_files.begin(), tmp_files.end());
return tmp;
}
}