Skip to content

Commit

Permalink
karm-app: Simple user preference api.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Dec 22, 2024
1 parent 71a5e83 commit d685eec
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 3 deletions.
17 changes: 17 additions & 0 deletions src/impls/impl-efi/app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@


#include <karm-app/prefs.h>

#include <karm-app/_embed.h>

namespace Karm::App::_Ember {

static Opt<MockPrefs> _globalPrefs;

Prefs &globalPrefs() {
if (not _globalPrefs)
_globalPrefs = MockPrefs{};
return *_globalPrefs;
}

} // namespace Karm::App::_Ember
69 changes: 69 additions & 0 deletions src/impls/impl-posix/app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <karm-app/prefs.h>
#include <karm-json/parse.h>
#include <karm-logger/logger.h>
#include <karm-mime/url.h>
#include <karm-sys/dir.h>
#include <karm-sys/file.h>

#include <karm-app/_embed.h>
#include <karm-pkg/_embed.h>

namespace Karm::App::_Ember {

struct XdgConfigPrefs : public Prefs {
Mime::Url _url;

XdgConfigPrefs(Mime::Url url)
: _url{std::move(url)} {}

Json::Value _load() {
auto data = Sys::readAllUtf8(_url).unwrapOr("{}"s);
Io::SScan s{data};
return Json::parse(s).unwrapOr(Json::Object{});
}

Res<> _save(Json::Value object) {
auto file = try$(Sys::File::create(_url));
Io::TextEncoder<> enc{file};
Io::Emit e{enc};
return Json::stringify(e, object);
}

Async::Task<Json::Value> loadAsync(String key, Json::Value defaultValue) {
auto object = _load();
auto value = object.get(key);
co_return Ok(value == NONE ? defaultValue : value);
}

Async::Task<> saveAsync(String key, Json::Value value) {
auto object = _load();
object.set(key, value);
co_return _save(object);
}
};

static Opt<XdgConfigPrefs> _globalPrefs;

static Res<Mime::Url> _resolveConfigDir() {
auto *xdgConfigHome = getenv("XDG_CONFIG_HOME");
if (xdgConfigHome)
return Ok(Mime::Url::parse(xdgConfigHome) / try$(Pkg::_Embed::currentBundle()));

auto *home = getenv("HOME");
if (home)
return Ok(Mime::Url::parse(home) / ".config" / try$(Pkg::_Embed::currentBundle()));

return Error::notFound("could not find XDG_CONFIG_HOME nor HOME");
}

Prefs &globalPrefs() {
if (not _globalPrefs) {
auto url = _resolveConfigDir().unwrap("could not resolve preferences directory");
Sys::Dir::openOrCreate(url).unwrap("could not create preferences directory");
logInfo("preferences stored at {}", url);
_globalPrefs = XdgConfigPrefs{url / "configs.json"};
}
return *_globalPrefs;
}

} // namespace Karm::App::_Ember
17 changes: 17 additions & 0 deletions src/impls/impl-skift/app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@


#include <karm-app/prefs.h>

#include <karm-app/_embed.h>

namespace Karm::App::_Ember {

static Opt<MockPrefs> _globalPrefs;

Prefs &globalPrefs() {
if (not _globalPrefs)
_globalPrefs = MockPrefs{};
return *_globalPrefs;
}

} // namespace Karm::App::_Ember
17 changes: 17 additions & 0 deletions src/impls/impl-wasm/app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@


#include <karm-app/prefs.h>

#include <karm-app/_embed.h>

namespace Karm::App::_Ember {

static Opt<MockPrefs> _globalPrefs;

Prefs &globalPrefs() {
if (not _globalPrefs)
_globalPrefs = MockPrefs{};
return *_globalPrefs;
}

} // namespace Karm::App::_Ember
13 changes: 13 additions & 0 deletions src/libs/karm-app/_embed.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

namespace Karm::App {

struct Prefs;

} // namespace Karm::App

namespace Karm::App::_Embed {

Prefs &globalPrefs();

} // namespace Karm::App::_Embed
23 changes: 23 additions & 0 deletions src/libs/karm-app/prefs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "prefs.h"

#include "_embed.h"

namespace Karm::App {

Async::Task<Json::Value> MockPrefs::loadAsync(String key, Json::Value defaultValue) {
auto item = _store.access(key);
if (item)
co_return *item;
co_return defaultValue;
}

Async::Task<> MockPrefs::saveAsync(String key, Json::Value value) {
_store.put(key, value);
co_return Ok();
}

Prefs &globalPrefs() {
return _Embed::globalPrefs();
}

} // namespace Karm::App
26 changes: 26 additions & 0 deletions src/libs/karm-app/prefs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <karm-base/async.h>
#include <karm-json/values.h>

namespace Karm::App {

struct Prefs {
virtual ~Prefs() = default;

virtual Async::Task<Json::Value> loadAsync(String key, Json::Value defaultValue = NONE) = 0;

virtual Async::Task<> saveAsync(String key, Json::Value value) = 0;
};

struct MockPrefs : public Prefs {
Json::Object _store;

Async::Task<Json::Value> loadAsync(String key, Json::Value defaultValue) override;

Async::Task<> saveAsync(String key, Json::Value value) override;
};

Prefs &globalPrefs();

} // namespace Karm::App
1 change: 0 additions & 1 deletion src/libs/karm-base/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ struct None {
explicit operator bool() const { return false; }

bool operator==(None const &) const = default;

auto operator<=>(None const &) const = default;
};

Expand Down
14 changes: 12 additions & 2 deletions src/libs/karm-json/values.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,8 @@ struct Value {
}

Value get(Str key) const {
if (not isObject()) {
if (not isObject())
return NONE;
}
return try$(asObject().tryGet(key));
}

Expand All @@ -262,6 +261,12 @@ struct Value {
return asArray()[index];
}

void set(Str key, Value value) {
if (not isObject())
return;
asObject().put(key, value);
}

usize len() const {
return _store.visit(
Visitor{
Expand Down Expand Up @@ -306,6 +311,11 @@ struct Value {
Opt<T> take() const {
return _store.take<T>();
}

template <Meta::Equatable<_Store> T>
bool operator==(T const &other) const {
return _store == other;
}
};

Res<> stringify(Io::Emit &emit, Value const &v);
Expand Down
4 changes: 4 additions & 0 deletions src/libs/karm-sys/dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ struct Dir {

static Res<Dir> open(Mime::Url url);

static Res<Dir> create(Mime::Url url);

static Res<Dir> openOrCreate(Mime::Url url);

auto const &entries() const { return _entries; }

auto const &path() const { return _url; }
Expand Down

0 comments on commit d685eec

Please sign in to comment.