Thanks to visit codestin.com
Credit goes to docs.rs

Skip to main content

lightdm_client/
message.rs

1// SPDX-FileCopyrightText: 2026 ZaynChen <[email protected]>
2//
3// SPDX-License-Identifier: MIT
4
5use std::io::{PipeReader, Read};
6
7use super::GreeterError;
8
9#[derive(Debug, Clone, Copy)]
10pub enum ServerMessageType {
11    Connected = 0,
12    PromptAuthentication = 1,
13    EndAuthentication = 2,
14    SessionResult = 3,
15    SharedDirResult = 4,
16    Idle = 5,
17    Reset = 6,
18    ConnectedV2 = 7,
19}
20
21impl TryFrom<u32> for ServerMessageType {
22    type Error = glib::Error;
23
24    fn try_from(value: u32) -> Result<Self, Self::Error> {
25        match value {
26            0 => Ok(Self::Connected),
27            1 => Ok(Self::PromptAuthentication),
28            2 => Ok(Self::EndAuthentication),
29            3 => Ok(Self::SessionResult),
30            4 => Ok(Self::SharedDirResult),
31            5 => Ok(Self::Idle),
32            6 => Ok(Self::Reset),
33            7 => Ok(Self::ConnectedV2),
34            _ => Err(glib::Error::new(
35                GreeterError::Communication,
36                "invalid server message type",
37            )),
38        }
39    }
40}
41
42#[derive(Debug, Clone, Copy)]
43pub enum GreeterMessageType {
44    Connect = 0,
45    Authenticate = 1,
46    AuthenticateAsGuest = 2,
47    ContinueAuthentication = 3,
48    StartSession = 4,
49    CancelAuthentication = 5,
50    SetLanguage = 6,
51    AuthenticateRemote = 7,
52    EnsureSharedDir = 8,
53}
54
55pub(super) struct GreeterMessage {
56    buf: Vec<u8>,
57}
58
59impl GreeterMessage {
60    pub(super) fn builder(id: GreeterMessageType) -> GreeterMessageBuilder {
61        GreeterMessageBuilder::new(id)
62    }
63
64    pub(super) fn into_bytes(self) -> Vec<u8> {
65        self.buf
66    }
67}
68
69pub(super) struct GreeterMessageBuilder {
70    id: GreeterMessageType,
71    buf: Vec<u8>,
72}
73
74impl GreeterMessageBuilder {
75    fn new(id: GreeterMessageType) -> Self {
76        Self {
77            id,
78            buf: Vec::new(),
79        }
80    }
81
82    pub(super) fn arg_u32(mut self, value: u32) -> Self {
83        self.buf.extend(value.to_be_bytes());
84        self
85    }
86
87    pub(super) fn arg_string(mut self, value: String) -> Self {
88        self.buf.extend((value.len() as u32).to_be_bytes());
89        self.buf.extend(value.into_bytes());
90        self
91    }
92
93    pub(super) fn build(self) -> GreeterMessage {
94        let buf = [
95            &(self.id as u32).to_be_bytes(),
96            &(self.buf.len() as u32).to_be_bytes(),
97            self.buf.as_slice(),
98        ]
99        .concat();
100        GreeterMessage { buf }
101    }
102}
103
104#[derive(Debug)]
105pub(super) struct ServerMessage {
106    pub(super) id: ServerMessageType,
107    buf: Vec<u8>,
108}
109
110impl ServerMessage {
111    pub(super) fn from_reader(reader: &mut PipeReader) -> Result<Self, glib::Error> {
112        let id = {
113            let mut buf = [0; 4];
114            reader
115                .read_exact(&mut buf)
116                .map_err(|e| glib::Error::new(GreeterError::Communication, &e.to_string()))?;
117            ServerMessageType::try_from(u32::from_be_bytes(buf))?
118        };
119        let length = {
120            let mut buf = [0; 4];
121            reader
122                .read_exact(&mut buf)
123                .map_err(|e| glib::Error::new(GreeterError::Communication, &e.to_string()))?;
124            u32::from_be_bytes(buf) as usize
125        };
126        let mut buf = vec![0; length];
127        reader
128            .read_exact(&mut buf)
129            .map_err(|e| glib::Error::new(GreeterError::Communication, &e.to_string()))?;
130        glib::g_debug!("", "Read {} bytes from daemon", buf.len() + 8);
131        Ok(Self { id, buf })
132    }
133
134    pub(super) fn reader(&self) -> ServerMessageReader {
135        ServerMessageReader::new(self.buf.clone())
136    }
137}
138
139pub(super) struct ServerMessageReader {
140    data: Vec<u8>,
141}
142
143impl ServerMessageReader {
144    fn new(data: Vec<u8>) -> Self {
145        Self { data }
146    }
147
148    pub(super) fn read_u32(&mut self) -> u32 {
149        if self.data.len() < 4 {
150            glib::g_warning!(
151                "",
152                "Not enough space for u32, need 4, got {}",
153                self.data.len()
154            );
155            0
156        } else {
157            u32::from_be_bytes(self.data.drain(0..4).as_slice().try_into().unwrap())
158        }
159    }
160
161    pub(super) fn read_string(&mut self) -> Option<String> {
162        let length = self.read_u32() as usize;
163        if self.data.len() < length {
164            glib::g_warning!(
165                "",
166                "ServerMessageReader: Not enough space for string ,need {length}, got {}",
167                self.data.len()
168            );
169            None
170        } else {
171            String::from_utf8(self.data.drain(0..length).collect()).ok()
172        }
173    }
174
175    pub(super) fn is_empty(&self) -> bool {
176        self.data.len() == 0
177    }
178}