use crate::pixmap::Color;
use crate::texts;
use std::fmt::{Display, Formatter};
use std::io::Write;
use tokio::io::{AsyncWrite, AsyncWriteExt};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum HelpTopic {
General,
Size,
Px,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Request {
Help(HelpTopic),
GetSize,
GetPixel {
x: usize,
y: usize,
},
SetPixel {
x: usize,
y: usize,
color: Color,
},
}
impl Request {
pub fn write(&self, writer: &mut impl Write) -> std::io::Result<()> {
match self {
Request::Help(topic) => match topic {
HelpTopic::General => writer.write_all("HELP\n".as_bytes()),
HelpTopic::Size => writer.write_all("HELP SIZE\n".as_bytes()),
HelpTopic::Px => writer.write_all("HELP PX\n".as_bytes()),
},
Request::GetSize => writer.write_all("SIZE\n".as_bytes()),
Request::GetPixel { x, y } => writer.write_all(format!("PX {} {}\n", x, y).as_bytes()),
Request::SetPixel { x, y, color } => {
writer.write_all(format!("PX {} {} {:X}\n", x, y, color).as_bytes())
}
}
}
pub async fn write_async(&self, writer: &mut (impl AsyncWrite + Unpin)) -> std::io::Result<()> {
match self {
Request::Help(topic) => match topic {
HelpTopic::General => writer.write_all("HELP\n".as_bytes()).await,
HelpTopic::Size => writer.write_all("HELP SIZE\n".as_bytes()).await,
HelpTopic::Px => writer.write_all("HELP PX\n".as_bytes()).await,
},
Request::GetSize => writer.write_all("SIZE\n".as_bytes()).await,
Request::GetPixel { x, y } => writer.write_all(format!("PX {} {}\n", x, y).as_bytes()).await,
Request::SetPixel { x, y, color } => {
writer
.write_all(format!("PX {} {} {:X}\n", x, y, color).as_bytes())
.await
}
}
}
}
impl Display for Request {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Request::Help(topic) => match topic {
HelpTopic::General => f.write_str("HELP"),
HelpTopic::Size => f.write_str("HELP SIZE"),
HelpTopic::Px => f.write_str("HELP PX"),
},
Request::GetSize => f.write_str("SIZE"),
Request::GetPixel { x, y } => f.write_fmt(format_args!("PX {} {}", x, y)),
Request::SetPixel { x, y, color } => f.write_fmt(format_args!("PX {} {} {:X}", x, y, color)),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Response {
Help(HelpTopic),
Size {
width: usize,
height: usize,
},
PxData {
x: usize,
y: usize,
color: Color,
},
}
impl Response {
pub fn write(&self, writer: &mut impl Write) -> std::io::Result<()> {
match self {
Response::Help(topic) => match topic {
HelpTopic::General => writer.write_all(texts::HELP_GENERAL.as_bytes()),
HelpTopic::Size => writer.write_all(texts::HELP_SIZE.as_bytes()),
HelpTopic::Px => writer.write_all(texts::HELP_PX.as_bytes()),
},
Response::Size { width, height } => {
writer.write_all(format!("SIZE {} {}\n", width, height).as_bytes())
}
Response::PxData { x, y, color } => {
writer.write_all(format!("PX {} {} {:X}\n", x, y, color).as_bytes())
}
}
}
pub async fn write_async(&self, writer: &mut (impl AsyncWrite + Unpin)) -> std::io::Result<()> {
match self {
Response::Help(topic) => match topic {
HelpTopic::General => writer.write_all(texts::HELP_GENERAL.as_bytes()).await,
HelpTopic::Size => writer.write_all(texts::HELP_SIZE.as_bytes()).await,
HelpTopic::Px => writer.write_all(texts::HELP_PX.as_bytes()).await,
},
Response::Size { width, height } => {
writer
.write_all(format!("SIZE {} {}\n", width, height).as_bytes())
.await
}
Response::PxData { x, y, color } => {
writer
.write_all(format!("PX {} {} {:X}\n", x, y, color).as_bytes())
.await
}
}
}
}
impl Display for Response {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Response::Help(topic) => match topic {
HelpTopic::General => f.write_str(texts::HELP_GENERAL),
HelpTopic::Size => f.write_str(texts::HELP_SIZE),
HelpTopic::Px => f.write_str(texts::HELP_PX),
},
Response::Size { width, height } => f.write_fmt(format_args!("SIZE {} {}", width, height)),
Response::PxData { x, y, color } => f.write_fmt(format_args!("PX {} {} {:X}", x, y, color)),
}
}
}