bro
This commit is contained in:
parent
e7a16d005c
commit
6d9390f02c
11 changed files with 114 additions and 103 deletions
|
@ -15,6 +15,8 @@ namespace {
|
||||||
using util::types::Vec, util::types::CStr, util::types::Exception;
|
using util::types::Vec, util::types::CStr, util::types::Exception;
|
||||||
|
|
||||||
fn GetConfigPath() -> fs::path {
|
fn GetConfigPath() -> fs::path {
|
||||||
|
using util::helpers::GetEnv;
|
||||||
|
|
||||||
Vec<fs::path> possiblePaths;
|
Vec<fs::path> possiblePaths;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -31,10 +33,10 @@ namespace {
|
||||||
|
|
||||||
possiblePaths.push_back(fs::path(".") / "config.toml");
|
possiblePaths.push_back(fs::path(".") / "config.toml");
|
||||||
#else
|
#else
|
||||||
if (Result<String, DraconisError> result = util::helpers::GetEnv("XDG_CONFIG_HOME"))
|
if (Result<String, DraconisError> result = GetEnv("XDG_CONFIG_HOME"))
|
||||||
possiblePaths.emplace_back(fs::path(*result) / "draconis++" / "config.toml");
|
possiblePaths.emplace_back(fs::path(*result) / "draconis++" / "config.toml");
|
||||||
|
|
||||||
if (Result<String, DraconisError> result = util::helpers::GetEnv("HOME")) {
|
if (Result<String, DraconisError> result = GetEnv("HOME")) {
|
||||||
possiblePaths.emplace_back(fs::path(*result) / ".config" / "draconis++" / "config.toml");
|
possiblePaths.emplace_back(fs::path(*result) / ".config" / "draconis++" / "config.toml");
|
||||||
possiblePaths.emplace_back(fs::path(*result) / ".draconis++" / "config.toml");
|
possiblePaths.emplace_back(fs::path(*result) / ".draconis++" / "config.toml");
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <glaze/core/read.hpp> // glz::read
|
#include <glaze/core/read.hpp> // glz::read
|
||||||
#include <glaze/core/reflect.hpp> // glz::format_error
|
#include <glaze/core/reflect.hpp> // glz::format_error
|
||||||
#include <glaze/json/write.hpp> // glz::write_json
|
#include <glaze/json/write.hpp> // glz::write_json
|
||||||
#include <glaze/util/atoi.hpp> // glz::atoi
|
|
||||||
#include <iterator> // std::istreambuf_iterator
|
#include <iterator> // std::istreambuf_iterator
|
||||||
#include <system_error> // std::error_code
|
#include <system_error> // std::error_code
|
||||||
#include <utility> // std::move
|
#include <utility> // std::move
|
||||||
|
|
|
@ -29,6 +29,8 @@ namespace {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
fn SystemData::fetchSystemData(const Config& config) -> SystemData {
|
fn SystemData::fetchSystemData(const Config& config) -> SystemData {
|
||||||
|
using util::types::None;
|
||||||
|
|
||||||
SystemData data {
|
SystemData data {
|
||||||
.date = GetDate(),
|
.date = GetDate(),
|
||||||
.host = os::GetHost(),
|
.host = os::GetHost(),
|
||||||
|
@ -66,10 +68,7 @@ fn SystemData::fetchSystemData(const Config& config) -> SystemData {
|
||||||
if (weatherFuture.valid())
|
if (weatherFuture.valid())
|
||||||
try {
|
try {
|
||||||
data.weather_info = weatherFuture.get();
|
data.weather_info = weatherFuture.get();
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) { data.weather_info = None; }
|
||||||
error_log("Failed to get weather info: {}", e.what());
|
|
||||||
data.weather_info = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nowPlayingFuture.valid())
|
if (nowPlayingFuture.valid())
|
||||||
data.now_playing = nowPlayingFuture.get();
|
data.now_playing = nowPlayingFuture.get();
|
||||||
|
|
|
@ -69,17 +69,17 @@ struct SystemData {
|
||||||
using NowPlayingResult = Option<Result<MediaInfo, util::error::DraconisError>>;
|
using NowPlayingResult = Option<Result<MediaInfo, util::error::DraconisError>>;
|
||||||
|
|
||||||
// clang-format off
|
// 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<String, util::error::DraconisError> host; ///< Host/product family (e.g., "MacBookPro18,3") or OS util::erroror.
|
Result<String, util::error::DraconisError> host; ///< Host/product family (e.g., "MacBookPro18,3") or OS util::erroror.
|
||||||
Result<String, util::error::DraconisError> kernel_version; ///< OS kernel version (e.g., "23.4.0") or OS error.
|
Result<String, util::error::DraconisError> kernel_version; ///< OS kernel version (e.g., "23.4.0") or OS error.
|
||||||
Result<String, util::error::DraconisError> os_version; ///< OS pretty name (e.g., "macOS Sonoma 14.4.1") or OS error.
|
Result<String, util::error::DraconisError> os_version; ///< OS pretty name (e.g., "macOS Sonoma 14.4.1") or OS error.
|
||||||
Result<u64, util::error::DraconisError> mem_info; ///< Total physical RAM in bytes or OS error.
|
Result<u64, util::error::DraconisError> mem_info; ///< Total physical RAM in bytes or OS error.
|
||||||
Option<String> desktop_environment; ///< Detected desktop environment (e.g., "Aqua", "Plasma"). None if not detected/applicable.
|
Option<String> desktop_environment; ///< Detected desktop environment (e.g., "Aqua", "Plasma"). None if not detected/applicable.
|
||||||
Option<String> window_manager; ///< Detected window manager (e.g., "Quartz Compositor", "KWin"). None if not detected/applicable.
|
Option<String> window_manager; ///< Detected window manager (e.g., "Quartz Compositor", "KWin"). None if not detected/applicable.
|
||||||
Result<DiskSpace, util::error::DraconisError> disk_usage; ///< Used/Total disk space for root filesystem or OS error.
|
Result<DiskSpace, util::error::DraconisError> disk_usage; ///< Used/Total disk space for root filesystem or OS error.
|
||||||
Option<String> shell; ///< Name of the current user shell (e.g., "zsh"). None if not detected.
|
Option<String> 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.
|
NowPlayingResult now_playing; ///< Optional: Result of fetching media info (MediaInfo on success, NowPlayingError on failure). None if disabled.
|
||||||
Option<weather::Output> weather_info; ///< Optional: Weather information. None if disabled or util::erroror during fetch.
|
Option<weather::Output> weather_info; ///< Optional: Weather information. None if disabled or util::erroror during fetch.
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,6 +7,3 @@
|
||||||
|
|
||||||
/// Macro alias for trailing return type functions.
|
/// Macro alias for trailing return type functions.
|
||||||
#define fn auto
|
#define fn auto
|
||||||
|
|
||||||
/// Macro alias for std::nullopt, represents an empty optional value.
|
|
||||||
#define None std::nullopt
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <format> // std::format
|
|
||||||
#include <source_location> // std::source_location
|
#include <source_location> // std::source_location
|
||||||
#include <string_view> // std::string_view (StringView)
|
|
||||||
#include <system_error> // std::error_code
|
#include <system_error> // std::error_code
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
#include <winerror.h> // error values
|
||||||
#include <winrt/base.h> // winrt::hresult_error
|
#include <winrt/base.h> // winrt::hresult_error
|
||||||
#elifdef __linux__
|
#elifdef __linux__
|
||||||
#include <dbus-cxx/error.h> // DBus::Error
|
#include <dbus-cxx/error.h> // DBus::Error
|
||||||
|
@ -79,16 +78,16 @@ namespace util::error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#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()) {
|
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_FILE_NOT_FOUND):
|
||||||
case HRESULT_FROM_WIN32(ERROR_PATH_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_TIMEOUT):
|
||||||
case HRESULT_FROM_WIN32(ERROR_SEM_TIMEOUT): code = OsErrorCode::Timeout; break;
|
case HRESULT_FROM_WIN32(ERROR_SEM_TIMEOUT): code = DraconisErrorCode::Timeout; break;
|
||||||
case HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED): code = OsErrorCode::NotSupported; break;
|
case HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED): code = DraconisErrorCode::NotSupported; break;
|
||||||
default: code = OsErrorCode::PlatformSpecific; break;
|
default: code = DraconisErrorCode::PlatformSpecific; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
namespace util::helpers {
|
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.
|
* @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,
|
* @return A Result containing the value of the environment variable as a String,
|
||||||
* or an EnvError if an error occurred.
|
* or an EnvError if an error occurred.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline fn GetEnv(CStr name) -> Result<String, error::DraconisError> {
|
[[nodiscard]] inline fn GetEnv(CStr name) -> Result<String, DraconisError> {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
using types::i32, types::usize, types::UniquePointer;
|
||||||
|
|
||||||
char* rawPtr = nullptr;
|
char* rawPtr = nullptr;
|
||||||
usize bufferSize = 0;
|
usize bufferSize = 0;
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ namespace util::helpers {
|
||||||
const CStr value = std::getenv(name);
|
const CStr value = std::getenv(name);
|
||||||
|
|
||||||
if (!value)
|
if (!value)
|
||||||
return Err(error::DraconisError(error::DraconisErrorCode::NotFound, "Environment variable not found"));
|
return Err(DraconisError(DraconisErrorCode::NotFound, "Environment variable not found"));
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "src/core/util/types.hpp"
|
#include "src/core/util/types.hpp"
|
||||||
|
|
||||||
namespace util::logging {
|
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
|
* @namespace term
|
||||||
|
@ -184,7 +184,7 @@ namespace util::logging {
|
||||||
* @enum LogLevel
|
* @enum LogLevel
|
||||||
* @brief Represents different log levels.
|
* @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.
|
* @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 std::chrono;
|
||||||
using namespace term;
|
using namespace term;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
using enum term::Color;
|
|
||||||
#else
|
|
||||||
using enum Color;
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
const auto [color, levelStr] = [&] {
|
const auto [color, levelStr] = [&] {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case LogLevel::DEBUG: return std::make_pair(Cyan, "DEBUG");
|
case LogLevel::Debug: return std::make_pair(Color::Cyan, "DEBUG");
|
||||||
case LogLevel::INFO: return std::make_pair(Green, "INFO ");
|
case LogLevel::Info: return std::make_pair(Color::Green, "INFO ");
|
||||||
case LogLevel::WARN: return std::make_pair(Yellow, "WARN ");
|
case LogLevel::Warn: return std::make_pair(Color::Yellow, "WARN ");
|
||||||
case LogLevel::ERROR: return std::make_pair(Red, "ERROR");
|
case LogLevel::Error: return std::make_pair(Color::Red, "ERROR");
|
||||||
default: std::unreachable();
|
default: std::unreachable();
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
Print(BrightWhite, "[{:%X}] ", std::chrono::floor<seconds>(system_clock::now()));
|
Print(Color::BrightWhite, "[{:%X}] ", std::chrono::floor<seconds>(system_clock::now()));
|
||||||
Print(Emphasis::Bold | color, "{} ", levelStr);
|
Print(Emphasis::Bold | color, "{} ", levelStr);
|
||||||
Print(fmt, std::forward<Args>(args)...);
|
Print(fmt, std::forward<Args>(args)...);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
Print(BrightWhite, "\n{:>14} ", "╰──");
|
Print(Color::BrightWhite, "\n{:>14} ", "╰──");
|
||||||
Print(
|
Print(
|
||||||
Emphasis::Italic | BrightWhite,
|
Emphasis::Italic | Color::BrightWhite,
|
||||||
"{}:{}",
|
"{}:{}",
|
||||||
std::filesystem::path(loc.file_name()).lexically_normal().string(),
|
std::filesystem::path(loc.file_name()).lexically_normal().string(),
|
||||||
loc.line()
|
loc.line()
|
||||||
|
@ -236,31 +230,31 @@ namespace util::logging {
|
||||||
fn LogAppError(const LogLevel level, const ErrorType& error_obj) {
|
fn LogAppError(const LogLevel level, const ErrorType& error_obj) {
|
||||||
using DecayedErrorType = std::decay_t<ErrorType>;
|
using DecayedErrorType = std::decay_t<ErrorType>;
|
||||||
|
|
||||||
std::source_location log_location;
|
std::source_location logLocation;
|
||||||
String error_message_part;
|
String errorMessagePart;
|
||||||
|
|
||||||
if constexpr (std::is_same_v<DecayedErrorType, error::DraconisError>) {
|
if constexpr (std::is_same_v<DecayedErrorType, error::DraconisError>) {
|
||||||
log_location = error_obj.location;
|
logLocation = error_obj.location;
|
||||||
error_message_part = error_obj.message;
|
errorMessagePart = error_obj.message;
|
||||||
} else {
|
} else {
|
||||||
log_location = std::source_location::current();
|
logLocation = std::source_location::current();
|
||||||
if constexpr (std::is_base_of_v<std::exception, DecayedErrorType>)
|
if constexpr (std::is_base_of_v<std::exception, DecayedErrorType>)
|
||||||
error_message_part = error_obj.what();
|
errorMessagePart = error_obj.what();
|
||||||
else if constexpr (requires { error_obj.message; })
|
else if constexpr (requires { error_obj.message; })
|
||||||
error_message_part = error_obj.message;
|
errorMessagePart = error_obj.message;
|
||||||
else
|
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
|
#ifndef NDEBUG
|
||||||
#define debug_log(fmt, ...) \
|
#define debug_log(fmt, ...) \
|
||||||
::util::logging::LogImpl( \
|
::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
|
#else
|
||||||
#define debug_log(...) ((void)0)
|
#define debug_log(...) ((void)0)
|
||||||
#define debug_at(...) ((void)0)
|
#define debug_at(...) ((void)0)
|
||||||
|
@ -268,19 +262,19 @@ namespace util::logging {
|
||||||
|
|
||||||
#define info_log(fmt, ...) \
|
#define info_log(fmt, ...) \
|
||||||
::util::logging::LogImpl( \
|
::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, ...) \
|
#define warn_log(fmt, ...) \
|
||||||
::util::logging::LogImpl( \
|
::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, ...) \
|
#define error_log(fmt, ...) \
|
||||||
::util::logging::LogImpl( \
|
::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
|
} // namespace util::logging
|
||||||
|
|
|
@ -33,6 +33,8 @@ namespace util::types {
|
||||||
|
|
||||||
using Exception = std::exception; ///< Standard exception type.
|
using Exception = std::exception; ///< Standard exception type.
|
||||||
|
|
||||||
|
inline constexpr std::nullopt_t None = std::nullopt; ///< Represents an empty optional value.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef Result
|
* @typedef Result
|
||||||
* @brief Alias for std::expected<Tp, Er>. Represents a value that can either be
|
* @brief Alias for std::expected<Tp, Er>. Represents a value that can either be
|
||||||
|
|
|
@ -270,7 +270,7 @@ fn main() -> i32 {
|
||||||
if (const Result<u64, DraconisError>& packageCount = os::GetPackageCount())
|
if (const Result<u64, DraconisError>& packageCount = os::GetPackageCount())
|
||||||
debug_log("{}", *packageCount);
|
debug_log("{}", *packageCount);
|
||||||
else
|
else
|
||||||
debug_at(packageCount.error());
|
error_at(packageCount.error());
|
||||||
|
|
||||||
Element document = vbox({ hbox({ SystemInfoBox(config, data), filler() }), text("") });
|
Element document = vbox({ hbox({ SystemInfoBox(config, data), filler() }), text("") });
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
@ -17,9 +16,18 @@
|
||||||
#include <winrt/base.h>
|
#include <winrt/base.h>
|
||||||
#include <winrt/impl/Windows.Media.Control.2.h>
|
#include <winrt/impl/Windows.Media.Control.2.h>
|
||||||
|
|
||||||
#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 {
|
namespace {
|
||||||
|
using util::error::DraconisError, util::error::DraconisErrorCode;
|
||||||
|
using namespace util::types;
|
||||||
|
|
||||||
struct OSVersion {
|
struct OSVersion {
|
||||||
u16 major;
|
u16 major;
|
||||||
u16 minor;
|
u16 minor;
|
||||||
|
@ -36,10 +44,10 @@ namespace {
|
||||||
.revision = static_cast<u16>(versionUl & 0xFFFF),
|
.revision = static_cast<u16>(versionUl & 0xFFFF),
|
||||||
};
|
};
|
||||||
} catch (const std::invalid_argument& e) {
|
} 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) {
|
} catch (const std::out_of_range& e) {
|
||||||
ERROR_LOG("Value out of range: {}", e.what());
|
error_log("Value out of range: {}", e.what());
|
||||||
} catch (const winrt::hresult_error& e) { ERROR_LOG("Windows error: {}", winrt::to_string(e.message())); }
|
} catch (const winrt::hresult_error& e) { error_log("Windows error: {}", winrt::to_string(e.message())); }
|
||||||
|
|
||||||
return { .major = 0, .minor = 0, .build = 0, .revision = 0 };
|
return { .major = 0, .minor = 0, .build = 0, .revision = 0 };
|
||||||
}
|
}
|
||||||
|
@ -83,7 +91,7 @@ namespace {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetProcessInfo() -> Result<Vec<Pair<DWORD, String>>, OsError> {
|
fn GetProcessInfo() -> Result<Vec<Pair<DWORD, String>>, DraconisError> {
|
||||||
try {
|
try {
|
||||||
using namespace winrt::Windows::System::Diagnostics;
|
using namespace winrt::Windows::System::Diagnostics;
|
||||||
using namespace winrt::Windows::Foundation::Collections;
|
using namespace winrt::Windows::Foundation::Collections;
|
||||||
|
@ -96,8 +104,8 @@ namespace {
|
||||||
for (const auto& processInfo : processInfos)
|
for (const auto& processInfo : processInfos)
|
||||||
processes.emplace_back(processInfo.ProcessId(), winrt::to_string(processInfo.ExecutableFileName()));
|
processes.emplace_back(processInfo.ProcessId(), winrt::to_string(processInfo.ExecutableFileName()));
|
||||||
return processes;
|
return processes;
|
||||||
} catch (const winrt::hresult_error& e) { return Err(OsError(e)); } catch (const std::exception& e) {
|
} catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } catch (const std::exception& e) {
|
||||||
return Err(OsError(e));
|
return Err(DraconisError(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +129,8 @@ namespace {
|
||||||
try {
|
try {
|
||||||
currentProcessInfo = ProcessDiagnosticInfo::TryGetForProcessId(startPid);
|
currentProcessInfo = ProcessDiagnosticInfo::TryGetForProcessId(startPid);
|
||||||
} catch (const winrt::hresult_error& e) {
|
} 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) {
|
while (currentProcessInfo) {
|
||||||
|
@ -145,9 +154,9 @@ namespace {
|
||||||
currentProcessInfo = currentProcessInfo.Parent();
|
currentProcessInfo = currentProcessInfo.Parent();
|
||||||
}
|
}
|
||||||
} catch (const winrt::hresult_error& e) {
|
} 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) {
|
} 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;
|
return None;
|
||||||
|
@ -164,23 +173,23 @@ namespace {
|
||||||
return (versionUl >> 16) & 0xFFFF;
|
return (versionUl >> 16) & 0xFFFF;
|
||||||
}
|
}
|
||||||
} catch (const winrt::hresult_error& e) {
|
} catch (const winrt::hresult_error& e) {
|
||||||
DEBUG_LOG("WinRT error getting build number: {}", winrt::to_string(e.message()));
|
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()); }
|
} catch (const Exception& e) { debug_log("Standard exception getting build number: {}", e.what()); }
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
fn os::GetMemInfo() -> Result<u64, OsError> {
|
fn os::GetMemInfo() -> Result<u64, DraconisError> {
|
||||||
try {
|
try {
|
||||||
return winrt::Windows::System::Diagnostics::SystemDiagnosticInfo::GetForCurrentSystem()
|
return winrt::Windows::System::Diagnostics::SystemDiagnosticInfo::GetForCurrentSystem()
|
||||||
.MemoryUsage()
|
.MemoryUsage()
|
||||||
.GetReport()
|
.GetReport()
|
||||||
.TotalPhysicalSizeInBytes();
|
.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<MediaInfo, NowPlayingError> {
|
fn os::GetNowPlaying() -> Result<MediaInfo, DraconisError> {
|
||||||
using namespace winrt::Windows::Media::Control;
|
using namespace winrt::Windows::Media::Control;
|
||||||
using namespace winrt::Windows::Foundation;
|
using namespace winrt::Windows::Foundation;
|
||||||
|
|
||||||
|
@ -200,11 +209,11 @@ fn os::GetNowPlaying() -> Result<MediaInfo, NowPlayingError> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(NowPlayingCode::NoActivePlayer);
|
return Err(DraconisError(DraconisErrorCode::NotFound, "No media session found"));
|
||||||
} catch (const winrt::hresult_error& e) { return Err(OsError(e)); }
|
} catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn os::GetOSVersion() -> Result<String, OsError> {
|
fn os::GetOSVersion() -> Result<String, DraconisError> {
|
||||||
try {
|
try {
|
||||||
const String regSubKey = R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)";
|
const String regSubKey = R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)";
|
||||||
|
|
||||||
|
@ -212,7 +221,7 @@ fn os::GetOSVersion() -> Result<String, OsError> {
|
||||||
const String displayVersion = GetRegistryValue(HKEY_LOCAL_MACHINE, regSubKey, "DisplayVersion");
|
const String displayVersion = GetRegistryValue(HKEY_LOCAL_MACHINE, regSubKey, "DisplayVersion");
|
||||||
|
|
||||||
if (productName.empty())
|
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<u64> buildNumberOpt = GetBuildNumber()) {
|
if (const Option<u64> buildNumberOpt = GetBuildNumber()) {
|
||||||
if (const u64 buildNumber = *buildNumberOpt; buildNumber >= 22000) {
|
if (const u64 buildNumber = *buildNumberOpt; buildNumber >= 22000) {
|
||||||
|
@ -227,18 +236,18 @@ fn os::GetOSVersion() -> Result<String, OsError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
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<String, OsError> {
|
fn os::GetHost() -> Result<String, DraconisError> {
|
||||||
return GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SYSTEM\HardwareConfig\Current)", "SystemFamily");
|
return GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SYSTEM\HardwareConfig\Current)", "SystemFamily");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn os::GetKernelVersion() -> Result<String, OsError> {
|
fn os::GetKernelVersion() -> Result<String, DraconisError> {
|
||||||
try {
|
try {
|
||||||
using namespace winrt::Windows::System::Profile;
|
using namespace winrt::Windows::System::Profile;
|
||||||
|
|
||||||
|
@ -247,15 +256,15 @@ fn os::GetKernelVersion() -> Result<String, OsError> {
|
||||||
if (const winrt::hstring familyVersion = versionInfo.DeviceFamilyVersion(); !familyVersion.empty())
|
if (const winrt::hstring familyVersion = versionInfo.DeviceFamilyVersion(); !familyVersion.empty())
|
||||||
if (auto [major, minor, build, revision] = OSVersion::parseDeviceFamilyVersion(familyVersion); build > 0)
|
if (auto [major, minor, build, revision] = OSVersion::parseDeviceFamilyVersion(familyVersion); build > 0)
|
||||||
return std::format("{}.{}.{}.{}", major, minor, build, revision);
|
return std::format("{}.{}.{}.{}", major, minor, build, revision);
|
||||||
} catch (const winrt::hresult_error& e) { return Err(OsError(e)); } catch (const Exception& e) {
|
} catch (const winrt::hresult_error& e) { return Err(DraconisError(e)); } catch (const Exception& e) {
|
||||||
return Err(OsError(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<String> {
|
fn os::GetWindowManager() -> Option<String> {
|
||||||
if (const Result<Vec<Pair<DWORD, String>>, OsError> processInfoResult = GetProcessInfo()) {
|
if (const Result<Vec<Pair<DWORD, String>>, DraconisError> processInfoResult = GetProcessInfo()) {
|
||||||
const Vec<Pair<DWORD, String>>& processInfo = *processInfoResult;
|
const Vec<Pair<DWORD, String>>& processInfo = *processInfoResult;
|
||||||
|
|
||||||
Vec<String> processNames;
|
Vec<String> processNames;
|
||||||
|
@ -279,7 +288,7 @@ fn os::GetWindowManager() -> Option<String> {
|
||||||
if (IsProcessRunning(processNames, processExe))
|
if (IsProcessRunning(processNames, processExe))
|
||||||
return wmName;
|
return wmName;
|
||||||
} else {
|
} 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;
|
BOOL compositionEnabled = FALSE;
|
||||||
|
@ -295,8 +304,8 @@ fn os::GetDesktopEnvironment() -> Option<String> {
|
||||||
GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "CurrentBuildNumber");
|
GetRegistryValue(HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", "CurrentBuildNumber");
|
||||||
|
|
||||||
if (buildStr.empty()) {
|
if (buildStr.empty()) {
|
||||||
DEBUG_LOG("Failed to get CurrentBuildNumber from registry");
|
debug_log("Failed to get CurrentBuildNumber from registry");
|
||||||
return std::nullopt;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -332,22 +341,25 @@ fn os::GetDesktopEnvironment() -> Option<String> {
|
||||||
// Pre-Win7
|
// Pre-Win7
|
||||||
return "Classic";
|
return "Classic";
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
DEBUG_LOG("Failed to parse CurrentBuildNumber");
|
debug_log("Failed to parse CurrentBuildNumber");
|
||||||
return std::nullopt;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn os::GetShell() -> Option<String> {
|
fn os::GetShell() -> Option<String> {
|
||||||
|
using util::helpers::GetEnv;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const DWORD currentPid =
|
const DWORD currentPid =
|
||||||
winrt::Windows::System::Diagnostics::ProcessDiagnosticInfo::GetForCurrentProcess().ProcessId();
|
winrt::Windows::System::Diagnostics::ProcessDiagnosticInfo::GetForCurrentProcess().ProcessId();
|
||||||
|
|
||||||
if (const Result<String, EnvError> msystemResult = GetEnv("MSYSTEM"); msystemResult && !msystemResult->empty()) {
|
if (const Result<String, DraconisError> msystemResult = GetEnv("MSYSTEM");
|
||||||
|
msystemResult && !msystemResult->empty()) {
|
||||||
String shellPath;
|
String shellPath;
|
||||||
|
|
||||||
if (const Result<String, EnvError> shellResult = GetEnv("SHELL"); shellResult && !shellResult->empty())
|
if (const Result<String, DraconisError> shellResult = GetEnv("SHELL"); shellResult && !shellResult->empty())
|
||||||
shellPath = *shellResult;
|
shellPath = *shellResult;
|
||||||
else if (const Result<String, EnvError> loginShellResult = GetEnv("LOGINSHELL");
|
else if (const Result<String, DraconisError> loginShellResult = GetEnv("LOGINSHELL");
|
||||||
loginShellResult && !loginShellResult->empty())
|
loginShellResult && !loginShellResult->empty())
|
||||||
shellPath = *loginShellResult;
|
shellPath = *loginShellResult;
|
||||||
|
|
||||||
|
@ -355,8 +367,8 @@ fn os::GetShell() -> Option<String> {
|
||||||
const usize lastSlash = shellPath.find_last_of("\\/");
|
const usize lastSlash = shellPath.find_last_of("\\/");
|
||||||
String shellExe = (lastSlash != String::npos) ? shellPath.substr(lastSlash + 1) : shellPath;
|
String shellExe = (lastSlash != String::npos) ? shellPath.substr(lastSlash + 1) : shellPath;
|
||||||
|
|
||||||
std::ranges::transform(shellExe, shellExe.begin(), [](const u8 c) {
|
std::ranges::transform(shellExe, shellExe.begin(), [](const u8 character) {
|
||||||
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
return static_cast<char>(std::tolower(static_cast<unsigned char>(character)));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (shellExe.ends_with(".exe"))
|
if (shellExe.ends_with(".exe"))
|
||||||
|
@ -378,19 +390,23 @@ fn os::GetShell() -> Option<String> {
|
||||||
if (const Option<String> windowsShell = FindShellInProcessTree(currentPid, windowsShellMap))
|
if (const Option<String> windowsShell = FindShellInProcessTree(currentPid, windowsShellMap))
|
||||||
return *windowsShell;
|
return *windowsShell;
|
||||||
} catch (const winrt::hresult_error& e) {
|
} catch (const winrt::hresult_error& e) {
|
||||||
ERROR_LOG("WinRT error during shell detection: {}", winrt::to_string(e.message()));
|
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()); }
|
} catch (const std::exception& e) { error_log("Standard exception during shell detection: {}", e.what()); }
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn os::GetDiskUsage() -> Result<DiskSpace, OsError> {
|
fn os::GetDiskUsage() -> Result<DiskSpace, DraconisError> {
|
||||||
ULARGE_INTEGER freeBytes, totalBytes;
|
ULARGE_INTEGER freeBytes, totalBytes;
|
||||||
|
|
||||||
if (GetDiskFreeSpaceExW(L"C:\\", nullptr, &totalBytes, &freeBytes))
|
if (GetDiskFreeSpaceExW(L"C:\\", nullptr, &totalBytes, &freeBytes))
|
||||||
return DiskSpace { .used_bytes = totalBytes.QuadPart - freeBytes.QuadPart, .total_bytes = totalBytes.QuadPart };
|
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<u64, DraconisError> {
|
||||||
|
return Err(DraconisError(DraconisErrorCode::NotFound, "GetPackageCount not implemented"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue