use proto::handshake::client::do_client_handshake; use proto::handshake::request::HandshakeRequest; use proto::reader::protoreader::ProtoReader; use proto::writer::protowriter::{ProtoFlush, ProtoWriter}; use tokio::io::{BufReader, BufWriter}; use tokio::net::TcpStream; use proto::message::backend::{BackendMessage, DataRowData, RowDescriptionData}; use proto::message::frontend::{FrontendMessage, QueryData}; use proto::reader::oneway::OneWayProtoReader; use proto::writer::oneway::OneWayProtoWriter; #[tokio::main] async fn main() -> anyhow::Result<()> { let addr = "127.0.0.1:5432"; let mut stream = TcpStream::connect(addr).await?; let (reader, writer) = stream.split(); let mut writer = ProtoWriter::new(BufWriter::new(writer)); let mut reader = ProtoReader::new(BufReader::new(reader), 1024); let request = HandshakeRequest::new(196608) .parameter("user", "test user") .parameter("client_encoding", "UTF8"); let response = do_client_handshake(&mut writer, &mut reader, request).await?; println!("Handshake complete:\n{response:?}"); writer.write_proto(FrontendMessage::Query(QueryData { query: "SELECT * FROM users;".to_string().into(), })).await?; writer.flush().await?; let mut line = String::new(); loop { let msg: BackendMessage = reader.read_proto().await?; match msg { BackendMessage::RowDescription(data) => { print_header(data); }, BackendMessage::DataRow(data) => { print_row(data); }, BackendMessage::CommandComplete(data) => { println!("Command complete: {:?}", data); }, BackendMessage::ReadyForQuery(data) => { println!("Ready for query: {:?}", data); line.clear(); let res = std::io::stdin().read_line(&mut line); if let Ok(_) = res { if line.eq("exit") { break; } writer.write_proto(FrontendMessage::Query(QueryData { query: line.clone().into(), })).await?; writer.flush().await?; } }, m => { println!("Unexpected message: {:?}", m); } } } writer.write_proto(FrontendMessage::Terminate).await?; writer.flush().await?; Ok(()) } fn print_header(header: RowDescriptionData) { print!("Header -> "); for column in Vec::from(header.columns) { print!("{} | ", column.name.as_str()); } println!(); } fn print_row(row: DataRowData) { print!("Row -> "); for column in Vec::from(row.columns) { let bytes = Vec::from(column); let string = String::from_utf8(bytes).unwrap(); print!("{} | ", string); } println!(); }