From 4d1e69bbe5ceabbd536f006a3def1e79e00894ba Mon Sep 17 00:00:00 2001 From: Mars Date: Sun, 9 Jun 2024 20:14:51 -0400 Subject: [PATCH] :3 --- include/util/result.h | 24 ++++--- src/config/config.cpp | 31 +++++---- src/config/config.h | 153 +++++++++++++++++++++-------------------- src/config/weather.cpp | 45 +++++++----- src/main.cpp | 7 +- src/os/macos.cpp | 6 +- src/os/macos/bridge.h | 8 ++- src/os/macos/bridge.mm | 26 ++++--- 8 files changed, 167 insertions(+), 133 deletions(-) diff --git a/include/util/result.h b/include/util/result.h index 7586b74..8975aa7 100644 --- a/include/util/result.h +++ b/include/util/result.h @@ -5,11 +5,13 @@ #include #include +#include "util/numtypes.h" + // Define an error type class Error { public: explicit Error(std::string message) : m_Message(std::move(message)) {} - [[nodiscard]] const std::string& message() const { return m_Message; } + [[nodiscard]] fn message() const -> const std::string& { return m_Message; } private: std::string m_Message; @@ -29,10 +31,10 @@ class Result { Result(Error&& error) : m_Result(std::move(error)) {} // Check if the result is an error - [[nodiscard]] bool isOk() const { + [[nodiscard]] fn isOk() const -> bool { return std::holds_alternative(m_Result); } - [[nodiscard]] bool isErr() const { + [[nodiscard]] fn isErr() const -> bool { return std::holds_alternative(m_Result); } @@ -44,7 +46,7 @@ class Result { } // Get the error or throw an exception if it is a value - [[nodiscard]] const Error& error() const { + [[nodiscard]] fn error() const -> const Error& { if (isOk()) { throw std::logic_error("Attempted to access error of an ok Result"); } @@ -66,15 +68,15 @@ class Result { Result(Error&& error) : m_Result(std::move(error)) {} // Check if the result is an error - [[nodiscard]] bool isOk() const { + [[nodiscard]] fn isOk() const -> bool { return std::holds_alternative(m_Result); } - [[nodiscard]] bool isErr() const { + [[nodiscard]] fn isErr() const -> bool { return std::holds_alternative(m_Result); } // Get the value or throw an exception if it is an error - const T& value() const { + fn value() const -> const T& { if (isErr()) { throw std::logic_error("Attempted to access value of an error Result"); } @@ -82,7 +84,7 @@ class Result { } // Get the error or throw an exception if it is a value - [[nodiscard]] const Error& error() const { + [[nodiscard]] fn error() const -> const Error& { if (isOk()) { throw std::logic_error("Attempted to access error of an ok Result"); } @@ -90,7 +92,7 @@ class Result { } // Optional: Get the value or provide a default - T valueOr(const T& defaultValue) const { + fn valueOr(const T& defaultValue) const -> T { return isOk() ? std::get(m_Result) : defaultValue; } @@ -99,8 +101,8 @@ class Result { }; template -auto Ok(T&& value) { +fn Ok(T&& value) { return Result>(std::forward(value)); } -inline auto Ok() { return Result(); } +inline fn Ok() -> Result { return {}; } diff --git a/src/config/config.cpp b/src/config/config.cpp index 4af1f30..325cc8d 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -1,7 +1,7 @@ #include "config.h" #define DEFINE_GETTER(class_name, type, name) \ - type class_name::get##name() const { return m_##name; } + fn class_name::get##name() const->type { return m_##name; } DEFINE_GETTER(Config, const General, General) DEFINE_GETTER(Config, const NowPlaying, NowPlaying) @@ -12,7 +12,7 @@ DEFINE_GETTER(Weather, const Weather::Location, Location) DEFINE_GETTER(Weather, const std::string, ApiKey) DEFINE_GETTER(Weather, const std::string, Units) -const Config& Config::getInstance() { +fn Config::getInstance() -> const Config& { static const auto* INSTANCE = new Config(rfl::toml::load("./config.toml").value()); return *INSTANCE; @@ -25,14 +25,14 @@ Config::Config(General general, NowPlaying now_playing, Weather weather) General::General(std::string name) : m_Name(std::move(name)) {} -NowPlaying::NowPlaying(bool enable) : m_Enabled(enable) {} +NowPlaying::NowPlaying(bool enabled) : m_Enabled(enabled) {} Weather::Weather(Location location, std::string api_key, std::string units) : m_Location(std::move(location)), m_ApiKey(std::move(api_key)), m_Units(std::move(units)) {} -WeatherImpl WeatherImpl::from_class(const Weather& weather) noexcept { +fn WeatherImpl::from_class(const Weather& weather) noexcept -> WeatherImpl { return { .location = weather.getLocation(), .api_key = weather.getApiKey(), @@ -40,22 +40,27 @@ WeatherImpl WeatherImpl::from_class(const Weather& weather) noexcept { }; } -Weather WeatherImpl::to_class() const { return {location, api_key, units}; } +fn WeatherImpl::to_class() const -> Weather { + return {location, api_key, units}; +} -GeneralImpl GeneralImpl::from_class(const General& general) noexcept { +fn GeneralImpl::from_class(const General& general) noexcept -> GeneralImpl { return {general.getName()}; } -General GeneralImpl::to_class() const { return {name}; } +fn GeneralImpl::to_class() const -> General { return {name}; } -NowPlayingImpl NowPlayingImpl::from_class( - const NowPlaying& now_playing) noexcept { +// clang-format off +fn NowPlayingImpl::from_class( + const NowPlaying& now_playing +) noexcept -> NowPlayingImpl { return {.enabled = now_playing.getEnabled()}; } +//clang-format on -NowPlaying NowPlayingImpl::to_class() const { return {enabled}; } +fn NowPlayingImpl::to_class() const -> NowPlaying { return {enabled}; } -ConfigImpl ConfigImpl::from_class(const Config& config) noexcept { +fn ConfigImpl::from_class(const Config& config) noexcept -> ConfigImpl { return { .general = config.getGeneral(), .now_playing = config.getNowPlaying(), @@ -63,4 +68,6 @@ ConfigImpl ConfigImpl::from_class(const Config& config) noexcept { }; } -Config ConfigImpl::to_class() const { return {general, now_playing, weather}; } +fn ConfigImpl::to_class() const -> Config { + return {general, now_playing, weather}; +} diff --git a/src/config/config.h b/src/config/config.h index f8adea9..998838f 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -10,30 +10,30 @@ class Weather { public: - using percentage = rfl::Validator, rfl::Maximum<100>>; using degrees = rfl::Validator, rfl::Maximum<360>>; + using percentage = rfl::Validator, rfl::Maximum<100>>; struct Condition { - usize id; - rfl::Rename<"main", std::string> group; std::string description; - rfl::Rename<"icon", std::string> icon_id; + std::string icon; + std::string main; + usize id; }; struct Main { - f64 temp; - f64 temp_max; - f64 temp_min; - f64 feels_like; - isize pressure; - std::optional sea_level; + f64 feels_like; + f64 temp; + f64 temp_max; + f64 temp_min; + isize pressure; + percentage humidity; std::optional grnd_level; - percentage humidity; + std::optional sea_level; }; struct Wind { - f64 speed; - degrees deg; + degrees deg; + f64 speed; std::optional gust; }; @@ -44,10 +44,10 @@ class Weather { struct Sys { std::string country; - usize id; - usize sunrise; - usize sunset; - usize type; + usize id; + usize sunrise; + usize sunset; + usize type; }; struct Clouds { @@ -60,47 +60,47 @@ class Weather { }; struct WeatherOutput { - isize timezone; - isize visibility; - Main main; - Clouds clouds; + Clouds clouds; + Main main; + Sys sys; + Wind wind; + isize timezone; + isize visibility; rfl::Rename<"coord", Coords> coords; std::optional rain; std::optional snow; - std::vector weather; - std::string base; - std::string name; - Sys sys; - usize cod; - usize dt; - usize id; - Wind wind; + std::string base; + std::string name; + std::vector weather; + usize cod; + usize dt; + usize id; }; using Location = std::variant; private: - Location m_Location; + Location m_Location; std::string m_ApiKey; std::string m_Units; public: Weather(Location location, std::string api_key, std::string units); - [[nodiscard]] WeatherOutput getWeatherInfo() const; - [[nodiscard]] const Location getLocation() const; - [[nodiscard]] const std::string getApiKey() const; - [[nodiscard]] const std::string getUnits() const; + [[nodiscard]] fn getWeatherInfo() const -> WeatherOutput; + [[nodiscard]] fn getLocation() const -> const Location; + [[nodiscard]] fn getApiKey() const -> const std::string; + [[nodiscard]] fn getUnits() const -> const std::string; }; struct WeatherImpl { Weather::Location location; - std::string api_key; - std::string units; + std::string api_key; + std::string units; - static WeatherImpl from_class(const Weather& weather) noexcept; + static fn from_class(const Weather& weather) noexcept -> WeatherImpl; - [[nodiscard]] Weather to_class() const; + [[nodiscard]] fn to_class() const -> Weather; }; class General { @@ -110,15 +110,15 @@ class General { public: General(std::string name); - [[nodiscard]] const std::string getName() const; + [[nodiscard]] fn getName() const -> const std::string; }; struct GeneralImpl { std::string name; - static GeneralImpl from_class(const General& general) noexcept; + static fn from_class(const General& general) noexcept -> GeneralImpl; - [[nodiscard]] General to_class() const; + [[nodiscard]] fn to_class() const -> General; }; class NowPlaying { @@ -128,74 +128,79 @@ class NowPlaying { public: NowPlaying(bool enabled); - [[nodiscard]] bool getEnabled() const; + [[nodiscard]] fn getEnabled() const -> bool; }; struct NowPlayingImpl { bool enabled; - static NowPlayingImpl from_class(const NowPlaying& now_playing) noexcept; + static fn from_class(const NowPlaying& now_playing + ) noexcept -> NowPlayingImpl; - [[nodiscard]] NowPlaying to_class() const; + [[nodiscard]] fn to_class() const -> NowPlaying; }; class Config { private: - General m_General; + General m_General; NowPlaying m_NowPlaying; - Weather m_Weather; + Weather m_Weather; public: Config(General general, NowPlaying now_playing, Weather weather); - static const Config& getInstance(); + static fn getInstance() -> const Config&; - [[nodiscard]] const Weather getWeather() const; - [[nodiscard]] const General getGeneral() const; - [[nodiscard]] const NowPlaying getNowPlaying() const; + [[nodiscard]] fn getWeather() const -> const Weather; + [[nodiscard]] fn getGeneral() const -> const General; + [[nodiscard]] fn getNowPlaying() const -> const NowPlaying; }; struct ConfigImpl { - General general; + General general; NowPlaying now_playing; - Weather weather; + Weather weather; - static ConfigImpl from_class(const Config& config) noexcept; + static fn from_class(const Config& config) noexcept -> ConfigImpl; - [[nodiscard]] Config to_class() const; + [[nodiscard]] fn to_class() const -> Config; }; // Parsers for Config classes namespace rfl::parsing { template struct Parser - : public CustomParser {}; + : public CustomParser< + ReaderType, + WriterType, + ProcessorsType, + Weather, + WeatherImpl> {}; template struct Parser - : public CustomParser {}; + : public CustomParser< + ReaderType, + WriterType, + ProcessorsType, + General, + GeneralImpl> {}; template struct Parser - : public CustomParser {}; + : public CustomParser< + ReaderType, + WriterType, + ProcessorsType, + NowPlaying, + NowPlayingImpl> {}; template struct Parser - : public CustomParser {}; + : public CustomParser< + ReaderType, + WriterType, + ProcessorsType, + Config, + ConfigImpl> {}; } // namespace rfl::parsing diff --git a/src/config/weather.cpp b/src/config/weather.cpp index 879cd9d..7ba6770 100644 --- a/src/config/weather.cpp +++ b/src/config/weather.cpp @@ -8,11 +8,12 @@ using WeatherOutput = Weather::WeatherOutput; // Function to read cache from file -Result ReadCacheFromFile() { +fn ReadCacheFromFile() -> Result { const std::string cacheFile = "/tmp/weather_cache.json"; - std::ifstream ifs(cacheFile); + std::ifstream ifs(cacheFile); - if (!ifs.is_open()) return Error("Cache file not found."); + if (!ifs.is_open()) + return Error("Cache file not found."); fmt::println("Reading from cache file..."); @@ -32,12 +33,13 @@ Result ReadCacheFromFile() { } // Function to write cache to file -Result<> WriteCacheToFile(const WeatherOutput& data) { +fn WriteCacheToFile(const WeatherOutput& data) -> Result<> { const std::string cacheFile = "/tmp/weather_cache.json"; fmt::println("Writing to cache file..."); std::ofstream ofs(cacheFile); - if (!ofs.is_open()) return Error("Failed to open cache file for writing."); + if (!ofs.is_open()) + return Error("Failed to open cache file for writing."); ofs << rfl::json::write(data); @@ -46,10 +48,8 @@ Result<> WriteCacheToFile(const WeatherOutput& data) { return Ok(); } -size_t WriteCallback(void* contents, - size_t size, - size_t nmemb, - std::string* buffer) { +fn WriteCallback(void* contents, size_t size, size_t nmemb, std::string* buffer) + -> size_t { size_t realsize = size * nmemb; buffer->append(static_cast(contents), realsize); @@ -58,7 +58,7 @@ size_t WriteCallback(void* contents, } // Function to make API request -Result MakeApiRequest(const std::string& url) { +fn MakeApiRequest(const std::string& url) -> Result { fmt::println("Making API request..."); CURL* curl = curl_easy_init(); @@ -73,8 +73,9 @@ Result MakeApiRequest(const std::string& url) { curl_easy_cleanup(curl); if (res != CURLE_OK) - return Error(fmt::format("Failed to perform cURL request: {}", - curl_easy_strerror(res))); + return Error(fmt::format( + "Failed to perform cURL request: {}", curl_easy_strerror(res) + )); fmt::println("Received response from API."); // Parse the JSON response @@ -88,10 +89,10 @@ Result MakeApiRequest(const std::string& url) { } // Core function to get weather information -WeatherOutput Weather::getWeatherInfo() const { +fn Weather::getWeatherInfo() const -> WeatherOutput { using namespace std::chrono; - const Location loc = m_Location; + const Location loc = m_Location; const std::string apiKey = m_ApiKey; const std::string units = m_Units; @@ -116,15 +117,19 @@ WeatherOutput Weather::getWeatherInfo() const { if (holds_alternative(loc)) { const std::string city = get(loc); - const char* location = curl_easy_escape(nullptr, city.c_str(), - static_cast(city.length())); + const char* location = curl_easy_escape( + nullptr, city.c_str(), static_cast(city.length()) + ); fmt::println("City: {}", location); const std::string apiUrl = fmt::format( "https://api.openweathermap.org/data/2.5/" "weather?q={}&appid={}&units={}", - location, apiKey, units); + location, + apiKey, + units + ); result = MakeApiRequest(apiUrl).value(); } else { @@ -135,7 +140,11 @@ WeatherOutput Weather::getWeatherInfo() const { const std::string apiUrl = fmt::format( "https://api.openweathermap.org/data/2.5/" "weather?lat={:.3f}&lon={:.3f}&appid={}&units={}", - lat, lon, apiKey, units); + lat, + lon, + apiKey, + units + ); result = MakeApiRequest(apiUrl).value(); } diff --git a/src/main.cpp b/src/main.cpp index 120c331..28a7e19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,13 +11,14 @@ struct BytesToGiB { u64 value; }; +constexpr u64 GIB = 1'073'741'824; + template <> struct fmt::formatter : formatter { template fn format(const BytesToGiB BTG, FmtCtx& ctx) -> typename FmtCtx::iterator { - typename FmtCtx::iterator out = formatter::format( - static_cast(BTG.value) / pow(1024, 3), ctx - ); + typename FmtCtx::iterator out = + formatter::format(static_cast(BTG.value) / GIB, ctx); *out++ = 'G'; *out++ = 'i'; *out++ = 'B'; diff --git a/src/os/macos.cpp b/src/os/macos.cpp index c395a33..b1ae63a 100644 --- a/src/os/macos.cpp +++ b/src/os/macos.cpp @@ -5,7 +5,7 @@ #include "macos/bridge.h" #include "os.h" -u64 GetMemInfo() { +fn GetMemInfo() -> u64 { u64 mem = 0; usize size = sizeof(mem); @@ -14,7 +14,7 @@ u64 GetMemInfo() { return mem; } -std::string GetNowPlaying() { +fn GetNowPlaying() -> std::string { if (const char* title = GetCurrentPlayingTitle(); const char* artist = GetCurrentPlayingArtist()) return "Now Playing: " + std::string(artist) + " - " + std::string(title); @@ -22,6 +22,6 @@ std::string GetNowPlaying() { return "No song playing"; } -const char* GetOSVersion() { return GetMacOSVersion(); }; +fn GetOSVersion() -> const char* { return GetMacOSVersion(); }; #endif diff --git a/src/os/macos/bridge.h b/src/os/macos/bridge.h index 5bc3791..c151d80 100644 --- a/src/os/macos/bridge.h +++ b/src/os/macos/bridge.h @@ -9,10 +9,12 @@ + (NSString*)macOSVersion; @end #else +#include "util/numtypes.h" + extern "C" { - const char* GetCurrentPlayingTitle(); - const char* GetCurrentPlayingArtist(); - const char* GetMacOSVersion(); + fn GetCurrentPlayingTitle() -> const char*; + fn GetCurrentPlayingArtist() -> const char*; + fn GetMacOSVersion() -> const char*; } #endif #endif diff --git a/src/os/macos/bridge.mm b/src/os/macos/bridge.mm index e17691a..c9a6b03 100644 --- a/src/os/macos/bridge.mm +++ b/src/os/macos/bridge.mm @@ -79,7 +79,8 @@ using MRMediaRemoteGetNowPlayingInfoFunction = void (*)( NSNumber* majorVersionNumber = @(osVersion.majorVersion); NSString* versionName = versionNames[majorVersionNumber]; - if (versionName == nil) versionName = @"Unknown"; + if (versionName == nil) + versionName = @"Unknown"; NSString* fullVersion = [NSString stringWithFormat:@"macOS %@ %@", version, versionName]; @@ -88,37 +89,44 @@ using MRMediaRemoteGetNowPlayingInfoFunction = void (*)( } @end +#include "util/numtypes.h" + extern "C" { - const char* GetCurrentPlayingTitle() { + fn GetCurrentPlayingTitle() -> const char* { NSDictionary* metadata = [Bridge currentPlayingMetadata]; - if (metadata == nil) return nullptr; + if (metadata == nil) + return nullptr; NSString* title = [metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoTitle"]; - if (title) return strdup([title UTF8String]); + if (title) + return strdup([title UTF8String]); return nullptr; } - const char* GetCurrentPlayingArtist() { + fn GetCurrentPlayingArtist() -> const char* { NSDictionary* metadata = [Bridge currentPlayingMetadata]; - if (metadata == nil) return nullptr; + if (metadata == nil) + return nullptr; NSString* artist = [metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoArtist"]; - if (artist) return strdup([artist UTF8String]); + if (artist) + return strdup([artist UTF8String]); return nullptr; } - const char* GetMacOSVersion() { + fn GetMacOSVersion() -> const char* { NSString* version = [Bridge macOSVersion]; - if (version) return strdup([version UTF8String]); + if (version) + return strdup([version UTF8String]); return nullptr; }