sysd_manager_comcontroler/
socket_unit.rs1use crate::data::{PRIMARY, SYSD_SOCKET_LISTEN_IDX, UnitInfo, convert_to_string};
2
3use glib::{self, object::ObjectExt, subclass::types::ObjectSubclassIsExt};
4use zvariant::OwnedValue;
5
6glib::wrapper! {
7 pub struct SocketUnitInfo(ObjectSubclass<imp::SocketUnitInfoImpl>)
8 @extends UnitInfo;
9}
10
11impl SocketUnitInfo {
12 pub fn from_unit_socket(unit: &UnitInfo, socket_listen_idx: usize) -> Self {
13 let this_object: Self = glib::Object::builder()
16 .property(PRIMARY, unit.primary())
17 .build();
18 this_object.imp().init(unit, socket_listen_idx);
19 let key = glib::Quark::from_str(SYSD_SOCKET_LISTEN_IDX);
20 unsafe { this_object.set_qdata(key, socket_listen_idx) };
21 this_object
22 }
23
24 pub fn get_parent_qproperty<T: 'static>(&self, key: glib::Quark) -> Option<&T> {
25 self.imp().base_unit.borrow().clone().and_then(|a| {
26 unsafe { a.qdata::<T>(key) }.map(|value_ptr| unsafe { value_ptr.as_ref() })
27 })
28 }
29
30 pub fn get_parent_qproperty_to_string<T: 'static + ToString>(
31 &self,
32 key: glib::Quark,
33 ) -> Option<String> {
34 self.get_parent_qproperty::<T>(key).map(|v| v.to_string())
35 }
36
37 pub fn display_custom_property(&self, key: glib::Quark) -> Option<String> {
38 unsafe { self.qdata::<OwnedValue>(key) }
39 .map(|value_ptr| unsafe { value_ptr.as_ref() })
40 .and_then(|value| convert_to_string(value))
41 }
42}
43
44mod imp {
45 use std::cell::{Cell, OnceCell, RefCell};
46
47 use base::enums::UnitDBusLevel;
48 use glib::{
49 self,
50 object::{IsA, ObjectExt},
51 subclass::{
52 object::*,
53 types::{IsSubclassable, ObjectSubclass},
54 },
55 };
56
57 use crate::{
58 data::UnitInfo,
59 enums::{ActiveState, UnitType},
60 };
61
62 #[derive(Debug, glib::Properties, Default)]
63 #[properties(wrapper_type = super::SocketUnitInfo)]
64 pub struct SocketUnitInfoImpl {
65 #[property(get, construct_only, set = Self::set_primary)]
66 pub(super) primary: OnceCell<String>,
67
68 #[property(get = Self::get_display_name, type = String)]
69 display_name: OnceCell<u32>,
70 #[property(get, builder(UnitType::Socket))]
71 unit_type: Cell<UnitType>,
72
73 #[property(get)]
74 socket_listen_idx: Cell<u32>,
75 #[property(get, set, default)]
76 dbus_level: Cell<UnitDBusLevel>,
77
78 #[property(get=Self::get_active_state, set=Self::set_active_state, name="active-state", default, type= ActiveState)]
80 #[property(get=Self::get_unit_path, name="object-path", type = String)]
81 pub(super) base_unit: RefCell<Option<UnitInfo>>,
82 }
83
84 #[glib::object_subclass]
85 impl ObjectSubclass for SocketUnitInfoImpl {
86 const NAME: &'static str = "SocketUnitInfo";
87 type Type = super::SocketUnitInfo;
88 type ParentType = UnitInfo;
89
90 fn new() -> Self {
91 Default::default()
92 }
93 }
94
95 #[glib::derived_properties]
96 impl ObjectImpl for SocketUnitInfoImpl {
97 fn constructed(&self) {
98 self.parent_constructed();
99 }
100 }
101
102 impl SocketUnitInfoImpl {
103 pub(super) fn init(&self, unit: &UnitInfo, socket_listen_idx: usize) {
104 self.dbus_level.replace(unit.dbus_level());
105 self.socket_listen_idx.replace(socket_listen_idx as u32);
106 self.base_unit.replace(Some(unit.clone()));
107 }
108
109 pub fn get_display_name(&self) -> String {
110 let index = *self.display_name.get_or_init(|| unreachable!()) as usize;
111 let s = &self.primary.get().expect("Being set")[..index];
112 s.to_owned()
113 }
114
115 pub fn get_active_state(&self) -> ActiveState {
116 let u = self.base_unit.borrow();
117 let u = u.as_ref().unwrap();
118 u.active_state()
119 }
120
121 pub fn set_active_state(&self, state: ActiveState) {
122 let u = self.base_unit.borrow();
123 let u = u.as_ref().unwrap();
124 u.set_active_state(state)
125 }
126
127 fn set_primary(&self, primary: String) {
128 let mut split_char_index = primary.len();
129 for (i, c) in primary.chars().rev().enumerate() {
130 if c == '.' {
131 split_char_index -= i;
132 break;
133 }
134 }
135
136 self.display_name.set((split_char_index - 1) as u32);
138
139 let unit_type = UnitType::new(&primary[(split_char_index)..]);
140 self.unit_type.set(unit_type);
141 self.primary.set(primary);
142 }
143
144 fn get_unit_path(&self) -> String {
145 let u = self.base_unit.borrow();
146 let u = u.as_ref().unwrap();
147 u.object_path()
148 }
149 }
150
151 pub trait UnitInfoImplTr: ObjectImpl + ObjectSubclass<Type: IsA<UnitInfo>> {}
152
153 unsafe impl<T: UnitInfoImplTr> IsSubclassable<T> for UnitInfo {}
154
155 impl UnitInfoImplTr for SocketUnitInfoImpl {}
156}