Skip to main content

sysd_manager_comcontroler/
socket_unit.rs

1use 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::new();
14
15        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        // socket_listen_idx: Cell<usize>,
79        #[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            // let display_name = primary[..split_char_index - 1].to_owned();
137            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}