1use bytes::BytesMut;
2use chrono::Local;
3use tokio::{
4 io::{AsyncReadExt, ReadHalf, WriteHalf},
5 net::TcpStream,
6};
7
8use crate::parse::LazyParse;
9
10#[derive(Debug)]
11pub struct LazyNet {
12 pub buffer: bytes::BytesMut,
13 pub reader: ReadHalf<TcpStream>,
14}
15
16impl LazyNet {
17 pub async fn connect(
18 addr: &str,
19 buf_len: usize,
20 ) -> Result<(Self, WriteHalf<TcpStream>), Box<dyn std::error::Error>> {
21 let stream = TcpStream::connect(addr).await?;
22 let (reader, writer) = tokio::io::split(stream);
23 Ok((
24 LazyNet {
25 buffer: BytesMut::with_capacity(buf_len),
26 reader,
27 },
28 writer,
29 ))
30 }
31 pub async fn read_frame(
32 &mut self,
33 parse: &mut dyn LazyParse,
34 print: bool,
35 ) -> Result<(), Box<dyn std::error::Error>> {
36 loop {
37 let len = self.reader.read_buf(&mut self.buffer).await?;
38 if len == 0 {
39 println!("connection closed");
40 }
41 match parse.try_parse_frame(&mut self.buffer) {
42 Ok(_) => {
43 let now = Local::now();
44 if print {
45 let formatted = now.format("[%Y-%m-%d %H:%M:%S%.3f]");
46 println!("{}", formatted);
47 }
48 }
49 Err(e) => {
50 if print {
51 println!("parse error: {}", e);
52 }
53 }
54 }
55 }
56 }
57}