mirror of
https://codeberg.org/vyn/mirai.git
synced 2025-07-02 01:13:19 +00:00
Add helper lib for strings and vectors
This commit is contained in:
parent
6ef9740db9
commit
2bb7fcfcc6
10 changed files with 168 additions and 123 deletions
|
@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD 20)
|
|||
find_package(Qt6 6.6 REQUIRED COMPONENTS Quick)
|
||||
|
||||
include_directories(src)
|
||||
include_directories(libs)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.6)
|
||||
|
||||
|
|
27
libs/cpp-utils/string.h
Normal file
27
libs/cpp-utils/string.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Mirai. Copyright (C) 2024 Vyn
|
||||
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
|
||||
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
*/
|
||||
|
||||
#ifndef CPP_UTILS_STRING_H
|
||||
#define CPP_UTILS_STRING_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace cpputils::string {
|
||||
|
||||
inline std::string trim(std::string str) {
|
||||
str.erase(str.begin(), std::ranges::find_if(str, [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
str.erase(std::ranges::find_if(str.rbegin(), str.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), str.end());
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
44
libs/cpp-utils/vector.h
Normal file
44
libs/cpp-utils/vector.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Mirai. Copyright (C) 2024 Vyn
|
||||
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
|
||||
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
*/
|
||||
|
||||
#ifndef CPP_UTILS_VECTOR_H
|
||||
#define CPP_UTILS_VECTOR_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <concepts>
|
||||
|
||||
namespace cpputils::vector {
|
||||
|
||||
template <typename C, typename T>
|
||||
concept AnyIterable =
|
||||
std::same_as<typename C::value_type, T> &&
|
||||
requires (C c) {
|
||||
{ c.begin() } -> std::forward_iterator;
|
||||
{ c.end() } -> std::forward_iterator;
|
||||
{ const_cast<const C&>(c).begin() } -> std::forward_iterator;
|
||||
{ const_cast<const C&>(c).end() } -> std::forward_iterator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool contains(const std::vector<T>& vec, const T& value) {
|
||||
return std::ranges::find(vec, value) != vec.end();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool containsAll(const std::vector<T>& vec, const AnyIterable<T> auto vec2) {
|
||||
for (auto& elem : vec) {
|
||||
if (!contains(vec2, elem)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "Mirai.h"
|
||||
#include "TaskItem.h"
|
||||
#include <algorithm>
|
||||
#include "cpp-utils/vector.h"
|
||||
|
||||
namespace mirai {
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace mirai {
|
|||
tags.clear();
|
||||
for (auto& task : (*files)[0].getTasks()) {
|
||||
for (auto& tag : task->getTags()) {
|
||||
if (std::find(tags.begin(), tags.end(), tag) == tags.end()) {
|
||||
if (vectorUtils::contains(tags, tag)) {
|
||||
tags.push_back(tag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
|
||||
#include "TaskItem.h"
|
||||
#include <algorithm>
|
||||
#include "cpp-utils/vector.h"
|
||||
|
||||
namespace mirai {
|
||||
|
||||
|
@ -36,6 +36,6 @@ namespace mirai {
|
|||
|
||||
|
||||
bool TaskItem::hasTag(const std::string& tag) const {
|
||||
return std::find(tags.begin(), tags.end(), tag) != tags.end();
|
||||
return vectorUtils::contains(tags, tag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
#include "TasksView.h"
|
||||
#include "cpp-utils/vector.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace mirai {
|
||||
|
||||
|
@ -23,10 +26,10 @@ namespace mirai {
|
|||
tasksToShow.clear();
|
||||
for (auto& file : *files) {
|
||||
for (auto& task : file.getTasks()) {
|
||||
if (tagsFilter.size() != 0
|
||||
&& std::find_if(tagsFilter.begin(), tagsFilter.end(), [&](const std::string& tag) {
|
||||
std::function<bool(const std::string&)> f = [&](const std::string& tag) {
|
||||
return task->hasTag(tag);
|
||||
}) == tagsFilter.end())
|
||||
};
|
||||
if (tagsFilter.size() > 0 && !vectorUtils::containsAll(tagsFilter, task->getTags()))
|
||||
continue;
|
||||
tasksToShow.push_back(task.get());
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "TodoMd.h"
|
||||
#include "TaskItem.h"
|
||||
#include "cpp-utils/vector.h"
|
||||
|
||||
namespace mirai {
|
||||
|
||||
|
@ -50,7 +51,7 @@ namespace mirai {
|
|||
|
||||
while (std::regex_search(metadata, matches, regex))
|
||||
{
|
||||
if (std::find(tags.begin(), tags.end(), matches[0]) == tags.end()) {
|
||||
if (!vectorUtils::contains(tags, matches[0].str())) {
|
||||
tags.push_back(matches[0]);
|
||||
}
|
||||
metadata = matches.suffix();
|
||||
|
@ -97,8 +98,7 @@ namespace mirai {
|
|||
/*std::cout << "M 6 " << matches[6] << std::endl;*/
|
||||
/*std::cout << "M 7 " << matches[7] << std::endl;*/
|
||||
|
||||
std::string text = matches[5];
|
||||
trim(text);
|
||||
std::string text = stringUtils::trim(matches[5]);
|
||||
|
||||
TaskItem taskItem = {
|
||||
.text = text,
|
||||
|
|
|
@ -7,89 +7,89 @@
|
|||
#ifndef MIRAI_TODOTXT_H
|
||||
#define MIRAI_TODOTXT_H
|
||||
|
||||
#include "TaskItem.h"
|
||||
#include "utils.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
/*#include "TaskItem.h"*/
|
||||
/*#include "utils.h"*/
|
||||
/*#include <fstream>*/
|
||||
/*#include <iostream>*/
|
||||
/*#include <iterator>*/
|
||||
/*#include <memory>*/
|
||||
/*#include <regex>*/
|
||||
/*#include <stdexcept>*/
|
||||
/*#include <string>*/
|
||||
/*#include <vector>*/
|
||||
|
||||
namespace mirai {
|
||||
/*namespace mirai {*/
|
||||
|
||||
class TodoTxtFormat {
|
||||
public:
|
||||
/*class TodoTxtFormat {*/
|
||||
/*public:*/
|
||||
|
||||
static TaskList readFile() {
|
||||
std::ifstream file("../newqml/todo.txt");
|
||||
if (!file.is_open()) {
|
||||
throw std::runtime_error("todo.txt file not found");
|
||||
}
|
||||
std::vector<TaskItem> taskItems;
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
auto taskItem = parseLine(line);
|
||||
taskItems.push_back(taskItem);
|
||||
}
|
||||
file.close();
|
||||
TaskList tasks({
|
||||
.tasks = taskItems
|
||||
});
|
||||
return tasks;
|
||||
}
|
||||
/*static TaskList readFile() {*/
|
||||
/*std::ifstream file("../newqml/todo.txt");*/
|
||||
/*if (!file.is_open()) {*/
|
||||
/*throw std::runtime_error("todo.txt file not found");*/
|
||||
/*}*/
|
||||
/*std::vector<TaskItem> taskItems;*/
|
||||
/*std::string line;*/
|
||||
/*while (std::getline(file, line)) {*/
|
||||
/*auto taskItem = parseLine(line);*/
|
||||
/*taskItems.push_back(taskItem);*/
|
||||
/*}*/
|
||||
/*file.close();*/
|
||||
/*TaskList tasks({*/
|
||||
/*.tasks = taskItems*/
|
||||
/*});*/
|
||||
/*return tasks;*/
|
||||
/*}*/
|
||||
|
||||
static void writeFile(TaskList& tasks) {
|
||||
std::ofstream file("../newqml/todo.txt");
|
||||
if (!file.is_open()) {
|
||||
throw std::runtime_error("can't create todo.txt");
|
||||
}
|
||||
for (const auto& task : tasks.getTasks()) {
|
||||
file << fieldWithSpace(task->state == DONE ? "x" : task->priority);
|
||||
file << fieldWithSpace(task->state == DONE ? task->getDate() : "");
|
||||
file << fieldWithSpace(task->getCreationDate());
|
||||
file << task->getText() << '\n';
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
/*static void writeFile(TaskList& tasks) {*/
|
||||
/*std::ofstream file("../newqml/todo.txt");*/
|
||||
/*if (!file.is_open()) {*/
|
||||
/*throw std::runtime_error("can't create todo.txt");*/
|
||||
/*}*/
|
||||
/*for (const auto& task : tasks.getTasks()) {*/
|
||||
/*file << fieldWithSpace(task->state == DONE ? "x" : task->priority);*/
|
||||
/*file << fieldWithSpace(task->state == DONE ? task->getDate() : "");*/
|
||||
/*file << fieldWithSpace(task->getCreationDate());*/
|
||||
/*file << task->getText() << '\n';*/
|
||||
/*}*/
|
||||
/*file.close();*/
|
||||
/*}*/
|
||||
|
||||
private:
|
||||
/*private:*/
|
||||
|
||||
static std::string fieldWithSpace(const std::string& field) {
|
||||
if (field.length() == 0)
|
||||
return "";
|
||||
return (field + " ");
|
||||
}
|
||||
/*static std::string fieldWithSpace(const std::string& field) {*/
|
||||
/*if (field.length() == 0)*/
|
||||
/*return "";*/
|
||||
/*return (field + " ");*/
|
||||
/*}*/
|
||||
|
||||
static TaskItem parseLine(const std::string& line) {
|
||||
std::smatch matches;
|
||||
std::regex regex("(^x )?(\\([A-Z]\\) )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?(.*)");
|
||||
std::regex_match(line, matches, regex);
|
||||
/*static TaskItem parseLine(const std::string& line) {*/
|
||||
/*std::smatch matches;*/
|
||||
/*std::regex regex("(^x )?(\\([A-Z]\\) )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?([0-9]{4}-[0-9]{2}-[0-9]{2} )?(.*)");*/
|
||||
/*std::regex_match(line, matches, regex);*/
|
||||
|
||||
for (size_t i = 0; i < matches.size(); ++i) {
|
||||
std::ssub_match sub_match = matches[i];
|
||||
std::string piece = sub_match.str();
|
||||
}
|
||||
/*for (size_t i = 0; i < matches.size(); ++i) {*/
|
||||
/*std::ssub_match sub_match = matches[i];*/
|
||||
/*std::string piece = sub_match.str();*/
|
||||
/*}*/
|
||||
|
||||
const TaskItemState taskState = trim_copy(matches[1].str()) == "x" ? DONE : TODO;
|
||||
const std::string priority = trim_copy(matches[2].str());
|
||||
const std::string firstDate = trim_copy(matches[3].str());
|
||||
const std::string secondDate = trim_copy(matches[4].str());
|
||||
const std::string text = trim_copy(matches[5].str());
|
||||
/*const TaskItemState taskState = trim_copy(matches[1].str()) == "x" ? DONE : TODO;*/
|
||||
/*const std::string priority = trim_copy(matches[2].str());*/
|
||||
/*const std::string firstDate = trim_copy(matches[3].str());*/
|
||||
/*const std::string secondDate = trim_copy(matches[4].str());*/
|
||||
/*const std::string text = trim_copy(matches[5].str());*/
|
||||
|
||||
const std::string date = taskState == DONE ? firstDate : "";
|
||||
/*const std::string date = taskState == DONE ? firstDate : "";*/
|
||||
|
||||
|
||||
|
||||
return {
|
||||
.text = text,
|
||||
.state = taskState,
|
||||
.date = date,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
/*return {*/
|
||||
/*.text = text,*/
|
||||
/*.state = taskState,*/
|
||||
/*.date = date,*/
|
||||
/*};*/
|
||||
/*}*/
|
||||
/*};*/
|
||||
/*}*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,39 +6,9 @@
|
|||
|
||||
#include "utils.h"
|
||||
|
||||
void ltrim(std::string& s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
}
|
||||
|
||||
void rtrim(std::string& s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
}
|
||||
|
||||
void trim(std::string& s) {
|
||||
rtrim(s);
|
||||
ltrim(s);
|
||||
}
|
||||
|
||||
std::string ltrim_copy(std::string s) {
|
||||
ltrim(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string rtrim_copy(std::string s) {
|
||||
rtrim(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string trim_copy(std::string s) {
|
||||
trim(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
namespace mirai {
|
||||
bool isDate(const std::string& dateStr) {
|
||||
std::regex regex("[0-9]{4}-[0-9]{2}-[0-9]{2}");
|
||||
return std::regex_match(dateStr, regex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,15 +11,15 @@
|
|||
#include <cctype>
|
||||
#include <locale>
|
||||
#include <regex>
|
||||
#include <cpp-utils/string.h>
|
||||
#include <cpp-utils/vector.h>
|
||||
|
||||
void ltrim(std::string& s);
|
||||
void rtrim(std::string& s);
|
||||
void trim(std::string& s);
|
||||
|
||||
std::string ltrim_copy(std::string s);
|
||||
std::string rtrim_copy(std::string s);
|
||||
std::string trim_copy(std::string s);
|
||||
namespace mirai {
|
||||
namespace stringUtils = cpputils::string;
|
||||
namespace vectorUtils = cpputils::vector;
|
||||
|
||||
bool isDate(const std::string& dateStr);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue