To handle the commands received by the FTP server, we'll have a Client struct:
type Writer = SplitSink<Framed<TcpStream, FtpCodec>>; struct Client { writer: Writer, }
The client contains a Writer object that will be useful to send messages to the client. The Writer type represents a Sink that has been split, and uses the FtpCodec on a TcpStream. A Sink is the opposite of a Stream: instead of representing a sequence of values that are received, it represents a sequence of values that are sent.
We used two methods on Client, so let's write them:
use cmd::Command; impl Client { fn new(writer: Writer) -> Client { Client { writer, } } #[async] fn handle_cmd(mut self, cmd: Command) -> Result<Self> { Ok(self) } }
The constructor is very simple and creates the struct with the provided argument. The handle_cmd() receives the command sent to the FTP server by this specific client and will handle them; we'll write the code to handle them progressively in this chapter and the next. For now, it only returns self. Also, take note that this method receives self by move, instead of by reference. This is due to a current limitation of the futures-await crate: for now, async functions cannot take a reference. This issue will probably be fixed later, which will make the code even better. This is why we reassigned to the client variable in the client function:
client = await!(client.handle_cmd(cmd))?;