forked from lavina/lavina
1
0
Fork 0
lavina/crates/proto-irc/src/response.rs

52 lines
1.5 KiB
Rust
Raw Normal View History

use std::future::Future;
use tokio::io::{AsyncWrite, AsyncWriteExt};
use crate::prelude::Str;
use crate::Tag;
pub trait SendResponseBody {
fn write_response(self, writer: &mut (impl AsyncWrite + Unpin)) -> impl Future<Output = std::io::Result<()>>;
}
pub trait SendResponseMessage<Message> {
fn write_response(self, writer: &mut (impl AsyncWrite + Unpin)) -> impl Future<Output = std::io::Result<()>>;
}
/// Server-to-client enum agnostic message
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct IrcResponseMessage<T: SendResponseBody> {
/// Optional tags section, prefixed with `@`
pub tags: Vec<Tag>,
/// Optional server name, prefixed with `:`.
pub sender: Option<Str>,
pub body: T,
}
impl<T: SendResponseBody> IrcResponseMessage<T> {
pub fn empty_tags(sender: Option<Str>, body: T) -> Self {
IrcResponseMessage {
tags: vec![],
sender,
body,
}
}
pub fn new(tags: Vec<Tag>, sender: Option<Str>, body: T) -> Self {
IrcResponseMessage { tags, sender, body }
}
}
impl<T: SendResponseBody> SendResponseMessage<IrcResponseMessage<T>> for IrcResponseMessage<T> {
async fn write_response(self, writer: &mut (impl AsyncWrite + Unpin)) -> std::io::Result<()> {
if let Some(sender) = &self.sender {
writer.write_all(b":").await?;
writer.write_all(sender.as_bytes()).await?;
writer.write_all(b" ").await?;
}
self.body.write_response(writer).await?;
writer.write_all(b"\r\n").await?;
Ok(())
}
}