abridged/src/bridge_irc_sp/network.rs

72 lines
1.7 KiB
Rust

use std::{fmt, io};
use tokio::io::{Lines, AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt};
use log::debug;
use super::message::{Message, parse, ParseError};
#[derive(Debug)]
pub enum ReadMessageError {
String(&'static str),
ParseError(ParseError),
Io(std::io::Error),
}
impl fmt::Display for ReadMessageError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ReadMessageError::String(e) => write!(f, "{e}"),
ReadMessageError::ParseError(e) => write!(f, "{e}"),
ReadMessageError::Io(e) => write!(f, "{e}"),
}
}
}
impl std::error::Error for ReadMessageError {}
pub struct MessageReader<R: AsyncBufRead + Unpin> {
reader: Lines<R>,
buf: String,
}
impl<R: AsyncBufRead + Unpin> MessageReader<R> {
pub fn new(reader: R) -> Self {
Self {
reader: reader.lines(),
buf: String::with_capacity(0),
}
}
pub async fn read_message(&mut self) -> Result<Message, ReadMessageError> {
match self.reader.next_line().await {
Ok(Some(line)) => {
self.buf = line;
parse(&self.buf).map_err(ReadMessageError::ParseError)
}
Ok(None) => Err(ReadMessageError::String("Lost connection to peer server")),
Err(e) => Err(ReadMessageError::Io(e)),
}
}
}
pub struct MessageWriter<W: AsyncWrite + Unpin> {
writer: W,
}
impl<W: AsyncWrite + Unpin> MessageWriter<W> {
pub fn new(writer: W) -> Self {
Self { writer }
}
pub async fn write_msg<'a>(&mut self, msg: Message<'a>) -> Result<(), io::Error> {
let msg = format!("{}\r\n", msg);
debug!("sending message: {:?}", msg);
self.writer.write_all(msg.as_bytes()).await
}
pub async fn flush(&mut self) -> Result<(), io::Error> {
self.writer.flush().await
}
}