i think? this is better??
This commit is contained in:
parent
b3e79b56f7
commit
c3b829b68f
11 changed files with 413 additions and 678 deletions
|
@ -20,48 +20,6 @@
|
|||
},
|
||||
"version": "11.1.4"
|
||||
},
|
||||
"reflect-cpp": {
|
||||
"cargoLocks": null,
|
||||
"date": "2025-03-02",
|
||||
"extract": null,
|
||||
"name": "reflect-cpp",
|
||||
"passthru": null,
|
||||
"pinned": false,
|
||||
"src": {
|
||||
"deepClone": false,
|
||||
"fetchSubmodules": false,
|
||||
"leaveDotGit": false,
|
||||
"name": null,
|
||||
"owner": "getml",
|
||||
"repo": "reflect-cpp",
|
||||
"rev": "ec8c19fa3e931d736b3f3ff2e400fce4a5f97829",
|
||||
"sha256": "sha256-3bbaVbU9ICQ8no/3W4M8ePsnrZR3e3CWhT3RO3lL3r0=",
|
||||
"sparseCheckout": [],
|
||||
"type": "github"
|
||||
},
|
||||
"version": "ec8c19fa3e931d736b3f3ff2e400fce4a5f97829"
|
||||
},
|
||||
"sdbus-cpp": {
|
||||
"cargoLocks": null,
|
||||
"date": null,
|
||||
"extract": null,
|
||||
"name": "sdbus-cpp",
|
||||
"passthru": null,
|
||||
"pinned": false,
|
||||
"src": {
|
||||
"deepClone": false,
|
||||
"fetchSubmodules": false,
|
||||
"leaveDotGit": false,
|
||||
"name": null,
|
||||
"owner": "kistler-group",
|
||||
"repo": "sdbus-cpp",
|
||||
"rev": "v2.1.0",
|
||||
"sha256": "sha256-JnjabBr7oELLsUV9a+dAAaRyUzaMIriu90vkaVJg2eY=",
|
||||
"sparseCheckout": [],
|
||||
"type": "github"
|
||||
},
|
||||
"version": "v2.1.0"
|
||||
},
|
||||
"tomlplusplus": {
|
||||
"cargoLocks": null,
|
||||
"date": null,
|
||||
|
@ -82,26 +40,5 @@
|
|||
"type": "github"
|
||||
},
|
||||
"version": "v3.4.0"
|
||||
},
|
||||
"yyjson": {
|
||||
"cargoLocks": null,
|
||||
"date": null,
|
||||
"extract": null,
|
||||
"name": "yyjson",
|
||||
"passthru": null,
|
||||
"pinned": false,
|
||||
"src": {
|
||||
"deepClone": false,
|
||||
"fetchSubmodules": false,
|
||||
"leaveDotGit": false,
|
||||
"name": null,
|
||||
"owner": "ibireme",
|
||||
"repo": "yyjson",
|
||||
"rev": "0.10.0",
|
||||
"sha256": "sha256-mp9Oz08qTyhj3P6F1d81SX96vamUY/JWpD2DTYR+v04=",
|
||||
"sparseCheckout": [],
|
||||
"type": "github"
|
||||
},
|
||||
"version": "0.10.0"
|
||||
}
|
||||
}
|
|
@ -12,29 +12,6 @@
|
|||
sha256 = "sha256-sUbxlYi/Aupaox3JjWFqXIjcaQa0LFjclQAOleT+FRA=";
|
||||
};
|
||||
};
|
||||
reflect-cpp = {
|
||||
pname = "reflect-cpp";
|
||||
version = "ec8c19fa3e931d736b3f3ff2e400fce4a5f97829";
|
||||
src = fetchFromGitHub {
|
||||
owner = "getml";
|
||||
repo = "reflect-cpp";
|
||||
rev = "ec8c19fa3e931d736b3f3ff2e400fce4a5f97829";
|
||||
fetchSubmodules = false;
|
||||
sha256 = "sha256-3bbaVbU9ICQ8no/3W4M8ePsnrZR3e3CWhT3RO3lL3r0=";
|
||||
};
|
||||
date = "2025-03-02";
|
||||
};
|
||||
sdbus-cpp = {
|
||||
pname = "sdbus-cpp";
|
||||
version = "v2.1.0";
|
||||
src = fetchFromGitHub {
|
||||
owner = "kistler-group";
|
||||
repo = "sdbus-cpp";
|
||||
rev = "v2.1.0";
|
||||
fetchSubmodules = false;
|
||||
sha256 = "sha256-JnjabBr7oELLsUV9a+dAAaRyUzaMIriu90vkaVJg2eY=";
|
||||
};
|
||||
};
|
||||
tomlplusplus = {
|
||||
pname = "tomlplusplus";
|
||||
version = "v3.4.0";
|
||||
|
@ -46,15 +23,4 @@
|
|||
sha256 = "sha256-h5tbO0Rv2tZezY58yUbyRVpsfRjY3i+5TPkkxr6La8M=";
|
||||
};
|
||||
};
|
||||
yyjson = {
|
||||
pname = "yyjson";
|
||||
version = "0.10.0";
|
||||
src = fetchFromGitHub {
|
||||
owner = "ibireme";
|
||||
repo = "yyjson";
|
||||
rev = "0.10.0";
|
||||
fetchSubmodules = false;
|
||||
sha256 = "sha256-mp9Oz08qTyhj3P6F1d81SX96vamUY/JWpD2DTYR+v04=";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
192
flake.lock
generated
192
flake.lock
generated
|
@ -1,96 +1,96 @@
|
|||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1739863612,
|
||||
"narHash": "sha256-UbtgxplOhFcyjBcNbTVO8+HUHAl/WXFDOb6LvqShiZo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "632f04521e847173c54fa72973ec6c39a371211c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1735554305,
|
||||
"narHash": "sha256-zExSA1i/b+1NMRhGGLtNfFGXgLtgo+dcuzHzaWA6w3Q=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0e82ab234249d8eee3e8c91437802b32c74bb3fd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix",
|
||||
"utils": "utils"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1739829690,
|
||||
"narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "3d0579f5cc93436052d94b73925b48973a104204",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1741678040,
|
||||
"narHash": "sha256-rmBsz7BBcDwfvDkxnKHmolKceGJrr0nyz5PQYZg0kMk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3ee8818da146871cd570b164fc4f438f78479a50",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1735554305,
|
||||
"narHash": "sha256-zExSA1i/b+1NMRhGGLtNfFGXgLtgo+dcuzHzaWA6w3Q=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0e82ab234249d8eee3e8c91437802b32c74bb3fd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix",
|
||||
"utils": "utils"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1739829690,
|
||||
"narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "3d0579f5cc93436052d94b73925b48973a104204",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
|
|
286
flake.nix
286
flake.nix
|
@ -1,143 +1,143 @@
|
|||
{
|
||||
description = "C/C++ environment";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
treefmt-nix,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
utils.lib.eachDefaultSystem (
|
||||
system: let
|
||||
pkgs = import nixpkgs {inherit system;};
|
||||
|
||||
llvmPackages = with pkgs;
|
||||
if hostPlatform.isLinux
|
||||
then llvmPackages_20
|
||||
else llvmPackages_19;
|
||||
|
||||
stdenv = with pkgs;
|
||||
(
|
||||
if hostPlatform.isLinux
|
||||
then stdenvAdapters.useMoldLinker
|
||||
else lib.id
|
||||
)
|
||||
llvmPackages.stdenv;
|
||||
|
||||
sources = import ./_sources/generated.nix {
|
||||
inherit (pkgs) fetchFromGitHub fetchgit fetchurl dockerTools;
|
||||
};
|
||||
|
||||
fmt = pkgs.pkgsStatic.fmt.overrideAttrs (old: {
|
||||
inherit (sources.fmt) pname version src;
|
||||
});
|
||||
|
||||
tomlplusplus = pkgs.pkgsStatic.tomlplusplus.overrideAttrs {
|
||||
inherit (sources.tomlplusplus) pname version src;
|
||||
doCheck = false;
|
||||
};
|
||||
|
||||
deps = with pkgs.pkgsStatic;
|
||||
[
|
||||
curl
|
||||
fmt
|
||||
libiconv
|
||||
tomlplusplus
|
||||
nlohmann_json
|
||||
sqlitecpp
|
||||
ftxui
|
||||
]
|
||||
++ linuxPkgs;
|
||||
|
||||
linuxPkgs = nixpkgs.lib.optionals stdenv.isLinux (with pkgs;
|
||||
[
|
||||
valgrind
|
||||
]
|
||||
++ (with pkgsStatic; [
|
||||
dbus
|
||||
xorg.libX11
|
||||
wayland
|
||||
]));
|
||||
in
|
||||
with pkgs; {
|
||||
packages = rec {
|
||||
draconisplusplus = stdenv.mkDerivation {
|
||||
name = "draconis++";
|
||||
version = "0.1.0";
|
||||
src = self;
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
buildInputs = deps;
|
||||
|
||||
configurePhase = ''
|
||||
meson setup build
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
meson compile -C build
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
mv build/draconis++ $out/bin/draconis++
|
||||
'';
|
||||
};
|
||||
|
||||
default = draconisplusplus;
|
||||
};
|
||||
|
||||
formatter = treefmt-nix.lib.mkWrapper pkgs {
|
||||
projectRootFile = "flake.nix";
|
||||
programs = {
|
||||
alejandra.enable = true;
|
||||
deadnix.enable = true;
|
||||
|
||||
clang-format = {
|
||||
enable = true;
|
||||
package = pkgs.llvmPackages.clang-tools;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
devShell = mkShell.override {inherit stdenv;} {
|
||||
packages =
|
||||
[
|
||||
alejandra
|
||||
bear
|
||||
llvmPackages.clang-tools
|
||||
cmake
|
||||
lldb
|
||||
hyperfine
|
||||
meson
|
||||
ninja
|
||||
nvfetcher
|
||||
pkg-config
|
||||
unzip
|
||||
|
||||
(writeScriptBin "build" "meson compile -C build")
|
||||
(writeScriptBin "clean" "meson setup build --wipe")
|
||||
(writeScriptBin "run" "meson compile -C build && build/draconis++")
|
||||
]
|
||||
++ deps;
|
||||
|
||||
LD_LIBRARY_PATH = "${lib.makeLibraryPath deps}";
|
||||
NIX_ENFORCE_NO_NATIVE = 0;
|
||||
|
||||
name = "C++";
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
{
|
||||
description = "C/C++ environment";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
treefmt-nix,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
utils.lib.eachDefaultSystem (
|
||||
system: let
|
||||
pkgs = import nixpkgs {inherit system;};
|
||||
|
||||
llvmPackages = with pkgs;
|
||||
if hostPlatform.isLinux
|
||||
then llvmPackages_20
|
||||
else llvmPackages_19;
|
||||
|
||||
stdenv = with pkgs;
|
||||
(
|
||||
if hostPlatform.isLinux
|
||||
then stdenvAdapters.useMoldLinker
|
||||
else lib.id
|
||||
)
|
||||
llvmPackages.stdenv;
|
||||
|
||||
sources = import ./_sources/generated.nix {
|
||||
inherit (pkgs) fetchFromGitHub fetchgit fetchurl dockerTools;
|
||||
};
|
||||
|
||||
fmt = pkgs.pkgsStatic.fmt.overrideAttrs (old: {
|
||||
inherit (sources.fmt) pname version src;
|
||||
});
|
||||
|
||||
tomlplusplus = pkgs.pkgsStatic.tomlplusplus.overrideAttrs {
|
||||
inherit (sources.tomlplusplus) pname version src;
|
||||
doCheck = false;
|
||||
};
|
||||
|
||||
deps = with pkgs.pkgsStatic;
|
||||
[
|
||||
curl
|
||||
fmt
|
||||
ftxui
|
||||
libiconv
|
||||
sqlitecpp
|
||||
tomlplusplus
|
||||
]
|
||||
++ linuxPkgs;
|
||||
|
||||
linuxPkgs = nixpkgs.lib.optionals stdenv.isLinux (with pkgs;
|
||||
[
|
||||
valgrind
|
||||
(glaze.override {enableAvx2 = true;})
|
||||
]
|
||||
++ (with pkgsStatic; [
|
||||
dbus
|
||||
xorg.libX11
|
||||
wayland
|
||||
]));
|
||||
in
|
||||
with pkgs; {
|
||||
packages = rec {
|
||||
draconisplusplus = stdenv.mkDerivation {
|
||||
name = "draconis++";
|
||||
version = "0.1.0";
|
||||
src = self;
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
buildInputs = deps;
|
||||
|
||||
configurePhase = ''
|
||||
meson setup build
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
meson compile -C build
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
mv build/draconis++ $out/bin/draconis++
|
||||
'';
|
||||
};
|
||||
|
||||
default = draconisplusplus;
|
||||
};
|
||||
|
||||
formatter = treefmt-nix.lib.mkWrapper pkgs {
|
||||
projectRootFile = "flake.nix";
|
||||
programs = {
|
||||
alejandra.enable = true;
|
||||
deadnix.enable = true;
|
||||
|
||||
clang-format = {
|
||||
enable = true;
|
||||
package = pkgs.llvmPackages.clang-tools;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
devShell = mkShell.override {inherit stdenv;} {
|
||||
packages =
|
||||
[
|
||||
alejandra
|
||||
bear
|
||||
llvmPackages.clang-tools
|
||||
cmake
|
||||
lldb
|
||||
hyperfine
|
||||
meson
|
||||
ninja
|
||||
nvfetcher
|
||||
pkg-config
|
||||
unzip
|
||||
|
||||
(writeScriptBin "build" "meson compile -C build")
|
||||
(writeScriptBin "clean" "meson setup build --wipe")
|
||||
(writeScriptBin "run" "meson compile -C build && build/draconis++")
|
||||
]
|
||||
++ deps;
|
||||
|
||||
LD_LIBRARY_PATH = "${lib.makeLibraryPath deps}";
|
||||
NIX_ENFORCE_NO_NATIVE = 0;
|
||||
|
||||
name = "C++";
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ project(
|
|||
default_options: [
|
||||
'default_library=static',
|
||||
'warning_level=everything',
|
||||
'buildtype=release',
|
||||
'buildtype=debugoptimized',
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -98,7 +98,7 @@ common_deps = [
|
|||
dependency('fmt', include_type: 'system', static: true),
|
||||
dependency('libcurl', include_type: 'system', static: true),
|
||||
dependency('tomlplusplus', include_type: 'system', static: true),
|
||||
dependency('nlohmann_json', include_type: 'system', static: true),
|
||||
dependency('glaze'),
|
||||
dependency('openssl', include_type: 'system', static: true, required: false),
|
||||
]
|
||||
|
||||
|
@ -122,13 +122,12 @@ elif host_system == 'windows'
|
|||
elif host_system == 'linux' or host_system == 'freebsd'
|
||||
platform_deps += [
|
||||
dependency('SQLiteCpp'),
|
||||
dependency('sdbus-c++'),
|
||||
dependency('x11'),
|
||||
dependency('xcb'),
|
||||
dependency('xau'),
|
||||
dependency('xdmcp'),
|
||||
dependency('wayland-client'),
|
||||
dependency('dbus-1'),
|
||||
dependency('dbus-1', include_type: 'system'),
|
||||
]
|
||||
endif
|
||||
|
||||
|
@ -164,7 +163,7 @@ objc_args = []
|
|||
if host_system == 'darwin'
|
||||
objc_args += ['-fobjc-arc']
|
||||
elif cpp.get_id() == 'clang'
|
||||
link_args += ['-static-libgcc', '-static-libstdc++', '-static']
|
||||
link_args += ['-static-libgcc', '-static-libstdc++']
|
||||
endif
|
||||
|
||||
# ------------------- #
|
||||
|
|
|
@ -2,18 +2,6 @@
|
|||
src.github = "fmtlib/fmt"
|
||||
fetch.github = "fmtlib/fmt"
|
||||
|
||||
[reflect-cpp]
|
||||
src.git = "https://github.com/getml/reflect-cpp"
|
||||
fetch.github = "getml/reflect-cpp"
|
||||
|
||||
[sdbus-cpp]
|
||||
src.github = "kistler-group/sdbus-cpp"
|
||||
fetch.github = "kistler-group/sdbus-cpp"
|
||||
|
||||
[tomlplusplus]
|
||||
src.github = "marzer/tomlplusplus"
|
||||
fetch.github = "marzer/tomlplusplus"
|
||||
|
||||
[yyjson]
|
||||
src.github = "ibireme/yyjson"
|
||||
fetch.github = "ibireme/yyjson"
|
||||
|
|
|
@ -12,56 +12,59 @@
|
|||
#include "src/util/macros.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
using namespace std::string_literals;
|
||||
using namespace nlohmann;
|
||||
using namespace std::string_literals;
|
||||
|
||||
// Alias for cleaner error handling
|
||||
template <typename T>
|
||||
using Result = std::expected<T, std::string>;
|
||||
|
||||
namespace {
|
||||
// Common function to get cache path
|
||||
constexpr glz::opts glaze_opts = { .error_on_unknown_keys = false };
|
||||
|
||||
fn GetCachePath() -> Result<fs::path> {
|
||||
std::error_code errc;
|
||||
fs::path cachePath = fs::temp_directory_path(errc);
|
||||
|
||||
if (errc)
|
||||
return std::unexpected("Failed to get temp directory: "s + errc.message());
|
||||
return std::unexpected("Failed to get temp directory: " + errc.message());
|
||||
|
||||
cachePath /= "weather_cache.json";
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
// Function to read cache from file
|
||||
fn ReadCacheFromFile() -> Result<WeatherOutput> {
|
||||
Result<fs::path> cachePath = GetCachePath();
|
||||
|
||||
if (!cachePath)
|
||||
return std::unexpected(cachePath.error());
|
||||
|
||||
std::ifstream ifs(*cachePath, std::ios::binary);
|
||||
|
||||
if (!ifs.is_open())
|
||||
return std::unexpected("Cache file not found: "s + cachePath->string());
|
||||
return std::unexpected("Cache file not found: " + cachePath->string());
|
||||
|
||||
DEBUG_LOG("Reading from cache file...");
|
||||
|
||||
try {
|
||||
const std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
|
||||
json json = json::parse(content);
|
||||
WeatherOutput result = json.get<WeatherOutput>();
|
||||
WeatherOutput result;
|
||||
glz::error_ctx errc = glz::read<glaze_opts>(result, content);
|
||||
|
||||
if (errc.ec != glz::error_code::none)
|
||||
return std::unexpected("JSON parse error: " + glz::format_error(errc, content));
|
||||
|
||||
DEBUG_LOG("Successfully read from cache file.");
|
||||
return result;
|
||||
} catch (const std::exception& e) { return std::unexpected("JSON parse error: "s + e.what()); }
|
||||
} catch (const std::exception& e) { return std::unexpected("Error reading cache: "s + e.what()); }
|
||||
}
|
||||
|
||||
// Function to write cache to file
|
||||
fn WriteCacheToFile(const WeatherOutput& data) -> Result<void> {
|
||||
Result<fs::path> cachePath = GetCachePath();
|
||||
|
||||
if (!cachePath)
|
||||
return std::unexpected(cachePath.error());
|
||||
|
||||
DEBUG_LOG("Writing to cache file...");
|
||||
|
||||
fs::path tempPath = *cachePath;
|
||||
tempPath += ".tmp";
|
||||
|
||||
|
@ -69,26 +72,29 @@ namespace {
|
|||
{
|
||||
std::ofstream ofs(tempPath, std::ios::binary | std::ios::trunc);
|
||||
if (!ofs.is_open())
|
||||
return std::unexpected("Failed to open temp file: "s + tempPath.string());
|
||||
return std::unexpected("Failed to open temp file: " + tempPath.string());
|
||||
|
||||
json json = data;
|
||||
ofs << json.dump();
|
||||
std::string jsonStr;
|
||||
glz::error_ctx errc = glz::write_json(data, jsonStr);
|
||||
|
||||
if (errc.ec != glz::error_code::none)
|
||||
return std::unexpected("JSON serialization error: " + glz::format_error(errc, jsonStr));
|
||||
|
||||
ofs << jsonStr;
|
||||
if (!ofs)
|
||||
return std::unexpected("Failed to write to temp file");
|
||||
}
|
||||
|
||||
std::error_code errc;
|
||||
fs::rename(tempPath, *cachePath, errc);
|
||||
|
||||
if (errc) {
|
||||
fs::remove(tempPath, errc);
|
||||
return std::unexpected("Failed to replace cache file: "s + errc.message());
|
||||
return std::unexpected("Failed to replace cache file: " + errc.message());
|
||||
}
|
||||
|
||||
DEBUG_LOG("Successfully wrote to cache file.");
|
||||
return {};
|
||||
} catch (const std::exception& e) { return std::unexpected("JSON serialization error: "s + e.what()); }
|
||||
} catch (const std::exception& e) { return std::unexpected("File operation error: "s + e.what()); }
|
||||
}
|
||||
|
||||
fn WriteCallback(void* contents, const size_t size, const size_t nmemb, std::string* str) -> size_t {
|
||||
|
@ -97,10 +103,8 @@ namespace {
|
|||
return totalSize;
|
||||
}
|
||||
|
||||
// Function to make API request
|
||||
fn MakeApiRequest(const std::string& url) -> Result<WeatherOutput> {
|
||||
fn MakeApiRequest(const std::string& url) -> const Result<WeatherOutput> {
|
||||
DEBUG_LOG("Making API request to URL: {}", url);
|
||||
|
||||
CURL* curl = curl_easy_init();
|
||||
std::string responseBuffer;
|
||||
|
||||
|
@ -119,37 +123,38 @@ namespace {
|
|||
if (res != CURLE_OK)
|
||||
return std::unexpected(fmt::format("cURL error: {}", curl_easy_strerror(res)));
|
||||
|
||||
DEBUG_LOG("API response size: {}", responseBuffer.size());
|
||||
DEBUG_LOG("API response: {}", responseBuffer);
|
||||
WeatherOutput output;
|
||||
glz::error_ctx errc = glz::read<glaze_opts>(output, responseBuffer);
|
||||
|
||||
try {
|
||||
json json = json::parse(responseBuffer);
|
||||
WeatherOutput output = json.get<WeatherOutput>();
|
||||
return output;
|
||||
} catch (const std::exception& e) { return std::unexpected("API response parse error: "s + e.what()); }
|
||||
if (errc.ec != glz::error_code::none)
|
||||
return std::unexpected("API response parse error: " + glz::format_error(errc, responseBuffer));
|
||||
|
||||
return std::move(output);
|
||||
}
|
||||
}
|
||||
|
||||
// Core function to get weather information
|
||||
fn Weather::getWeatherInfo() const -> WeatherOutput {
|
||||
using namespace std::chrono;
|
||||
|
||||
if (Result<WeatherOutput> data = ReadCacheFromFile()) {
|
||||
const WeatherOutput& dataVal = *data;
|
||||
const WeatherOutput& dataVal = *data;
|
||||
const duration<double> cacheAge = system_clock::now() - system_clock::time_point(seconds(dataVal.dt));
|
||||
|
||||
if (const duration<double> cacheAge = system_clock::now() - system_clock::time_point(seconds(dataVal.dt));
|
||||
cacheAge < 10min) {
|
||||
if (cacheAge < 10min) {
|
||||
DEBUG_LOG("Using valid cache");
|
||||
return dataVal;
|
||||
}
|
||||
|
||||
DEBUG_LOG("Cache expired");
|
||||
} else {
|
||||
DEBUG_LOG("Cache error: {}", data.error());
|
||||
}
|
||||
|
||||
fn handleApiResult = [](const Result<WeatherOutput>& result) -> WeatherOutput {
|
||||
if (!result)
|
||||
if (!result) {
|
||||
ERROR_LOG("API request failed: {}", result.error());
|
||||
return WeatherOutput {};
|
||||
}
|
||||
|
||||
if (Result<void> writeResult = WriteCacheToFile(*result); !writeResult)
|
||||
ERROR_LOG("Failed to write cache: {}", writeResult.error());
|
||||
|
@ -160,8 +165,8 @@ fn Weather::getWeatherInfo() const -> WeatherOutput {
|
|||
if (std::holds_alternative<std::string>(location)) {
|
||||
const auto& city = std::get<std::string>(location);
|
||||
char* escaped = curl_easy_escape(nullptr, city.c_str(), static_cast<int>(city.length()));
|
||||
|
||||
DEBUG_LOG("Requesting city: {}", escaped);
|
||||
|
||||
const std::string apiUrl =
|
||||
fmt::format("https://api.openweathermap.org/data/2.5/weather?q={}&appid={}&units={}", escaped, api_key, units);
|
||||
|
||||
|
|
|
@ -1,51 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <glaze/glaze.hpp>
|
||||
|
||||
#include "../util/types.h"
|
||||
|
||||
using degrees = unsigned short; // 0-360, validate manually
|
||||
using percentage = unsigned char; // 0-100, validate manually
|
||||
// NOLINTBEGIN(readability-identifier-naming)
|
||||
|
||||
struct Condition {
|
||||
std::string description;
|
||||
std::string icon;
|
||||
std::string main;
|
||||
usize id;
|
||||
|
||||
struct glaze {
|
||||
using T = Condition;
|
||||
static constexpr auto value = glz::object("description", &T::description);
|
||||
};
|
||||
};
|
||||
|
||||
struct Main {
|
||||
f64 feels_like;
|
||||
f64 temp;
|
||||
f64 temp_max;
|
||||
f64 temp_min;
|
||||
isize pressure;
|
||||
percentage humidity;
|
||||
std::optional<isize> grnd_level;
|
||||
std::optional<isize> sea_level;
|
||||
};
|
||||
f64 temp;
|
||||
|
||||
struct Wind {
|
||||
degrees deg;
|
||||
f64 speed;
|
||||
std::optional<f64> gust;
|
||||
};
|
||||
|
||||
struct Precipitation {
|
||||
std::optional<f64> one_hour;
|
||||
std::optional<f64> three_hours;
|
||||
};
|
||||
|
||||
struct Sys {
|
||||
std::string country;
|
||||
usize id;
|
||||
usize sunrise;
|
||||
usize sunset;
|
||||
usize type;
|
||||
};
|
||||
|
||||
struct Clouds {
|
||||
percentage all;
|
||||
struct glaze {
|
||||
using T = Main;
|
||||
static constexpr auto value = glz::object("temp", &T::temp);
|
||||
};
|
||||
};
|
||||
|
||||
struct Coords {
|
||||
|
@ -54,204 +30,15 @@ struct Coords {
|
|||
};
|
||||
|
||||
struct WeatherOutput {
|
||||
Clouds clouds;
|
||||
isize timezone;
|
||||
isize visibility;
|
||||
Main main;
|
||||
Coords coords; // JSON key: "coord"
|
||||
std::optional<Precipitation> rain;
|
||||
std::optional<Precipitation> snow;
|
||||
std::string base;
|
||||
std::string name;
|
||||
std::vector<Condition> weather;
|
||||
Sys sys;
|
||||
usize cod;
|
||||
usize dt;
|
||||
usize id;
|
||||
Wind wind;
|
||||
Main main;
|
||||
std::string name;
|
||||
std::vector<Condition> weather;
|
||||
usize dt;
|
||||
|
||||
struct glaze {
|
||||
using T = WeatherOutput;
|
||||
static constexpr auto value = glz::object("main", &T::main, "name", &T::name, "weather", &T::weather, "dt", &T::dt);
|
||||
};
|
||||
};
|
||||
|
||||
// JSON Serialization Definitions
|
||||
// NOLINTBEGIN(readability-identifier-naming)
|
||||
namespace nlohmann {
|
||||
using namespace nlohmann;
|
||||
template <>
|
||||
struct adl_serializer<Condition> {
|
||||
static void to_json(json& jsonOut, const Condition& cond) {
|
||||
jsonOut = json {
|
||||
{ "description", cond.description },
|
||||
{ "icon", cond.icon },
|
||||
{ "main", cond.main },
|
||||
{ "id", cond.id }
|
||||
};
|
||||
}
|
||||
|
||||
static void from_json(const json& jsonIn, Condition& cond) {
|
||||
jsonIn.at("description").get_to(cond.description);
|
||||
jsonIn.at("icon").get_to(cond.icon);
|
||||
jsonIn.at("main").get_to(cond.main);
|
||||
jsonIn.at("id").get_to(cond.id);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<Main> {
|
||||
static void to_json(json& jsonOut, const Main& main) {
|
||||
jsonOut = json {
|
||||
{ "feels_like", main.feels_like },
|
||||
{ "temp", main.temp },
|
||||
{ "temp_max", main.temp_max },
|
||||
{ "temp_min", main.temp_min },
|
||||
{ "pressure", main.pressure },
|
||||
{ "humidity", main.humidity }
|
||||
};
|
||||
if (main.grnd_level)
|
||||
jsonOut["grnd_level"] = *main.grnd_level;
|
||||
if (main.sea_level)
|
||||
jsonOut["sea_level"] = *main.sea_level;
|
||||
}
|
||||
|
||||
static void from_json(const json& jsonIn, Main& main) {
|
||||
jsonIn.at("feels_like").get_to(main.feels_like);
|
||||
jsonIn.at("temp").get_to(main.temp);
|
||||
jsonIn.at("temp_max").get_to(main.temp_max);
|
||||
jsonIn.at("temp_min").get_to(main.temp_min);
|
||||
jsonIn.at("pressure").get_to(main.pressure);
|
||||
jsonIn.at("humidity").get_to(main.humidity);
|
||||
if (jsonIn.contains("grnd_level"))
|
||||
main.grnd_level = jsonIn["grnd_level"].get<isize>();
|
||||
if (jsonIn.contains("sea_level"))
|
||||
main.sea_level = jsonIn["sea_level"].get<isize>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<Wind> {
|
||||
static void to_json(json& jsonOut, const Wind& wind) {
|
||||
jsonOut = json {
|
||||
{ "deg", wind.deg },
|
||||
{ "speed", wind.speed }
|
||||
};
|
||||
if (wind.gust)
|
||||
jsonOut["gust"] = *wind.gust;
|
||||
}
|
||||
static void from_json(const json& jsonIn, Wind& wind) {
|
||||
jsonIn.at("deg").get_to(wind.deg);
|
||||
jsonIn.at("speed").get_to(wind.speed);
|
||||
if (jsonIn.contains("gust"))
|
||||
wind.gust = jsonIn["gust"].get<f64>();
|
||||
// Validate degrees (0-360)
|
||||
if (wind.deg > 360)
|
||||
throw std::runtime_error("Invalid wind degree");
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<Precipitation> {
|
||||
static void to_json(json& jsonOut, const Precipitation& precip) {
|
||||
if (precip.one_hour)
|
||||
jsonOut["1h"] = *precip.one_hour;
|
||||
if (precip.three_hours)
|
||||
jsonOut["3h"] = *precip.three_hours;
|
||||
}
|
||||
|
||||
static void from_json(const json& jsonIn, Precipitation& precip) {
|
||||
if (jsonIn.contains("1h"))
|
||||
precip.one_hour = jsonIn["1h"].get<f64>();
|
||||
if (jsonIn.contains("3h"))
|
||||
precip.three_hours = jsonIn["3h"].get<f64>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<Sys> {
|
||||
static void to_json(json& jsonOut, const Sys& sys) {
|
||||
jsonOut = json {
|
||||
{ "country", sys.country },
|
||||
{ "id", sys.id },
|
||||
{ "sunrise", sys.sunrise },
|
||||
{ "sunset", sys.sunset },
|
||||
{ "type", sys.type }
|
||||
};
|
||||
}
|
||||
|
||||
static void from_json(const json& jsonIn, Sys& sys) {
|
||||
jsonIn.at("country").get_to(sys.country);
|
||||
jsonIn.at("id").get_to(sys.id);
|
||||
jsonIn.at("sunrise").get_to(sys.sunrise);
|
||||
jsonIn.at("sunset").get_to(sys.sunset);
|
||||
jsonIn.at("type").get_to(sys.type);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<Clouds> {
|
||||
static void to_json(json& jsonOut, const Clouds& clouds) {
|
||||
jsonOut = json {
|
||||
{ "all", clouds.all }
|
||||
};
|
||||
}
|
||||
|
||||
static void from_json(const json& jsonIn, Clouds& clouds) { jsonIn.at("all").get_to(clouds.all); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<Coords> {
|
||||
static void to_json(json& jsonOut, const Coords& coords) {
|
||||
jsonOut = json {
|
||||
{ "lat", coords.lat },
|
||||
{ "lon", coords.lon }
|
||||
};
|
||||
}
|
||||
static void from_json(const json& jsonIn, Coords& coords) {
|
||||
jsonIn.at("lat").get_to(coords.lat);
|
||||
jsonIn.at("lon").get_to(coords.lon);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct adl_serializer<WeatherOutput> {
|
||||
static void to_json(json& jsonOut, const WeatherOutput& weatherOut) {
|
||||
jsonOut = json {
|
||||
{ "clouds", weatherOut.clouds },
|
||||
{ "timezone", weatherOut.timezone },
|
||||
{ "visibility", weatherOut.visibility },
|
||||
{ "main", weatherOut.main },
|
||||
{ "coord", weatherOut.coords },
|
||||
{ "base", weatherOut.base },
|
||||
{ "name", weatherOut.name },
|
||||
{ "weather", weatherOut.weather },
|
||||
{ "sys", weatherOut.sys },
|
||||
{ "cod", weatherOut.cod },
|
||||
{ "dt", weatherOut.dt },
|
||||
{ "id", weatherOut.id },
|
||||
{ "wind", weatherOut.wind }
|
||||
};
|
||||
if (weatherOut.rain)
|
||||
jsonOut["rain"] = *weatherOut.rain;
|
||||
if (weatherOut.snow)
|
||||
jsonOut["snow"] = *weatherOut.snow;
|
||||
}
|
||||
|
||||
static void from_json(const json& jsonIn, WeatherOutput& weatherOut) {
|
||||
jsonIn.at("clouds").get_to(weatherOut.clouds);
|
||||
jsonIn.at("timezone").get_to(weatherOut.timezone);
|
||||
jsonIn.at("visibility").get_to(weatherOut.visibility);
|
||||
jsonIn.at("main").get_to(weatherOut.main);
|
||||
jsonIn.at("coord").get_to(weatherOut.coords);
|
||||
if (jsonIn.contains("rain"))
|
||||
weatherOut.rain = jsonIn["rain"].get<Precipitation>();
|
||||
if (jsonIn.contains("snow"))
|
||||
weatherOut.snow = jsonIn["snow"].get<Precipitation>();
|
||||
jsonIn.at("base").get_to(weatherOut.base);
|
||||
jsonIn.at("name").get_to(weatherOut.name);
|
||||
jsonIn.at("weather").get_to(weatherOut.weather);
|
||||
jsonIn.at("sys").get_to(weatherOut.sys);
|
||||
jsonIn.at("cod").get_to(weatherOut.cod);
|
||||
jsonIn.at("dt").get_to(weatherOut.dt);
|
||||
jsonIn.at("id").get_to(weatherOut.id);
|
||||
jsonIn.at("wind").get_to(weatherOut.wind);
|
||||
}
|
||||
};
|
||||
}
|
||||
// NOLINTEND(readability-identifier-naming)
|
||||
|
|
96
src/main.cpp
96
src/main.cpp
|
@ -166,21 +166,25 @@ namespace {
|
|||
|
||||
content.push_back(text(" Hello " + name + "! ") | bold | color(Color::Cyan));
|
||||
content.push_back(separator() | color(borderColor));
|
||||
content.push_back(hbox({
|
||||
text(" ") | color(iconColor), // Palette icon
|
||||
CreateColorCircles(),
|
||||
}));
|
||||
content.push_back(hbox(
|
||||
{
|
||||
text(" ") | color(iconColor), // Palette icon
|
||||
CreateColorCircles(),
|
||||
}
|
||||
));
|
||||
content.push_back(separator() | color(borderColor));
|
||||
|
||||
// Helper function for aligned rows
|
||||
fn createRow = [&](const std::string& icon, const std::string& label, const std::string& value) {
|
||||
return hbox({
|
||||
text(icon) | color(iconColor),
|
||||
text(label) | color(labelColor),
|
||||
filler(),
|
||||
text(value) | color(valueColor),
|
||||
text(" "),
|
||||
});
|
||||
return hbox(
|
||||
{
|
||||
text(icon) | color(iconColor),
|
||||
text(label) | color(labelColor),
|
||||
filler(),
|
||||
text(value) | color(valueColor),
|
||||
text(" "),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// System info rows
|
||||
|
@ -191,31 +195,39 @@ namespace {
|
|||
const WeatherOutput& weatherInfo = data.weather_info.value();
|
||||
|
||||
if (weather.show_town_name)
|
||||
content.push_back(hbox({
|
||||
text(weatherIcon) | color(iconColor),
|
||||
text("Weather") | color(labelColor),
|
||||
filler(),
|
||||
content.push_back(hbox(
|
||||
{
|
||||
text(weatherIcon) | color(iconColor),
|
||||
text("Weather") | color(labelColor),
|
||||
filler(),
|
||||
|
||||
hbox({
|
||||
text(fmt::format("{}°F ", std::lround(weatherInfo.main.temp))),
|
||||
text("in "),
|
||||
text(weatherInfo.name),
|
||||
text(" "),
|
||||
}) |
|
||||
color(valueColor),
|
||||
}));
|
||||
hbox(
|
||||
{
|
||||
text(fmt::format("{}°F ", std::lround(weatherInfo.main.temp))),
|
||||
text("in "),
|
||||
text(weatherInfo.name),
|
||||
text(" "),
|
||||
}
|
||||
) |
|
||||
color(valueColor),
|
||||
}
|
||||
));
|
||||
else
|
||||
content.push_back(hbox({
|
||||
text(weatherIcon) | color(iconColor),
|
||||
text("Weather") | color(labelColor),
|
||||
filler(),
|
||||
content.push_back(hbox(
|
||||
{
|
||||
text(weatherIcon) | color(iconColor),
|
||||
text("Weather") | color(labelColor),
|
||||
filler(),
|
||||
|
||||
hbox({
|
||||
text(fmt::format("{}°F, {}", std::lround(weatherInfo.main.temp), weatherInfo.weather[0].description)),
|
||||
text(" "),
|
||||
}) |
|
||||
color(valueColor),
|
||||
}));
|
||||
hbox(
|
||||
{
|
||||
text(fmt::format("{}°F, {}", std::lround(weatherInfo.main.temp), weatherInfo.weather[0].description)),
|
||||
text(" "),
|
||||
}
|
||||
) |
|
||||
color(valueColor),
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
content.push_back(separator() | color(borderColor));
|
||||
|
@ -259,14 +271,16 @@ namespace {
|
|||
const std::string& npText = *nowPlayingResult;
|
||||
|
||||
content.push_back(separator() | color(borderColor));
|
||||
content.push_back(hbox({
|
||||
text(musicIcon) | color(iconColor),
|
||||
text("Playing") | color(labelColor),
|
||||
text(" "),
|
||||
filler(),
|
||||
paragraph(npText) | color(Color::Magenta) | size(WIDTH, LESS_THAN, 30),
|
||||
text(" "),
|
||||
}));
|
||||
content.push_back(hbox(
|
||||
{
|
||||
text(musicIcon) | color(iconColor),
|
||||
text("Playing") | color(labelColor),
|
||||
text(" "),
|
||||
filler(),
|
||||
paragraph(npText) | color(Color::Magenta) | size(WIDTH, LESS_THAN, 30),
|
||||
text(" "),
|
||||
}
|
||||
));
|
||||
} else {
|
||||
const NowPlayingError& error = nowPlayingResult.error();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <optional>
|
||||
#include <ranges>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
@ -23,18 +24,36 @@
|
|||
#include "os.h"
|
||||
#include "src/util/macros.h"
|
||||
|
||||
using std::errc, std::expected, std::from_chars, std::getline, std::istreambuf_iterator, std::less, std::lock_guard,
|
||||
std::mutex, std::ofstream, std::pair, std::string_view, std::vector, std::nullopt, std::array, std::optional,
|
||||
std::bit_cast, std::to_string, std::ifstream, std::getenv, std::string, std::unexpected, std::ranges::is_sorted,
|
||||
std::ranges::lower_bound, std::ranges::replace, std::ranges::subrange, std::ranges::transform;
|
||||
|
||||
using namespace std::literals::string_view_literals;
|
||||
// Minimal global using declarations needed for function signatures
|
||||
using std::expected;
|
||||
using std::optional;
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
enum SessionType : u8 { Wayland, X11, TTY, Unknown };
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
namespace {
|
||||
// Local using declarations for the anonymous namespace
|
||||
using std::array;
|
||||
using std::bit_cast;
|
||||
using std::getenv;
|
||||
using std::ifstream;
|
||||
using std::istreambuf_iterator;
|
||||
using std::less;
|
||||
using std::lock_guard;
|
||||
using std::mutex;
|
||||
using std::nullopt;
|
||||
using std::ofstream;
|
||||
using std::pair;
|
||||
using std::string_view;
|
||||
using std::to_string;
|
||||
using std::unexpected;
|
||||
using std::vector;
|
||||
using std::ranges::is_sorted;
|
||||
using std::ranges::lower_bound;
|
||||
using std::ranges::replace;
|
||||
using std::ranges::subrange;
|
||||
using std::ranges::transform;
|
||||
|
||||
fn GetX11WindowManager() -> string {
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
|
||||
|
@ -394,6 +413,8 @@ fn GetOSVersion() -> expected<string, string> {
|
|||
}
|
||||
|
||||
fn GetMemInfo() -> expected<u64, string> {
|
||||
using std::from_chars, std::errc;
|
||||
|
||||
constexpr const char* path = "/proc/meminfo";
|
||||
|
||||
ifstream input(path);
|
||||
|
@ -657,9 +678,20 @@ fn GetDesktopEnvironment() -> optional<string> {
|
|||
}
|
||||
|
||||
fn GetShell() -> string {
|
||||
const char* shell = getenv("SHELL");
|
||||
const string_view shell = getenv("SHELL");
|
||||
|
||||
return shell ? shell : "";
|
||||
if (shell.ends_with("bash"))
|
||||
return "Bash";
|
||||
if (shell.ends_with("zsh"))
|
||||
return "Zsh";
|
||||
if (shell.ends_with("fish"))
|
||||
return "Fish";
|
||||
if (shell.ends_with("nu"))
|
||||
return "Nushell";
|
||||
if (shell.ends_with("sh"))
|
||||
return "SH";
|
||||
|
||||
return !shell.empty() ? string(shell) : "";
|
||||
}
|
||||
|
||||
fn GetHost() -> string {
|
||||
|
@ -691,4 +723,13 @@ fn GetKernelVersion() -> string {
|
|||
return static_cast<const char*>(uts.release);
|
||||
}
|
||||
|
||||
fn GetDiskUsage() -> pair<u64, u64> {
|
||||
struct statvfs stat;
|
||||
if (statvfs("/", &stat) == -1) {
|
||||
ERROR_LOG("statvfs() failed: {}", strerror(errno));
|
||||
return { 0, 0 };
|
||||
}
|
||||
return { (stat.f_blocks * stat.f_frsize) - (stat.f_bfree * stat.f_frsize), stat.f_blocks * stat.f_frsize };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
#include <guiddef.h>
|
||||
#include <variant>
|
||||
#include <winrt/base.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#else
|
||||
#include <variant>
|
||||
#endif
|
||||
|
||||
|
@ -151,13 +149,13 @@ enum class NowPlayingCode : u8 {
|
|||
* @brief Represents a Linux-specific error.
|
||||
*/
|
||||
using LinuxError = std::string;
|
||||
#elif defined(__APPLE__)
|
||||
#elifdef __APPLE__
|
||||
/**
|
||||
* @typedef MacError
|
||||
* @brief Represents a macOS-specific error.
|
||||
*/
|
||||
using MacError = std::string;
|
||||
#elif defined(_WIN32)
|
||||
#elifdef _WIN32
|
||||
/**
|
||||
* @typedef WindowsError
|
||||
* @brief Represents a Windows-specific error.
|
||||
|
@ -170,9 +168,9 @@ using NowPlayingError = std::variant<
|
|||
NowPlayingCode,
|
||||
#ifdef __linux__
|
||||
LinuxError
|
||||
#elif defined(__APPLE__)
|
||||
#elifdef __APPLE__
|
||||
MacError
|
||||
#elif defined(_WIN32)
|
||||
#elifdef _WIN32
|
||||
WindowsError
|
||||
#endif
|
||||
>;
|
||||
|
|
Loading…
Add table
Reference in a new issue