diff --git a/include/argparse.hpp b/include/argparse.hpp index 10c24e5..7662bae 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -2117,7 +2117,7 @@ namespace argparse { }; fn consume_digits = [=](StringView sd) -> StringView { - const char* const it = std::ranges::find_if_not(sd, is_digit); + const auto it = std::ranges::find_if_not(sd, is_digit); return sd.substr(static_cast(it - std::begin(sd))); }; diff --git a/include/matchit.hpp b/include/matchit.hpp index c2a8747..cea514a 100644 --- a/include/matchit.hpp +++ b/include/matchit.hpp @@ -1762,13 +1762,9 @@ namespace matchit { template constexpr fn asDsVia = [](auto... members) { return [members...](auto... pats) { return as(and_(app(members, pats)...)); }; }; - constexpr fn within = [](const auto& first, const auto& last) { + constexpr fn in = [](const auto& first, const auto& last) { return meet([=](auto&& v) { return first <= v && v <= last; }); }; - - constexpr fn between = [](const auto& first, const auto& last) { - return meet([=](auto&& v) { return first < v && v < last; }); - }; } // namespace impl using impl::_; @@ -1780,6 +1776,7 @@ namespace matchit { using impl::dsVia; using impl::expr; using impl::Id; + using impl::in; using impl::is; using impl::match; using impl::matched; @@ -1792,6 +1789,5 @@ namespace matchit { using impl::Subrange; using impl::SubrangeT; using impl::when; - using impl::within; } // namespace matchit // NOLINTEND(readability-identifier-*, cppcoreguidelines-special-member-functions) \ No newline at end of file diff --git a/src/config/config.cpp b/src/config/config.cpp index 0b38c43..9b00b46 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -53,15 +53,15 @@ location = "London" # Your city name #ifdef _WIN32 if (Result result = GetEnv("LOCALAPPDATA")) - possiblePaths.push_back(fs::path(*result) / "draconis++" / "config.toml"); + possiblePaths.emplace_back(fs::path(*result) / "draconis++" / "config.toml"); if (Result result = GetEnv("USERPROFILE")) { - possiblePaths.push_back(fs::path(*result) / ".config" / "draconis++" / "config.toml"); - possiblePaths.push_back(fs::path(*result) / "AppData" / "Local" / "draconis++" / "config.toml"); + possiblePaths.emplace_back(fs::path(*result) / ".config" / "draconis++" / "config.toml"); + possiblePaths.emplace_back(fs::path(*result) / "AppData" / "Local" / "draconis++" / "config.toml"); } if (Result result = GetEnv("APPDATA")) - possiblePaths.push_back(fs::path(*result) / "draconis++" / "config.toml"); + possiblePaths.emplace_back(fs::path(*result) / "draconis++" / "config.toml"); #else if (Result result = GetEnv("XDG_CONFIG_HOME")) possiblePaths.emplace_back(fs::path(*result) / "draconis++" / "config.toml"); @@ -72,7 +72,7 @@ location = "London" # Your city name } #endif - possiblePaths.push_back(fs::path(".") / "config.toml"); + possiblePaths.emplace_back(fs::path(".") / "config.toml"); for (const fs::path& path : possiblePaths) if (std::error_code errc; fs::exists(path, errc) && !errc) @@ -104,31 +104,6 @@ location = "London" # Your city name return false; } - String defaultName; - -#ifdef _WIN32 - Array username; - - DWORD size = sizeof(username); - - if (GetUserNameA(username.data(), &size)) { - defaultName = username.data(); - } else { - debug_log("Failed to get username: {}", GetLastError()); - defaultName = "User"; - } -#else - const passwd* pwd = getpwuid(getuid()); - CStr pwdName = pwd ? pwd->pw_name : nullptr; - - const Result envUser = util::helpers::GetEnv("USER"); - const Result envLogname = util::helpers::GetEnv("LOGNAME"); - - defaultName = pwdName ? pwdName : envUser ? *envUser - : envLogname ? *envLogname - : "User"; -#endif - std::ofstream file(configPath); if (!file) { error_log("Failed to open config file for writing: {}", configPath.string()); @@ -136,18 +111,14 @@ location = "London" # Your city name } try { - const String formattedConfig = std::format(defaultConfigTemplate, defaultName); + const String defaultName = General::getDefaultName(); + + const String formattedConfig = std::vformat(defaultConfigTemplate, std::make_format_args(defaultName)); + file << formattedConfig; } catch (const std::format_error& fmtErr) { - error_log("Failed to format default config string: {}. Using fallback name 'User'.", fmtErr.what()); - - try { - const String fallbackConfig = std::format(defaultConfigTemplate, "User"); - file << fallbackConfig; - } catch (...) { - error_log("Failed to format default config even with fallback name."); - return false; - } + error_log("Failed to format default config string: {}", fmtErr.what()); + return false; } if (!file) { @@ -189,9 +160,7 @@ fn Config::getInstance() -> Config { const bool exists = fs::exists(configPath, errc); if (errc) - warn_log( - "Failed to check if config file exists at {}: {}. Assuming it doesn't.", configPath.string(), errc.message() - ); + warn_log("Failed to check if config file exists at {}: {}. Assuming it doesn't.", configPath.string(), errc.message()); if (!exists) { info_log("Config file not found at {}, creating defaults.", configPath.string()); @@ -205,12 +174,15 @@ fn Config::getInstance() -> Config { const toml::table config = toml::parse_file(configPath.string()); debug_log("Config loaded from {}", configPath.string()); + return Config(config); } catch (const Exception& e) { debug_log("Config loading failed: {}, using defaults", e.what()); + return {}; } catch (...) { error_log("An unexpected error occurred during config loading. Using in-memory defaults."); + return {}; } } diff --git a/src/config/config.hpp b/src/config/config.hpp index 2936923..7bad8a4 100644 --- a/src/config/config.hpp +++ b/src/config/config.hpp @@ -47,25 +47,22 @@ struct General { #ifdef _WIN32 // Try to get the username using GetUserNameA Array username; - DWORD size = sizeof(username); + + DWORD size = username.size(); + return GetUserNameA(username.data(), &size) ? username.data() : "User"; #else using util::helpers::GetEnv; - // Try to get the username using getpwuid - if (const passwd* pwd = getpwuid(getuid())) - return pwd->pw_name; + const passwd* pwd = getpwuid(getuid()); + CStr pwdName = pwd ? pwd->pw_name : nullptr; + const Result envUser = GetEnv("USER"); + const Result envLogname = GetEnv("LOGNAME"); - // Try to get the username using environment variables - if (Result envUser = GetEnv("USER")) - return *envUser; - - // Finally, try to get the username using LOGNAME - if (Result envLogname = GetEnv("LOGNAME")) - return *envLogname; - - // If all else fails, return a default name - return "User"; + return pwdName ? pwdName + : envUser ? *envUser + : envLogname ? *envLogname + : "User"; #endif } diff --git a/src/core/system_data.cpp b/src/core/system_data.cpp index b4edd61..670b1ee 100644 --- a/src/core/system_data.cpp +++ b/src/core/system_data.cpp @@ -21,14 +21,14 @@ namespace { using util::types::i32, util::types::CStr; fn getOrdinalSuffix(const i32 day) -> CStr { - using matchit::match, matchit::is, matchit::_, matchit::within; + using matchit::match, matchit::is, matchit::_, matchit::in; return match(day % 10)( - is | within(11, 13) = "th", - is | 1 = "st", - is | 2 = "nd", - is | 3 = "rd", - is | _ = "th" + is | in(11, 13) = "th", + is | 1 = "st", + is | 2 = "nd", + is | 3 = "rd", + is | _ = "th" ); } @@ -83,23 +83,25 @@ namespace os { Future> shellFut = std::async(async, GetShell); Future> pkgFut = std::async(async, GetTotalCount); Future> npFut = std::async(config.nowPlaying.enabled ? async : deferred, GetNowPlaying); - Future> wthrFut = - std::async(config.weather.enabled ? async : deferred, [&config] { return config.weather.getWeatherInfo(); }); + Future> wthrFut = std::async(config.weather.enabled ? async : deferred, [&config] { + return config.weather.getWeatherInfo(); + }); - this->date = getDate(); - this->host = hostFut.get(); - this->kernelVersion = kernelFut.get(); - this->osVersion = osFut.get(); - this->memInfo = memFut.get(); - this->desktopEnv = deFut.get(); - this->windowMgr = wmFut.get(); - this->diskUsage = diskFut.get(); - this->shell = shellFut.get(); - this->packageCount = pkgFut.get(); - this->weather = - config.weather.enabled ? wthrFut.get() : Err(DracError(DracErrorCode::ApiUnavailable, "Weather API disabled")); - this->nowPlaying = config.nowPlaying.enabled - ? npFut.get() - : Err(DracError(DracErrorCode::ApiUnavailable, "Now Playing API disabled")); + { + using enum util::error::DracErrorCode; + + this->date = getDate(); + this->host = hostFut.get(); + this->kernelVersion = kernelFut.get(); + this->osVersion = osFut.get(); + this->memInfo = memFut.get(); + this->desktopEnv = deFut.get(); + this->windowMgr = wmFut.get(); + this->diskUsage = diskFut.get(); + this->shell = shellFut.get(); + this->packageCount = pkgFut.get(); + this->weather = config.weather.enabled ? wthrFut.get() : Err(DracError(ApiUnavailable, "Weather API disabled")); + this->nowPlaying = config.nowPlaying.enabled ? npFut.get() : Err(DracError(ApiUnavailable, "Now Playing API disabled")); + } } } // namespace os