Skip to content

Commit 11aeca7

Browse files
committed
wip
1 parent 71a6ac3 commit 11aeca7

File tree

10 files changed

+225
-36
lines changed

10 files changed

+225
-36
lines changed

.direnv/flake-profile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
flake-profile-4-link
1+
flake-profile-5-link

.direnv/flake-profile-4-link

Lines changed: 0 additions & 1 deletion
This file was deleted.

Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@ dbus-crossroads = "0.5.2"
1212
pulse = { version = "2.28.2", package = "libpulse-binding" }
1313
once_cell = "1.20.2"
1414
libloading = "0.8.6"
15-
gtk = { version = "0.9.5", package = "gtk4", features = ["v4_12"] }
15+
gtk = { version = "0.9.6", package = "gtk4", features = ["v4_16"] }
1616
serial_test = "3.2.0"
1717
toml = "0.8.19"
1818
xdg = "2.5.2"
1919
zbus = "5.3.1"
20+
iced = { version = "0.13.1", features = [
21+
"advanced",
22+
"canvas",
23+
"image",
24+
"svg",
25+
"tokio",
26+
] }

flake.lock

Lines changed: 42 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,50 @@
77
url = "github:hercules-ci/flake-parts";
88
inputs.nixpkgs-lib.follows = "nixpkgs";
99
};
10+
rust-overlay.url = "github:oxalica/rust-overlay";
1011
};
1112

12-
outputs =
13-
inputs@{ self, flake-parts, ... }:
14-
flake-parts.lib.mkFlake { inherit inputs; } {
13+
outputs = inputs @ {
14+
self,
15+
flake-parts,
16+
...
17+
}:
18+
flake-parts.lib.mkFlake {inherit inputs;} {
1519
systems = [
1620
"x86_64-linux"
1721
"aarch64-linux"
1822
];
1923

20-
perSystem =
21-
{
22-
pkgs,
23-
system,
24-
...
25-
}:
26-
{
27-
_module.args.pkgs = import self.inputs.nixpkgs {
28-
inherit system;
29-
};
30-
devShells.default = pkgs.mkShell {
31-
nativeBuildInputs = [
32-
pkgs.pkg-config
33-
pkgs.dbus
34-
];
24+
perSystem = {
25+
pkgs,
26+
system,
27+
...
28+
}: {
29+
_module.args.pkgs = import self.inputs.nixpkgs {
30+
inherit system;
31+
overlays = [
32+
(
33+
import
34+
inputs.rust-overlay
35+
)
36+
];
37+
};
38+
devShells.default = pkgs.mkShell {
39+
nativeBuildInputs = [
40+
pkgs.pkg-config
41+
pkgs.dbus
42+
];
3543

36-
buildInputs = [
37-
pkgs.dbus
38-
pkgs.gtk4
39-
pkgs.libadwaita
40-
pkgs.pulseaudio
41-
];
42-
};
44+
buildInputs = [
45+
pkgs.dbus
46+
pkgs.libadwaita
47+
pkgs.pulseaudio
48+
(pkgs.rust-bin.selectLatestNightlyWith
49+
(toolchain: toolchain.default))
50+
pkgs.rust-analyzer
51+
pkgs.clippy
52+
];
4353
};
54+
};
4455
};
4556
}

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![feature(trait_upcasting)]
22
#![feature(string_remove_matches)]
3-
#![feature(unsized_fn_params)]
43
#![feature(unboxed_closures)]
54
#![feature(fn_traits)]
65
use std::{

src/utils/any.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use std::any::TypeId;
2+
use std::fmt::Debug;
3+
4+
use iced::advanced::graphics::futures::MaybeSend;
5+
6+
// Taken from https://doc.rust-lang.org/stable/src/core/any.rs.html
7+
// adjusted to fit ReSet
8+
pub trait ReSetAny: 'static + MaybeSend + Debug + Send + Sync {
9+
fn type_id(&self) -> TypeId;
10+
}
11+
12+
impl<T: 'static + ?Sized + Debug + MaybeSend + Send + Sync> ReSetAny for T {
13+
fn type_id(&self) -> TypeId {
14+
TypeId::of::<T>()
15+
}
16+
}
17+
18+
impl dyn ReSetAny {
19+
#[inline]
20+
pub fn is<T: ReSetAny>(&self) -> bool {
21+
// Get `TypeId` of the type this function is instantiated with.
22+
let t = TypeId::of::<T>();
23+
// Get `TypeId` of the type in the trait object (`self`).
24+
let concrete = self.type_id();
25+
// Compare both `TypeId`s on equality.
26+
t == concrete
27+
}
28+
29+
#[inline]
30+
pub fn downcast_ref<T: ReSetAny>(&self) -> Option<&T> {
31+
if self.is::<T>() {
32+
// SAFETY: just checked whether we are pointing to the correct type, and we can rely on
33+
// that check for memory safety because we have implemented Any for all types; no other
34+
// impls can exist as they would conflict with our impl.
35+
unsafe { Some(self.downcast_ref_unchecked()) }
36+
} else {
37+
None
38+
}
39+
}
40+
41+
#[inline]
42+
pub fn downcast_mut<T: ReSetAny>(&mut self) -> Option<&mut T> {
43+
if self.is::<T>() {
44+
// SAFETY: just checked whether we are pointing to the correct type, and we can rely on
45+
// that check for memory safety because we have implemented Any for all types; no other
46+
// impls can exist as they would conflict with our impl.
47+
unsafe { Some(self.downcast_mut_unchecked()) }
48+
} else {
49+
None
50+
}
51+
}
52+
53+
#[inline]
54+
pub unsafe fn downcast_mut_unchecked<T: ReSetAny>(&mut self) -> &mut T {
55+
debug_assert!(self.is::<T>());
56+
// SAFETY: caller guarantees that T is the correct type
57+
unsafe { &mut *(self as *mut dyn ReSetAny as *mut T) }
58+
}
59+
60+
#[inline]
61+
pub unsafe fn downcast_ref_unchecked<T: ReSetAny>(&self) -> &T {
62+
debug_assert!(self.is::<T>());
63+
// SAFETY: caller guarantees that T is the correct type
64+
unsafe { &*(self as *const dyn ReSetAny as *const T) }
65+
}
66+
}

src/utils/error.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use std::fmt;
2+
3+
pub type ReSetError = Box<dyn TReSetError>;
4+
5+
pub trait TReSetError: fmt::Debug + fmt::Display + Send + Sync + 'static {}
6+
7+
pub fn create_error(err: impl TReSetError) -> ReSetError {
8+
Box::new(err)
9+
}
10+
11+
impl TReSetError for zbus::Error {}
12+
impl From<zbus::Error> for ReSetError {
13+
fn from(value: zbus::Error) -> Self {
14+
create_error(value)
15+
}
16+
}
17+
18+
impl TReSetError for String {}
19+
impl From<String> for ReSetError {
20+
fn from(value: String) -> Self {
21+
create_error(value)
22+
}
23+
}

src/utils/iced_sidebar.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use super::any::ReSetAny;
2+
3+
pub enum EntryButtonLevel {
4+
TopLevel,
5+
SubLevel,
6+
}
7+
8+
pub struct EntryButton {
9+
pub title: &'static str,
10+
pub icon: Option<String>,
11+
pub msg: Box<&'static dyn ReSetAny>,
12+
pub level: EntryButtonLevel,
13+
}
14+
15+
impl EntryButton {
16+
pub fn top_level(
17+
title: &'static str,
18+
icon: Option<impl Into<String>>,
19+
msg: impl Into<Box<&'static dyn ReSetAny>>,
20+
) -> Self {
21+
Self {
22+
title,
23+
icon: icon.map(|icon| icon.into()),
24+
msg: msg.into(),
25+
level: EntryButtonLevel::TopLevel,
26+
}
27+
}
28+
29+
pub fn sub_level(
30+
title: &'static str,
31+
icon: Option<impl Into<String>>,
32+
msg: impl Into<Box<&'static dyn ReSetAny>>,
33+
) -> Self {
34+
Self {
35+
title,
36+
icon: icon.map(|icon| icon.into()),
37+
msg: msg.into(),
38+
level: EntryButtonLevel::SubLevel,
39+
}
40+
}
41+
}
42+
43+
pub struct EntryCategory {
44+
pub main_entry: EntryButton,
45+
pub sub_entries: Vec<EntryButton>,
46+
}

src/utils/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
pub mod any;
12
pub mod config;
23
pub mod dbus_utils;
4+
pub mod error;
35
pub mod flags;
46
pub mod gtk;
7+
pub mod iced_sidebar;
58
pub mod macros;
69
pub mod plugin;
710
pub mod plugin_setup;

0 commit comments

Comments
 (0)