From 6d9390f02ccf5fd81832b2fec2f9ac4c062bff17 Mon Sep 17 00:00:00 2001 From: Mars Date: Mon, 28 Apr 2025 09:40:05 -0400 Subject: [PATCH] bro --- src/config/config.cpp | 6 ++- src/config/weather.cpp | 1 - src/core/system_data.cpp | 7 ++- src/core/system_data.hpp | 12 ++--- src/core/util/defs.hpp | 3 -- src/core/util/error.hpp | 15 +++--- src/core/util/helpers.hpp | 9 ++-- src/core/util/logging.hpp | 58 ++++++++++------------ src/core/util/types.hpp | 2 + src/main.cpp | 2 +- src/os/windows.cpp | 102 ++++++++++++++++++++++---------------- 11 files changed, 114 insertions(+), 103 deletions(-) diff --git a/src/config/config.cpp b/src/config/config.cpp index 07226bc..e2d8e51 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -15,6 +15,8 @@ namespace { using util::types::Vec, util::types::CStr, util::types::Exception; fn GetConfigPath() -> fs::path { + using util::helpers::GetEnv; + Vec possiblePaths; #ifdef _WIN32 @@ -31,10 +33,10 @@ namespace { possiblePaths.push_back(fs::path(".") / "config.toml"); #else - if (Result result = util::helpers::GetEnv("XDG_CONFIG_HOME")) + if (Result result = GetEnv("XDG_CONFIG_HOME")) possiblePaths.emplace_back(fs::path(*result) / "draconis++" / "config.toml"); - if (Result result = util::helpers::GetEnv("HOME")) { + if (Result result = GetEnv("HOME")) { possiblePaths.emplace_back(fs::path(*result) / ".config" / "draconis++" / "config.toml"); possiblePaths.emplace_back(fs::path(*result) / ".draconis++" / "config.toml"); } diff --git a/src/config/weather.cpp b/src/config/weather.cpp index a4a00bd..f93a4f9 100644 --- a/src/config/weather.cpp +++ b/src/config/weather.cpp @@ -11,7 +11,6 @@ #include // glz::read #include // glz::format_error #include // glz::write_json -#include // glz::atoi #include // std::istreambuf_iterator #include // std::error_code #include // std::move diff --git a/src/core/system_data.cpp b/src/core/system_data.cpp index f61b69e..c63c4d8 100644 --- a/src/core/system_data.cpp +++ b/src/core/system_data.cpp @@ -29,6 +29,8 @@ namespace { } // namespace fn SystemData::fetchSystemData(const Config& config) -> SystemData { + using util::types::None; + SystemData data { .date = GetDate(), .host = os::GetHost(), @@ -66,10 +68,7 @@ fn SystemData::fetchSystemData(const Config& config) -> SystemData { if (weatherFuture.valid()) try { data.weather_info = weatherFuture.get(); - } catch (const std::exception& e) { - error_log("Failed to get weather info: {}", e.what()); - data.weather_info = None; - } + } catch (const std::exception& e) { data.weather_info = None; } if (nowPlayingFuture.valid()) data.now_playing = nowPlayingFuture.get(); diff --git a/src/core/system_data.hpp b/src/core/system_data.hpp index eb72abb..6dfab8b 100644 --- a/src/core/system_data.hpp +++ b/src/core/system_data.hpp @@ -69,17 +69,17 @@ struct SystemData { using NowPlayingResult = Option>; // clang-format off - String date; ///< Current date (e.g., "April 26th"). Always expected to succeed. + String date; ///< Current date (e.g., "April 26th"). Always expected to succeed. Result host; ///< Host/product family (e.g., "MacBookPro18,3") or OS util::erroror. Result kernel_version; ///< OS kernel version (e.g., "23.4.0") or OS error. Result os_version; ///< OS pretty name (e.g., "macOS Sonoma 14.4.1") or OS error. Result mem_info; ///< Total physical RAM in bytes or OS error. - Option desktop_environment; ///< Detected desktop environment (e.g., "Aqua", "Plasma"). None if not detected/applicable. - Option window_manager; ///< Detected window manager (e.g., "Quartz Compositor", "KWin"). None if not detected/applicable. + Option desktop_environment; ///< Detected desktop environment (e.g., "Aqua", "Plasma"). None if not detected/applicable. + Option window_manager; ///< Detected window manager (e.g., "Quartz Compositor", "KWin"). None if not detected/applicable. Result disk_usage; ///< Used/Total disk space for root filesystem or OS error. - Option shell; ///< Name of the current user shell (e.g., "zsh"). None if not detected. - NowPlayingResult now_playing; ///< Optional: Result of fetching media info (MediaInfo on success, NowPlayingError on failure). None if disabled. - Option weather_info; ///< Optional: Weather information. None if disabled or util::erroror during fetch. + Option shell; ///< Name of the current user shell (e.g., "zsh"). None if not detected. + NowPlayingResult now_playing; ///< Optional: Result of fetching media info (MediaInfo on success, NowPlayingError on failure). None if disabled. + Option weather_info; ///< Optional: Weather information. None if disabled or util::erroror during fetch. // clang-format on /** diff --git a/src/core/util/defs.hpp b/src/core/util/defs.hpp index fa8e7d1..235fcb9 100644 --- a/src/core/util/defs.hpp +++ b/src/core/util/defs.hpp @@ -7,6 +7,3 @@ /// Macro alias for trailing return type functions. #define fn auto - -/// Macro alias for std::nullopt, represents an empty optional value. -#define None std::nullopt diff --git a/src/core/util/error.hpp b/src/core/util/error.hpp index b0ed098..0c5cb48 100644 --- a/src/core/util/error.hpp +++ b/src/core/util/error.hpp @@ -1,11 +1,10 @@ #pragma once -#include // std::format #include // std::source_location -#include // std::string_view (StringView) #include // std::error_code #ifdef _WIN32 + #include // error values #include // winrt::hresult_error #elifdef __linux__ #include // DBus::Error @@ -79,16 +78,16 @@ namespace util::error { } } #ifdef _WIN32 - explicit OsError(const winrt::hresult_error& e) : message(winrt::to_string(e.message())) { + explicit DraconisError(const winrt::hresult_error& e) : message(winrt::to_string(e.message())) { switch (e.code()) { - case E_ACCESSDENIED: code = OsErrorCode::PermissionDenied; break; + case E_ACCESSDENIED: code = DraconisErrorCode::PermissionDenied; break; case HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): case HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND): - case HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND): code = OsErrorCode::NotFound; break; + case HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND): code = DraconisErrorCode::NotFound; break; case HRESULT_FROM_WIN32(ERROR_TIMEOUT): - case HRESULT_FROM_WIN32(ERROR_SEM_TIMEOUT): code = OsErrorCode::Timeout; break; - case HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED): code = OsErrorCode::NotSupported; break; - default: code = OsErrorCode::PlatformSpecific; break; + case HRESULT_FROM_WIN32(ERROR_SEM_TIMEOUT): code = DraconisErrorCode::Timeout; break; + case HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED): code = DraconisErrorCode::NotSupported; break; + default: code = DraconisErrorCode::PlatformSpecific; break; } } #else diff --git a/src/core/util/helpers.hpp b/src/core/util/helpers.hpp index 0a14942..000791e 100644 --- a/src/core/util/helpers.hpp +++ b/src/core/util/helpers.hpp @@ -5,7 +5,8 @@ #include "types.hpp" namespace util::helpers { - using types::Result, types::String, types::CStr, types::UniquePointer, types::Err; + using error::DraconisError, error::DraconisErrorCode; + using types::Result, types::String, types::CStr, types::Err; /** * @brief Safely retrieves an environment variable. @@ -13,8 +14,10 @@ namespace util::helpers { * @return A Result containing the value of the environment variable as a String, * or an EnvError if an error occurred. */ - [[nodiscard]] inline fn GetEnv(CStr name) -> Result { + [[nodiscard]] inline fn GetEnv(CStr name) -> Result { #ifdef _WIN32 + using types::i32, types::usize, types::UniquePointer; + char* rawPtr = nullptr; usize bufferSize = 0; @@ -35,7 +38,7 @@ namespace util::helpers { const CStr value = std::getenv(name); if (!value) - return Err(error::DraconisError(error::DraconisErrorCode::NotFound, "Environment variable not found")); + return Err(DraconisError(DraconisErrorCode::NotFound, "Environment variable not found")); return value; #endif diff --git a/src/core/util/logging.hpp b/src/core/util/logging.hpp index aaef273..0eda5e6 100644 --- a/src/core/util/logging.hpp +++ b/src/core/util/logging.hpp @@ -12,7 +12,7 @@ #include "src/core/util/types.hpp" namespace util::logging { - using types::u8, types::i32, types::String, types::StringView, types::Option; + using types::u8, types::i32, types::String, types::StringView, types::Option, types::None; /** * @namespace term @@ -184,7 +184,7 @@ namespace util::logging { * @enum LogLevel * @brief Represents different log levels. */ - enum class LogLevel : u8 { DEBUG, INFO, WARN, ERROR }; + enum class LogLevel : u8 { Debug, Info, Warn, Error }; /** * @brief Logs a message with the specified log level, source location, and format string. @@ -199,30 +199,24 @@ namespace util::logging { using namespace std::chrono; using namespace term; -#ifdef _MSC_VER - using enum term::Color; -#else - using enum Color; -#endif // _MSC_VER - const auto [color, levelStr] = [&] { switch (level) { - case LogLevel::DEBUG: return std::make_pair(Cyan, "DEBUG"); - case LogLevel::INFO: return std::make_pair(Green, "INFO "); - case LogLevel::WARN: return std::make_pair(Yellow, "WARN "); - case LogLevel::ERROR: return std::make_pair(Red, "ERROR"); + case LogLevel::Debug: return std::make_pair(Color::Cyan, "DEBUG"); + case LogLevel::Info: return std::make_pair(Color::Green, "INFO "); + case LogLevel::Warn: return std::make_pair(Color::Yellow, "WARN "); + case LogLevel::Error: return std::make_pair(Color::Red, "ERROR"); default: std::unreachable(); } }(); - Print(BrightWhite, "[{:%X}] ", std::chrono::floor(system_clock::now())); + Print(Color::BrightWhite, "[{:%X}] ", std::chrono::floor(system_clock::now())); Print(Emphasis::Bold | color, "{} ", levelStr); Print(fmt, std::forward(args)...); #ifndef NDEBUG - Print(BrightWhite, "\n{:>14} ", "╰──"); + Print(Color::BrightWhite, "\n{:>14} ", "╰──"); Print( - Emphasis::Italic | BrightWhite, + Emphasis::Italic | Color::BrightWhite, "{}:{}", std::filesystem::path(loc.file_name()).lexically_normal().string(), loc.line() @@ -236,31 +230,31 @@ namespace util::logging { fn LogAppError(const LogLevel level, const ErrorType& error_obj) { using DecayedErrorType = std::decay_t; - std::source_location log_location; - String error_message_part; + std::source_location logLocation; + String errorMessagePart; if constexpr (std::is_same_v) { - log_location = error_obj.location; - error_message_part = error_obj.message; + logLocation = error_obj.location; + errorMessagePart = error_obj.message; } else { - log_location = std::source_location::current(); + logLocation = std::source_location::current(); if constexpr (std::is_base_of_v) - error_message_part = error_obj.what(); + errorMessagePart = error_obj.what(); else if constexpr (requires { error_obj.message; }) - error_message_part = error_obj.message; + errorMessagePart = error_obj.message; else - error_message_part = "Unknown error type logged"; + errorMessagePart = "Unknown error type logged"; } - LogImpl(level, log_location, "{}", error_message_part); + LogImpl(level, logLocation, "{}", errorMessagePart); } #ifndef NDEBUG #define debug_log(fmt, ...) \ ::util::logging::LogImpl( \ - ::util::logging::LogLevel::DEBUG, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ + ::util::logging::LogLevel::Debug, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ ) - #define debug_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::DEBUG, error_obj); + #define debug_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::Debug, error_obj); #else #define debug_log(...) ((void)0) #define debug_at(...) ((void)0) @@ -268,19 +262,19 @@ namespace util::logging { #define info_log(fmt, ...) \ ::util::logging::LogImpl( \ - ::util::logging::LogLevel::INFO, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ + ::util::logging::LogLevel::Info, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ ) -#define info_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::INFO, error_obj); +#define info_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::Info, error_obj); #define warn_log(fmt, ...) \ ::util::logging::LogImpl( \ - ::util::logging::LogLevel::WARN, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ + ::util::logging::LogLevel::Warn, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ ) -#define warn_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::WARN, error_obj); +#define warn_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::Warn, error_obj); #define error_log(fmt, ...) \ ::util::logging::LogImpl( \ - ::util::logging::LogLevel::ERROR, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ + ::util::logging::LogLevel::Error, std::source_location::current(), fmt __VA_OPT__(, ) __VA_ARGS__ \ ) -#define error_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::ERROR, error_obj); +#define error_at(error_obj) ::util::logging::LogAppError(::util::logging::LogLevel::Error, error_obj); } // namespace util::logging diff --git a/src/core/util/types.hpp b/src/core/util/types.hpp index 38f03a2..988d8af 100644 --- a/src/core/util/types.hpp +++ b/src/core/util/types.hpp @@ -33,6 +33,8 @@ namespace util::types { using Exception = std::exception; ///< Standard exception type. + inline constexpr std::nullopt_t None = std::nullopt; ///< Represents an empty optional value. + /** * @typedef Result * @brief Alias for std::expected. Represents a value that can either be diff --git a/src/main.cpp b/src/main.cpp index 6ff01f6..39aa8df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -270,7 +270,7 @@ fn main() -> i32 { if (const Result& packageCount = os::GetPackageCount()) debug_log("{}", *packageCount); else - debug_at(packageCount.error()); + error_at(packageCount.error()); Element document = vbox({ hbox({ SystemInfoBox(config, data), filler() }), text("") }); diff --git a/src/os/windows.cpp b/src/os/windows.cpp index f03fc89..3748bc8 100644 --- a/src/os/windows.cpp +++ b/src/os/windows.cpp @@ -5,7 +5,6 @@ #include #include #include -// clang-format on #include #include @@ -17,9 +16,18 @@ #include #include -#include "os.h" +#include "src/core/util/error.hpp" +#include "src/core/util/helpers.hpp" +#include "src/core/util/logging.hpp" +#include "src/core/util/types.hpp" + +#include "os.hpp" +// clang-format on namespace { + using util::error::DraconisError, util::error::DraconisErrorCode; + using namespace util::types; + struct OSVersion { u16 major; u16 minor; @@ -36,10 +44,10 @@ namespace { .revision = static_cast(versionUl & 0xFFFF), }; } catch (const std::invalid_argument& e) { - ERROR_LOG("Invalid argument: {}", e.what()); + error_log("Invalid argument: {}", e.what()); } catch (const std::out_of_range& e) { - ERROR_LOG("Value out of range: {}", e.what()); - } catch (const winrt::hresult_error& e) { ERROR_LOG("Windows error: {}", winrt::to_string(e.message())); } + error_log("Value out of range: {}", e.what()); + } catch (const winrt::hresult_error& e) { error_log("Windows error: {}", winrt::to_string(e.message())); } return { .major = 0, .minor = 0, .build = 0, .revision = 0 }; } @@ -83,7 +91,7 @@ namespace { return value; } - fn GetProcessInfo() -> Result>, OsError> { + fn GetProcessInfo() -> Result>, DraconisError> { try { using namespace winrt::Windows::System::Diagnostics; using namespace winrt::Windows::Foundation::Collections; @@ -96,8 +104,8 @@ namespace { for (const auto& processInfo : processInfos) processes.emplace_back(processInfo.ProcessId(), winrt::to_string(processInfo.ExecutableFileName())); return processes; - } catch (const winrt::hresult_error& e) { return Err(OsError(e)); } catch (const std::exception& e) { - return Err(OsError(e)); + } catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } catch (const std::exception& e) { + return Err(DraconisError(e)); } } @@ -121,7 +129,8 @@ namespace { try { currentProcessInfo = ProcessDiagnosticInfo::TryGetForProcessId(startPid); } catch (const winrt::hresult_error& e) { - RETURN_ERR("Failed to get process info for PID {}: {}", startPid, winrt::to_string(e.message())); + error_log("Failed to get process info for PID {}: {}", startPid, winrt::to_string(e.message())); + return None; } while (currentProcessInfo) { @@ -145,9 +154,9 @@ namespace { currentProcessInfo = currentProcessInfo.Parent(); } } catch (const winrt::hresult_error& e) { - ERROR_LOG("WinRT error during process tree walk (start PID {}): {}", startPid, winrt::to_string(e.message())); + error_log("WinRT error during process tree walk (start PID {}): {}", startPid, winrt::to_string(e.message())); } catch (const std::exception& e) { - ERROR_LOG("Standard exception during process tree walk (start PID {}): {}", startPid, e.what()); + error_log("Standard exception during process tree walk (start PID {}): {}", startPid, e.what()); } return None; @@ -164,23 +173,23 @@ namespace { return (versionUl >> 16) & 0xFFFF; } } catch (const winrt::hresult_error& e) { - DEBUG_LOG("WinRT error getting build number: {}", winrt::to_string(e.message())); - } catch (const Exception& e) { DEBUG_LOG("Standard exception getting build number: {}", e.what()); } + debug_log("WinRT error getting build number: {}", winrt::to_string(e.message())); + } catch (const Exception& e) { debug_log("Standard exception getting build number: {}", e.what()); } return None; } -} +} // namespace -fn os::GetMemInfo() -> Result { +fn os::GetMemInfo() -> Result { try { return winrt::Windows::System::Diagnostics::SystemDiagnosticInfo::GetForCurrentSystem() .MemoryUsage() .GetReport() .TotalPhysicalSizeInBytes(); - } catch (const winrt::hresult_error& e) { return Err(OsError(e)); } + } catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } } -fn os::GetNowPlaying() -> Result { +fn os::GetNowPlaying() -> Result { using namespace winrt::Windows::Media::Control; using namespace winrt::Windows::Foundation; @@ -200,11 +209,11 @@ fn os::GetNowPlaying() -> Result { ); } - return Err(NowPlayingCode::NoActivePlayer); - } catch (const winrt::hresult_error& e) { return Err(OsError(e)); } + return Err(DraconisError(DraconisErrorCode::NotFound, "No media session found")); + } catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } } -fn os::GetOSVersion() -> Result { +fn os::GetOSVersion() -> Result { try { const String regSubKey = R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)"; @@ -212,7 +221,7 @@ fn os::GetOSVersion() -> Result { const String displayVersion = GetRegistryValue(HKEY_LOCAL_MACHINE, regSubKey, "DisplayVersion"); if (productName.empty()) - return Err(OsError { OsErrorCode::NotFound, "ProductName not found in registry" }); + return Err(DraconisError(DraconisErrorCode::NotFound, "ProductName not found in registry")); if (const Option buildNumberOpt = GetBuildNumber()) { if (const u64 buildNumber = *buildNumberOpt; buildNumber >= 22000) { @@ -227,18 +236,18 @@ fn os::GetOSVersion() -> Result { } } } else { - DEBUG_LOG("Warning: Could not get build number via WinRT; Win11 detection might be inaccurate."); + debug_log("Warning: Could not get build number via WinRT; Win11 detection might be inaccurate."); } return displayVersion.empty() ? productName : productName + " " + displayVersion; - } catch (const std::exception& e) { return Err(OsError(e)); } + } catch (const std::exception& e) { return Err(DraconisError(e)); } } -fn os::GetHost() -> Result { +fn os::GetHost() -> Result { return GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SYSTEM\HardwareConfig\Current)", "SystemFamily"); } -fn os::GetKernelVersion() -> Result { +fn os::GetKernelVersion() -> Result { try { using namespace winrt::Windows::System::Profile; @@ -247,15 +256,15 @@ fn os::GetKernelVersion() -> Result { if (const winrt::hstring familyVersion = versionInfo.DeviceFamilyVersion(); !familyVersion.empty()) if (auto [major, minor, build, revision] = OSVersion::parseDeviceFamilyVersion(familyVersion); build > 0) return std::format("{}.{}.{}.{}", major, minor, build, revision); - } catch (const winrt::hresult_error& e) { return Err(OsError(e)); } catch (const Exception& e) { - return Err(OsError(e)); + } catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } catch (const Exception& e) { + return Err(DraconisError(e)); } - return Err(OsError { OsErrorCode::NotFound, "Could not determine kernel version" }); + return Err(DraconisError(DraconisErrorCode::NotFound, "Could not determine kernel version")); } fn os::GetWindowManager() -> Option { - if (const Result>, OsError> processInfoResult = GetProcessInfo()) { + if (const Result>, DraconisError> processInfoResult = GetProcessInfo()) { const Vec>& processInfo = *processInfoResult; Vec processNames; @@ -279,7 +288,7 @@ fn os::GetWindowManager() -> Option { if (IsProcessRunning(processNames, processExe)) return wmName; } else { - ERROR_LOG("Failed to get process info for WM detection: {}", processInfoResult.error().message); + error_log("Failed to get process info for WM detection: {}", processInfoResult.error().message); } BOOL compositionEnabled = FALSE; @@ -295,8 +304,8 @@ fn os::GetDesktopEnvironment() -> Option { GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "CurrentBuildNumber"); if (buildStr.empty()) { - DEBUG_LOG("Failed to get CurrentBuildNumber from registry"); - return std::nullopt; + debug_log("Failed to get CurrentBuildNumber from registry"); + return None; } try { @@ -332,22 +341,25 @@ fn os::GetDesktopEnvironment() -> Option { // Pre-Win7 return "Classic"; } catch (...) { - DEBUG_LOG("Failed to parse CurrentBuildNumber"); - return std::nullopt; + debug_log("Failed to parse CurrentBuildNumber"); + return None; } } fn os::GetShell() -> Option { + using util::helpers::GetEnv; + try { const DWORD currentPid = winrt::Windows::System::Diagnostics::ProcessDiagnosticInfo::GetForCurrentProcess().ProcessId(); - if (const Result msystemResult = GetEnv("MSYSTEM"); msystemResult && !msystemResult->empty()) { + if (const Result msystemResult = GetEnv("MSYSTEM"); + msystemResult && !msystemResult->empty()) { String shellPath; - if (const Result shellResult = GetEnv("SHELL"); shellResult && !shellResult->empty()) + if (const Result shellResult = GetEnv("SHELL"); shellResult && !shellResult->empty()) shellPath = *shellResult; - else if (const Result loginShellResult = GetEnv("LOGINSHELL"); + else if (const Result loginShellResult = GetEnv("LOGINSHELL"); loginShellResult && !loginShellResult->empty()) shellPath = *loginShellResult; @@ -355,8 +367,8 @@ fn os::GetShell() -> Option { const usize lastSlash = shellPath.find_last_of("\\/"); String shellExe = (lastSlash != String::npos) ? shellPath.substr(lastSlash + 1) : shellPath; - std::ranges::transform(shellExe, shellExe.begin(), [](const u8 c) { - return static_cast(std::tolower(static_cast(c))); + std::ranges::transform(shellExe, shellExe.begin(), [](const u8 character) { + return static_cast(std::tolower(static_cast(character))); }); if (shellExe.ends_with(".exe")) @@ -378,19 +390,23 @@ fn os::GetShell() -> Option { if (const Option windowsShell = FindShellInProcessTree(currentPid, windowsShellMap)) return *windowsShell; } catch (const winrt::hresult_error& e) { - ERROR_LOG("WinRT error during shell detection: {}", winrt::to_string(e.message())); - } catch (const std::exception& e) { ERROR_LOG("Standard exception during shell detection: {}", e.what()); } + error_log("WinRT error during shell detection: {}", winrt::to_string(e.message())); + } catch (const std::exception& e) { error_log("Standard exception during shell detection: {}", e.what()); } return None; } -fn os::GetDiskUsage() -> Result { +fn os::GetDiskUsage() -> Result { ULARGE_INTEGER freeBytes, totalBytes; if (GetDiskFreeSpaceExW(L"C:\\", nullptr, &totalBytes, &freeBytes)) return DiskSpace { .used_bytes = totalBytes.QuadPart - freeBytes.QuadPart, .total_bytes = totalBytes.QuadPart }; - return Err(OsError { OsErrorCode::NotFound, "Failed to get disk usage" }); + return Err(DraconisError(util::error::DraconisErrorCode::NotFound, "Failed to get disk usage")); +} + +fn os::GetPackageCount() -> Result { + return Err(DraconisError(DraconisErrorCode::NotFound, "GetPackageCount not implemented")); } #endif