mc_network_data_types/
var_string.rs1use std::io::{Error, ErrorKind, Result};
2
3use crate::var_int::VarIntRead;
4
5use super::var_int::VarIntWrite;
6
7pub trait VarStringRead {
8 fn read_var_string<const MAX_LENGTH: usize>(&mut self) -> Result<String>;
9}
10
11pub trait VarStringWrite {
12 fn write_var_string(&mut self, value: &str) -> Result<usize>;
13}
14
15impl<R> VarStringRead for R
16where
17 R: std::io::Read,
18{
19 fn read_var_string<const MAX_LENGTH: usize>(&mut self) -> Result<String> {
20 let length = self.read_var_i32()? as usize;
21 if length > MAX_LENGTH * 3 {
22 return Result::Err(Error::new(
23 ErrorKind::InvalidInput,
24 "String is longer than maximum allowed length",
25 ));
26 }
27 let mut buf = vec![0u8; length];
28 self.read_exact(&mut buf)?;
29 match String::from_utf8(buf) {
30 Ok(string) => Ok(string.to_string()),
31 Err(err) => Result::Err(Error::new(ErrorKind::InvalidInput, err)),
32 }
33 }
34}
35
36impl<W> VarStringWrite for W
37where
38 W: std::io::Write,
39{
40 fn write_var_string(&mut self, value: &str) -> Result<usize> {
41 self.write_var_i32(value.len() as i32)?;
42 Ok(self.write(value.as_bytes())?)
43 }
44}
45
46#[test]
47fn test_read_var_string() {
48 let input = "ABCD";
49 let mut vec = Vec::<u8>::new();
50 let mut cursor = std::io::Cursor::new(&mut vec);
51 cursor.write_var_string(input).unwrap();
52 cursor.set_position(0);
53 assert_eq!(cursor.read_var_string::<255>().unwrap(), input);
54}