use bytes::{BufMut, BytesMut};
use std::time::Instant;
use crate::channel::{Context, Handler};
use crate::transport::{TaggedBytesMut, TransportContext};
pub struct TaggedStringCodec;
impl Default for TaggedStringCodec {
fn default() -> Self {
Self::new()
}
}
impl TaggedStringCodec {
pub fn new() -> Self {
Self {}
}
}
#[derive(Clone)]
pub struct TaggedString {
pub now: Instant,
pub transport: TransportContext,
pub message: String,
}
impl Default for TaggedString {
fn default() -> Self {
Self {
now: Instant::now(),
transport: TransportContext::default(),
message: String::new(),
}
}
}
impl Handler for TaggedStringCodec {
type Rin = TaggedBytesMut;
type Rout = TaggedString;
type Win = TaggedString;
type Wout = TaggedBytesMut;
fn name(&self) -> &str {
"TaggedStringCodec"
}
fn handle_read(
&mut self,
ctx: &Context<Self::Rin, Self::Rout, Self::Win, Self::Wout>,
msg: Self::Rin,
) {
match String::from_utf8(msg.message.to_vec()) {
Ok(message) => {
ctx.fire_read(TaggedString {
now: msg.now,
transport: msg.transport,
message,
});
}
Err(err) => ctx.fire_exception(err.into()),
}
}
fn poll_write(
&mut self,
ctx: &Context<Self::Rin, Self::Rout, Self::Win, Self::Wout>,
) -> Option<Self::Wout> {
if let Some(msg) = ctx.fire_poll_write() {
let mut buf = BytesMut::new();
buf.put(msg.message.as_bytes());
Some(TaggedBytesMut {
now: Instant::now(),
transport: msg.transport,
message: buf,
})
} else {
None
}
}
}