ssh_commander_core/
rdp_client.rs1use crate::desktop_protocol::{DesktopProtocol, FrameUpdate, RdpConfig};
2use anyhow::Result;
3use async_trait::async_trait;
4use tokio::sync::mpsc;
5use tokio_util::sync::CancellationToken;
6
7pub struct RdpClient {
15 config: RdpConfig,
16 desktop_width: u16,
17 desktop_height: u16,
18 connected: bool,
19}
20
21impl RdpClient {
22 pub async fn connect(config: &RdpConfig) -> Result<Self> {
28 if config.host.is_empty() {
29 return Err(anyhow::anyhow!("RDP host cannot be empty"));
30 }
31 if config.username.is_empty() {
32 return Err(anyhow::anyhow!(
33 "RDP username is required for NLA authentication"
34 ));
35 }
36
37 Err(anyhow::anyhow!(
45 "RDP protocol support is not yet implemented. \
46 Connection to {}:{} cannot be established.",
47 config.host,
48 config.port
49 ))
50 }
51
52 #[allow(dead_code)]
54 fn new_disconnected(config: RdpConfig) -> Self {
55 Self {
56 desktop_width: config.width,
57 desktop_height: config.height,
58 config,
59 connected: false,
60 }
61 }
62}
63
64#[async_trait]
65impl DesktopProtocol for RdpClient {
66 async fn start_frame_loop(
67 &self,
68 _frame_tx: mpsc::UnboundedSender<FrameUpdate>,
69 _cancel: CancellationToken,
70 ) -> Result<()> {
71 if !self.connected {
72 return Err(anyhow::anyhow!("RDP client is not connected"));
73 }
74 Ok(())
76 }
77
78 async fn send_key(&self, _key_code: u32, _down: bool) -> Result<()> {
79 if !self.connected {
80 return Err(anyhow::anyhow!("RDP client is not connected"));
81 }
82 Ok(())
84 }
85
86 async fn send_pointer(&self, _x: u16, _y: u16, _button_mask: u8) -> Result<()> {
87 if !self.connected {
88 return Err(anyhow::anyhow!("RDP client is not connected"));
89 }
90 Ok(())
92 }
93
94 async fn request_full_frame(&self) -> Result<()> {
95 if !self.connected {
96 return Err(anyhow::anyhow!("RDP client is not connected"));
97 }
98 Ok(())
100 }
101
102 async fn set_clipboard(&self, _text: String) -> Result<()> {
103 if !self.connected {
104 return Err(anyhow::anyhow!("RDP client is not connected"));
105 }
106 Ok(())
108 }
109
110 fn desktop_size(&self) -> (u16, u16) {
111 (self.desktop_width, self.desktop_height)
112 }
113
114 async fn resize(&mut self, width: u16, height: u16) -> Result<()> {
115 if !self.connected {
116 return Err(anyhow::anyhow!("RDP client is not connected"));
117 }
118 self.desktop_width = width;
121 self.desktop_height = height;
122 Ok(())
123 }
124
125 async fn disconnect(&mut self) -> Result<()> {
126 if self.connected {
127 self.connected = false;
129 tracing::info!(
130 "RDP disconnected from {}:{}",
131 self.config.host,
132 self.config.port
133 );
134 }
135 Ok(())
136 }
137}