feat: initialize Nocal terminal calendar

This commit is contained in:
2026-07-17 21:24:06 +01:00
commit 22c6399056
37 changed files with 6146 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
#pragma once
#include "nocal/domain/event.hpp"
#include <filesystem>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <vector>
namespace nocal::storage {
class FileRevision {
public:
FileRevision() = default;
[[nodiscard]] bool existed() const noexcept { return existed_; }
[[nodiscard]] std::size_t size() const noexcept {
return contents_ ? contents_->size() : 0;
}
private:
bool existed_ = false;
std::shared_ptr<const std::string> contents_;
friend class IcsStore;
};
struct LoadResult {
std::vector<Event> events;
std::vector<std::string> warnings;
// False when saving the parsed events would discard source data that this
// version of nocal cannot represent faithfully.
bool safe_to_rewrite = true;
// Exact bytes that produced this result. Copies share immutable storage and
// can be supplied to save/restore as an optimistic concurrency token.
FileRevision revision;
};
class IcsStore {
public:
[[nodiscard]] static LoadResult load(const std::filesystem::path& path);
[[nodiscard]] static std::filesystem::path backup_path(
const std::filesystem::path& path);
// Writes a complete VCALENDAR. On POSIX systems replacement is atomic and
// requests durable filesystem flushes. I/O failures before replacement are
// reported as std::runtime_error. If expected is present, the destination
// must still contain the exact bytes represented by that revision.
static FileRevision save(
const std::filesystem::path& path, std::span<const Event> events,
std::optional<FileRevision> expected = std::nullopt);
// Restores the exact bytes in <path>.bak without changing the backup.
static FileRevision restore_backup(
const std::filesystem::path& path,
std::optional<FileRevision> expected = std::nullopt);
};
} // namespace nocal::storage