forked from lavina/lavina
52 lines
1.5 KiB
Rust
52 lines
1.5 KiB
Rust
|
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(())
|
||
|
}
|
||
|
}
|