mc_network_data_types/
var_string.rs

1use 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}