diff options
author | Kunal Mohan <kunalmohan99@gmail.com> | 2021-05-12 20:16:56 +0530 |
---|---|---|
committer | Kunal Mohan <kunalmohan99@gmail.com> | 2021-05-15 22:14:34 +0530 |
commit | c5675e965b9edede26cd26f4658c01ae29b7f2cb (patch) | |
tree | c298a01bc12b6e69e9285784024406a8daef6926 /src | |
parent | f2c43ac577d9d2a93695564cb3185264e3492a68 (diff) |
Use ClientToServerMsg and ServerToClientMsg for IPC
Diffstat (limited to 'src')
-rw-r--r-- | src/client/mod.rs | 39 | ||||
-rw-r--r-- | src/common/errors.rs | 9 | ||||
-rw-r--r-- | src/common/input/handler.rs | 8 | ||||
-rw-r--r-- | src/common/ipc.rs | 32 | ||||
-rw-r--r-- | src/common/os_input_output.rs | 30 | ||||
-rw-r--r-- | src/common/pty.rs | 4 | ||||
-rw-r--r-- | src/common/screen.rs | 4 | ||||
-rw-r--r-- | src/common/wasm_vm.rs | 4 | ||||
-rw-r--r-- | src/server/mod.rs | 35 | ||||
-rw-r--r-- | src/server/route.rs | 28 | ||||
-rw-r--r-- | src/tests/fakes.rs | 23 |
11 files changed, 117 insertions, 99 deletions
diff --git a/src/client/mod.rs b/src/client/mod.rs index 594960eb6..819fddf0c 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -4,7 +4,6 @@ pub mod pane_resizer; pub mod panes; pub mod tab; -use serde::{Deserialize, Serialize}; use std::env::current_exe; use std::io::{self, Write}; use std::path::Path; @@ -15,18 +14,17 @@ use std::thread; use crate::cli::CliArgs; use crate::common::{ command_is_executing::CommandIsExecuting, - errors::{ClientContext, ContextType}, + errors::ContextType, input::config::Config, input::handler::input_loop, - input::options::Options, + ipc::{ClientToServerMsg, ServerToClientMsg}, os_input_output::ClientOsApi, thread_bus::{SenderType, SenderWithContext, SyncChannelWithContext}, utils::consts::ZELLIJ_IPC_PIPE, }; -use crate::server::ServerInstruction; /// Instructions related to the client-side application and sent from server to client -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Debug, Clone)] pub enum ClientInstruction { Error(String), Render(Option<String>), @@ -35,6 +33,17 @@ pub enum ClientInstruction { ServerError(String), } +impl From<ServerToClientMsg> for ClientInstruction { + fn from(instruction: ServerToClientMsg) -> Self { + match instruction { + ServerToClientMsg::Exit => ClientInstruction::Exit, + ServerToClientMsg::Render(buffer) => ClientInstruction::Render(buffer), + ServerToClientMsg::UnblockInputThread => ClientInstruction::UnblockInputThread, + ServerToClientMsg::ServerError(backtrace) => ClientInstruction::ServerError(backtrace), + } + } +} + fn spawn_server(socket_path: &Path) -> io::Result<()> { let status = Command::new(current_exe()?) .arg("--server") @@ -71,7 +80,7 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>, opts: CliArgs, config: C let full_screen_ws = os_input.get_terminal_size_using_fd(0); os_input.connect_to_server(&*ZELLIJ_IPC_PIPE); - os_input.send_to_server(ServerInstruction::NewClient(full_screen_ws, opts)); + os_input.send_to_server(ClientToServerMsg::NewClient(full_screen_ws, opts)); os_input.set_raw_mode(0); let _ = os_input .get_stdout_writer() @@ -117,7 +126,7 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>, opts: CliArgs, config: C os_input.receive_sigwinch(Box::new({ let os_api = os_input.clone(); move || { - os_api.send_to_server(ServerInstruction::TerminalResize( + os_api.send_to_server(ClientToServerMsg::TerminalResize( os_api.get_terminal_size_using_fd(0), )); } @@ -132,15 +141,15 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>, opts: CliArgs, config: C let os_input = os_input.clone(); let mut should_break = false; move || loop { - let (instruction, mut err_ctx) = os_input.recv_from_server(); - err_ctx.add_call(ContextType::Client(ClientContext::from(&instruction))); + let (instruction, err_ctx) = os_input.recv_from_server(); + err_ctx.update_thread_ctx(); match instruction { - ClientInstruction::Exit | ClientInstruction::ServerError(_) => { + ServerToClientMsg::Exit | ServerToClientMsg::ServerError(_) => { should_break = true; } _ => {} } - send_client_instructions.send(instruction).unwrap(); + send_client_instructions.send(instruction.into()).unwrap(); if should_break { break; } @@ -168,13 +177,11 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>, opts: CliArgs, config: C .recv() .expect("failed to receive app instruction on channel"); - err_ctx.add_call(ContextType::Client(ClientContext::from( - &client_instruction, - ))); + err_ctx.add_call(ContextType::Client((&client_instruction).into())); match client_instruction { ClientInstruction::Exit => break, ClientInstruction::Error(backtrace) => { - let _ = os_input.send_to_server(ServerInstruction::ClientExit); + let _ = os_input.send_to_server(ClientToServerMsg::ClientExit); handle_error(backtrace); } ClientInstruction::ServerError(backtrace) => { @@ -196,7 +203,7 @@ pub fn start_client(mut os_input: Box<dyn ClientOsApi>, opts: CliArgs, config: C } } - let _ = os_input.send_to_server(ServerInstruction::ClientExit); + let _ = os_input.send_to_server(ClientToServerMsg::ClientExit); router_thread.join().unwrap(); // cleanup(); diff --git a/src/common/errors.rs b/src/common/errors.rs index c92b9b7f7..262dfd6bc 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -120,6 +120,11 @@ impl ErrorContext { break; } } + self.update_thread_ctx() + } + + /// Updates the thread local [`ErrorContext`]. + pub fn update_thread_ctx(&self) { ASYNCOPENCALLS .try_with(|ctx| *ctx.borrow_mut() = *self) .unwrap_or_else(|_| OPENCALLS.with(|ctx| *ctx.borrow_mut() = *self)); @@ -369,9 +374,7 @@ impl From<&ClientInstruction> for ClientContext { #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] pub enum ServerContext { NewClient, - Action, Render, - TerminalResize, UnblockInputThread, ClientExit, Error, @@ -381,8 +384,6 @@ impl From<&ServerInstruction> for ServerContext { fn from(server_instruction: &ServerInstruction) -> Self { match *server_instruction { ServerInstruction::NewClient(..) => ServerContext::NewClient, - ServerInstruction::Action(_) => ServerContext::Action, - ServerInstruction::TerminalResize(_) => ServerContext::TerminalResize, ServerInstruction::Render(_) => ServerContext::Render, ServerInstruction::UnblockInputThread => ServerContext::UnblockInputThread, ServerInstruction::ClientExit => ServerContext::ClientExit, diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs index b2f4d0a32..4ac2cf839 100644 --- a/src/common/input/handler.rs +++ b/src/common/input/handler.rs @@ -4,10 +4,10 @@ use super::actions::Action; use super::keybinds::Keybinds; use crate::client::ClientInstruction; use crate::common::input::config::Config; +use crate::common::ipc::ClientToServerMsg; use crate::common::thread_bus::{SenderWithContext, OPENCALLS}; use crate::errors::ContextType; use crate::os_input_output::ClientOsApi; -use crate::server::ServerInstruction; use crate::CommandIsExecuting; use termion::input::{TermRead, TermReadEventsAndRaw}; @@ -139,7 +139,7 @@ impl InputHandler { Action::SwitchToMode(mode) => { self.mode = mode; self.os_input - .send_to_server(ServerInstruction::Action(action)); + .send_to_server(ClientToServerMsg::Action(action)); } Action::CloseFocus | Action::NewPane(_) @@ -151,13 +151,13 @@ impl InputHandler { | Action::MoveFocusOrTab(_) => { self.command_is_executing.blocking_input_thread(); self.os_input - .send_to_server(ServerInstruction::Action(action)); + .send_to_server(ClientToServerMsg::Action(action)); self.command_is_executing .wait_until_input_thread_is_unblocked(); } _ => self .os_input - .send_to_server(ServerInstruction::Action(action)), + .send_to_server(ClientToServerMsg::Action(action)), } should_break diff --git a/src/common/ipc.rs b/src/common/ipc.rs index 190680dce..38a2fd4fc 100644 --- a/src/common/ipc.rs +++ b/src/common/ipc.rs @@ -1,10 +1,14 @@ //! IPC stuff for starting to split things into a client and server model. -use crate::common::errors::{get_current_ctx, ErrorContext}; +use crate::cli::CliArgs; +use crate::common::{ + errors::{get_current_ctx, ErrorContext}, + input::actions::Action, +}; +use crate::panes::PositionAndSize; use interprocess::local_socket::LocalSocketStream; use nix::unistd::dup; use serde::{Deserialize, Serialize}; -use std::collections::HashSet; use std::io::{self, Write}; use std::marker::PhantomData; use std::os::unix::io::{AsRawFd, FromRawFd}; @@ -29,9 +33,9 @@ pub enum ClientType { } // Types of messages sent from the client to the server -#[derive(Serialize, Deserialize)] -pub enum _ClientToServerMsg { - // List which sessions are available +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum ClientToServerMsg { + /*// List which sessions are available ListSessions, // Create a new session CreateSession, @@ -40,16 +44,24 @@ pub enum _ClientToServerMsg { // Force detach DetachSession(SessionId), // Disconnect from the session we're connected to - DisconnectFromSession, + DisconnectFromSession,*/ + ClientExit, + TerminalResize(PositionAndSize), + NewClient(PositionAndSize, CliArgs), + Action(Action), } // Types of messages sent from the server to the client -// @@@ Implement Serialize and Deserialize for this... -pub enum _ServerToClientMsg { - // Info about a particular session +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum ServerToClientMsg { + /*// Info about a particular session SessionInfo(Session), // A list of sessions - SessionList(HashSet<Session>), + SessionList(HashSet<Session>),*/ + Render(Option<String>), + UnblockInputThread, + Exit, + ServerError(String), } /// Sends messages on a stream socket, along with an [`ErrorContext`]. diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs index a8d674785..5e7b3ce22 100644 --- a/src/common/os_input_output.rs +++ b/src/common/os_input_output.rs @@ -1,8 +1,8 @@ -use crate::client::ClientInstruction; -use crate::common::ipc::{IpcReceiverWithContext, IpcSenderWithContext}; +use crate::common::ipc::{ + ClientToServerMsg, IpcReceiverWithContext, IpcSenderWithContext, ServerToClientMsg, +}; use crate::errors::ErrorContext; use crate::panes::PositionAndSize; -use crate::server::ServerInstruction; use crate::utils::shared::default_palette; use interprocess::local_socket::LocalSocketStream; use nix::fcntl::{fcntl, FcntlArg, OFlag}; @@ -167,8 +167,8 @@ fn spawn_terminal(file_to_open: Option<PathBuf>, orig_termios: termios::Termios) #[derive(Clone)] pub struct ServerOsInputOutput { orig_termios: Arc<Mutex<termios::Termios>>, - receive_instructions_from_client: Option<Arc<Mutex<IpcReceiverWithContext<ServerInstruction>>>>, - send_instructions_to_client: Arc<Mutex<Option<IpcSenderWithContext<ClientInstruction>>>>, + receive_instructions_from_client: Option<Arc<Mutex<IpcReceiverWithContext<ClientToServerMsg>>>>, + send_instructions_to_client: Arc<Mutex<Option<IpcSenderWithContext<ServerToClientMsg>>>>, } /// The `ServerOsApi` trait represents an abstract interface to the features of an operating system that @@ -192,9 +192,9 @@ pub trait ServerOsApi: Send + Sync { /// Returns a [`Box`] pointer to this [`ServerOsApi`] struct. fn box_clone(&self) -> Box<dyn ServerOsApi>; /// Receives a message on server-side IPC channel - fn recv_from_client(&self) -> (ServerInstruction, ErrorContext); + fn recv_from_client(&self) -> (ClientToServerMsg, ErrorContext); /// Sends a message to client - fn send_to_client(&self, msg: ClientInstruction); + fn send_to_client(&self, msg: ServerToClientMsg); /// Adds a sender to client fn add_client_sender(&mut self); /// Update the receiver socket for the client @@ -233,7 +233,7 @@ impl ServerOsApi for ServerOsInputOutput { waitpid(Pid::from_raw(pid), None).unwrap(); Ok(()) } - fn recv_from_client(&self) -> (ServerInstruction, ErrorContext) { + fn recv_from_client(&self) -> (ClientToServerMsg, ErrorContext) { self.receive_instructions_from_client .as_ref() .unwrap() @@ -241,7 +241,7 @@ impl ServerOsApi for ServerOsInputOutput { .unwrap() .recv() } - fn send_to_client(&self, msg: ClientInstruction) { + fn send_to_client(&self, msg: ServerToClientMsg) { self.send_instructions_to_client .lock() .unwrap() @@ -288,8 +288,8 @@ pub fn get_server_os_input() -> ServerOsInputOutput { #[derive(Clone)] pub struct ClientOsInputOutput { orig_termios: Arc<Mutex<termios::Termios>>, - send_instructions_to_server: Arc<Mutex<Option<IpcSenderWithContext<ServerInstruction>>>>, - receive_instructions_from_server: Arc<Mutex<Option<IpcReceiverWithContext<ClientInstruction>>>>, + send_instructions_to_server: Arc<Mutex<Option<IpcSenderWithContext<ClientToServerMsg>>>>, + receive_instructions_from_server: Arc<Mutex<Option<IpcReceiverWithContext<ServerToClientMsg>>>>, } /// The `ClientOsApi` trait represents an abstract interface to the features of an operating system that @@ -310,10 +310,10 @@ pub trait ClientOsApi: Send + Sync { /// Returns a [`Box`] pointer to this [`ClientOsApi`] struct. fn box_clone(&self) -> Box<dyn ClientOsApi>; /// Sends a message to the server. - fn send_to_server(&self, msg: ServerInstruction); + fn send_to_server(&self, msg: ClientToServerMsg); /// Receives a message on client-side IPC channel // This should be called from the client-side router thread only. - fn recv_from_server(&self) -> (ClientInstruction, ErrorContext); + fn recv_from_server(&self) -> (ServerToClientMsg, ErrorContext); fn receive_sigwinch(&self, cb: Box<dyn Fn()>); /// Establish a connection with the server socket. fn connect_to_server(&self, path: &Path); @@ -346,7 +346,7 @@ impl ClientOsApi for ClientOsInputOutput { let stdout = ::std::io::stdout(); Box::new(stdout) } - fn send_to_server(&self, msg: ServerInstruction) { + fn send_to_server(&self, msg: ClientToServerMsg) { self.send_instructions_to_server .lock() .unwrap() @@ -354,7 +354,7 @@ impl ClientOsApi for ClientOsInputOutput { .unwrap() .send(msg); } - fn recv_from_server(&self) -> (ClientInstruction, ErrorContext) { + fn recv_from_server(&self) -> (ServerToClientMsg, ErrorContext) { self.receive_instructions_from_server .lock() .unwrap() diff --git a/src/common/pty.rs b/src/common/pty.rs index 3c471d6ae..5f5442b51 100644 --- a/src/common/pty.rs +++ b/src/common/pty.rs @@ -8,7 +8,7 @@ use std::pin::*; use std::time::{Duration, Instant}; use crate::client::panes::PaneId; -use crate::common::errors::{get_current_ctx, ContextType, PtyContext}; +use crate::common::errors::{get_current_ctx, ContextType}; use crate::common::screen::ScreenInstruction; use crate::common::thread_bus::{Bus, ThreadSenders}; use crate::layout::Layout; @@ -87,7 +87,7 @@ pub struct Pty { pub fn pty_thread_main(mut pty: Pty, maybe_layout: Option<Layout>) { loop { let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel"); - err_ctx.add_call(ContextType::Pty(PtyContext::from(&event))); + err_ctx.add_call(ContextType::Pty((&event).into())); match event { PtyInstruction::SpawnTerminal(file_to_open) => { let pid = pty.spawn_terminal(file_to_open); diff --git a/src/common/screen.rs b/src/common/screen.rs index bc99f9532..62fcec195 100644 --- a/src/common/screen.rs +++ b/src/common/screen.rs @@ -7,7 +7,7 @@ use std::str; use crate::common::input::options::Options; use crate::common::pty::{PtyInstruction, VteBytes}; use crate::common::thread_bus::Bus; -use crate::errors::{ContextType, ScreenContext}; +use crate::errors::ContextType; use crate::layout::Layout; use crate::panes::PaneId; use crate::panes::PositionAndSize; @@ -353,7 +353,7 @@ pub fn screen_thread_main( .bus .recv() .expect("failed to receive event on channel"); - err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event))); + err_ctx.add_call(ContextType::Screen((&event).into())); match event { ScreenInstruction::PtyBytes(pid, vte_bytes) => { let active_tab = screen.get_active_tab_mut().unwrap(); diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs index e55672851..51eb4ed8d 100644 --- a/src/common/wasm_vm.rs +++ b/src/common/wasm_vm.rs @@ -15,7 +15,7 @@ use wasmer::{ use wasmer_wasi::{Pipe, WasiEnv, WasiState}; use zellij_tile::data::{Event, EventType, PluginIds}; -use crate::common::errors::{ContextType, PluginContext}; +use crate::common::errors::ContextType; use crate::common::pty::PtyInstruction; use crate::common::screen::ScreenInstruction; use crate::common::thread_bus::{Bus, ThreadSenders}; @@ -44,7 +44,7 @@ pub fn wasm_thread_main(bus: Bus<PluginInstruction>, store: Store, data_dir: Pat let mut plugin_map = HashMap::new(); loop { let (event, mut err_ctx) = bus.recv().expect("failed to receive event on channel"); - err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); + err_ctx.add_call(ContextType::Plugin((&event).into())); match event { PluginInstruction::Load(pid_tx, path) => { let plugin_dir = data_dir.join("plugins/"); diff --git a/src/server/mod.rs b/src/server/mod.rs index 884dbee14..96c0a3ce9 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -2,7 +2,6 @@ pub mod route; use daemonize::Daemonize; use interprocess::local_socket::LocalSocketListener; -use serde::{Deserialize, Serialize}; use std::sync::{Arc, RwLock}; use std::thread; use std::{path::PathBuf, sync::mpsc}; @@ -10,11 +9,10 @@ use wasmer::Store; use zellij_tile::data::PluginCapabilities; use crate::cli::CliArgs; -use crate::client::ClientInstruction; use crate::common::thread_bus::{Bus, ThreadSenders}; use crate::common::{ - errors::{ContextType, ServerContext}, - input::{actions::Action, options::Options}, + errors::ContextType, + ipc::{ClientToServerMsg, ServerToClientMsg}, os_input_output::{set_permissions, ServerOsApi}, pty::{pty_thread_main, Pty, PtyInstruction}, screen::{screen_thread_main, ScreenInstruction}, @@ -29,17 +27,25 @@ use route::route_thread_main; /// Instructions related to server-side application including the /// ones sent by client to server -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Debug, Clone)] pub enum ServerInstruction { - TerminalResize(PositionAndSize), - NewClient(PositionAndSize, CliArgs, Options), - Action(Action), + NewClient(PositionAndSize, CliArgs), Render(Option<String>), UnblockInputThread, ClientExit, Error(String), } +impl From<ClientToServerMsg> for ServerInstruction { + fn from(instruction: ClientToServerMsg) -> Self { + match instruction { + ClientToServerMsg::ClientExit => ServerInstruction::ClientExit, + ClientToServerMsg::NewClient(pos, opts) => ServerInstruction::NewClient(pos, opts), + _ => unreachable!(), + } + } +} + pub struct SessionMetaData { pub senders: ThreadSenders, screen_thread: Option<thread::JoinHandle<()>>, @@ -65,6 +71,8 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { .start() .expect("could not daemonize the server process"); + std::env::set_var(&"ZELLIJ", "0"); + let (to_server, server_receiver): SyncChannelWithContext<ServerInstruction> = mpsc::sync_channel(50); let to_server = SenderWithContext::new(SenderType::SyncSender(to_server)); @@ -140,7 +148,7 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { loop { let (instruction, mut err_ctx) = server_receiver.recv().unwrap(); - err_ctx.add_call(ContextType::IPCServer(ServerContext::from(&instruction))); + err_ctx.add_call(ContextType::IPCServer((&instruction).into())); match instruction { ServerInstruction::NewClient(full_screen_ws, opts) => { let session_data = @@ -156,21 +164,20 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { .unwrap(); } ServerInstruction::UnblockInputThread => { - os_input.send_to_client(ClientInstruction::UnblockInputThread); + os_input.send_to_client(ServerToClientMsg::UnblockInputThread); } ServerInstruction::ClientExit => { *sessions.write().unwrap() = None; - os_input.send_to_client(ClientInstruction::Exit); + os_input.send_to_client(ServerToClientMsg::Exit); break; } ServerInstruction::Render(output) => { - os_input.send_to_client(ClientInstruction::Render(output)) + os_input.send_to_client(ServerToClientMsg::Render(output)) } ServerInstruction::Error(backtrace) => { - os_input.send_to_client(ClientInstruction::ServerError(backtrace)); + os_input.send_to_client(ServerToClientMsg::ServerError(backtrace)); break; } - _ => panic!("Received unexpected instruction."), } } drop(std::fs::remove_file(&socket_path)); diff --git a/src/server/route.rs b/src/server/route.rs index bd4b1b608..31b82eb58 100644 --- a/src/server/route.rs +++ b/src/server/route.rs @@ -2,9 +2,9 @@ use std::sync::{Arc, RwLock}; use zellij_tile::data::{Event, PluginCapabilities}; -use crate::common::errors::{ContextType, ServerContext}; use crate::common::input::actions::{Action, Direction}; use crate::common::input::handler::get_mode_info; +use crate::common::ipc::ClientToServerMsg; use crate::common::os_input_output::ServerOsApi; use crate::common::pty::PtyInstruction; use crate::common::screen::ScreenInstruction; @@ -193,23 +193,18 @@ pub fn route_thread_main( capabilities: PluginCapabilities, ) { loop { - let (instruction, mut err_ctx) = os_input.recv_from_client(); - err_ctx.add_call(ContextType::IPCServer(ServerContext::from(&instruction))); + let (instruction, err_ctx) = os_input.recv_from_client(); + err_ctx.update_thread_ctx(); let rlocked_sessions = sessions.read().unwrap(); match instruction { - ServerInstruction::ClientExit => { - to_server.send(instruction).unwrap(); + ClientToServerMsg::ClientExit => { + to_server.send(instruction.into()).unwrap(); break; } - ServerInstruction::Action(action) => { - route_action( - action, - rlocked_sessions.as_ref().unwrap(), - &*os_input, - capabilities, - ); + ClientToServerMsg::Action(action) => { + route_action(action, rlocked_sessions.as_ref().unwrap(), &*os_input); } - ServerInstruction::TerminalResize(new_size) => { + ClientToServerMsg::TerminalResize(new_size) => { rlocked_sessions .as_ref() .unwrap() @@ -217,12 +212,9 @@ pub fn route_thread_main( .send_to_screen(ScreenInstruction::TerminalResize(new_size)) .unwrap(); } - ServerInstruction::NewClient(..) => { + ClientToServerMsg::NewClient(..) => { os_input.add_client_sender(); - to_server.send(instruction).unwrap(); - } - _ => { - to_server.send(instruction).unwrap(); + to_server.send(instruction.into()).unwrap(); } } } |