citadel_sdk/prefabs/
mod.rs1use crate::impl_remote;
62use crate::prefabs::client::peer_connection::FileTransferHandleRx;
63use citadel_io::tokio::sync::mpsc::UnboundedReceiver;
64use citadel_io::Mutex;
65use citadel_proto::prelude::*;
66use std::net::{SocketAddr, ToSocketAddrs};
67use std::ops::{Deref, DerefMut};
68use std::sync::Arc;
69
70pub mod client;
72pub mod server;
74pub mod shared;
76use crate::prelude::user_ids::TargetLockedRemote;
77use crate::remote_ext::results::LocalGroupPeer;
78use crate::remote_ext::ProtocolRemoteExt;
79
80#[derive(Clone)]
83pub struct ClientServerRemote<R: Ratchet> {
84 pub(crate) inner: NodeRemote<R>,
85 pub(crate) unprocessed_signals_rx: Arc<Mutex<Option<UnboundedReceiver<NodeResult<R>>>>>,
86 pub(crate) file_transfer_handle_rx: Arc<Mutex<Option<FileTransferHandleRx>>>,
87 conn_type: VirtualTargetType,
88 session_security_settings: SessionSecuritySettings,
89}
90
91impl<R: Ratchet> Deref for ClientServerRemote<R> {
92 type Target = NodeRemote<R>;
93 fn deref(&self) -> &Self::Target {
94 &self.inner
95 }
96}
97
98impl<R: Ratchet> DerefMut for ClientServerRemote<R> {
99 fn deref_mut(&mut self) -> &mut Self::Target {
100 &mut self.inner
101 }
102}
103
104impl_remote!(ClientServerRemote);
105
106impl<R: Ratchet> ClientServerRemote<R> {
107 pub fn new(
109 conn_type: VirtualTargetType,
110 remote: NodeRemote<R>,
111 session_security_settings: SessionSecuritySettings,
112 unprocessed_signals_rx: Option<UnboundedReceiver<NodeResult<R>>>,
113 file_transfer_handle_rx: Option<FileTransferHandleRx>,
114 ) -> Self {
115 Self {
117 inner: remote,
118 unprocessed_signals_rx: Arc::new(Mutex::new(unprocessed_signals_rx)),
119 file_transfer_handle_rx: Arc::new(Mutex::new(file_transfer_handle_rx)),
120 conn_type,
121 session_security_settings,
122 }
123 }
124 pub fn get_unprocessed_signals_receiver(
126 &self,
127 ) -> Option<citadel_io::tokio::sync::mpsc::UnboundedReceiver<NodeResult<R>>> {
128 self.unprocessed_signals_rx.lock().take()
129 }
130
131 pub fn get_incoming_file_transfer_handle(&self) -> Result<FileTransferHandleRx, NetworkError> {
133 self.file_transfer_handle_rx
134 .lock()
135 .take()
136 .ok_or(citadel_io::error!(
137 citadel_io::ErrorCode::RemoteFunctionAlreadyCalled
138 ))
139 }
140}
141
142impl<R: Ratchet> TargetLockedRemote<R> for ClientServerRemote<R> {
143 fn user(&self) -> &VirtualTargetType {
144 &self.conn_type
145 }
146 fn remote(&self) -> &NodeRemote<R> {
147 &self.inner
148 }
149 fn target_username(&self) -> Option<&str> {
150 None
151 }
152 fn user_mut(&mut self) -> &mut VirtualTargetType {
153 &mut self.conn_type
154 }
155
156 fn session_security_settings(&self) -> Option<&SessionSecuritySettings> {
157 Some(&self.session_security_settings)
158 }
159}
160
161impl<R: Ratchet> ClientServerRemote<R> {
162 pub async fn shutdown_kernel(&self) -> Result<(), NetworkError> {
164 self.inner.shutdown().await
165 }
166
167 pub async fn get_peers(
168 &self,
169 limit: Option<usize>,
170 ) -> Result<Vec<LocalGroupPeer>, NetworkError> {
171 let session_cid = self.conn_type.get_session_cid();
172 let peer_info = self.inner.get_local_group_peers(session_cid, limit).await?;
173 Ok(peer_info
174 .iter()
175 .map(|info| LocalGroupPeer {
176 cid: info.cid,
177 is_online: info.is_online,
178 })
179 .collect())
180 }
181}
182
183pub fn get_socket_addr<T: ToSocketAddrs>(addr: T) -> Result<SocketAddr, NetworkError> {
184 addr.to_socket_addrs()
185 .map_err(|err| NetworkError::socket(err.to_string()))?
186 .next()
187 .ok_or_else(|| citadel_io::error!(citadel_io::ErrorCode::BuilderInvalidSocketAddress))
188}