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