use std::io::{Error, Write};
use nom::{Parser, combinator::map_res};
use super::*;
pub fn read_var_string(input: &[u8]) -> IResult<&[u8], String> {
map_res(read_var_buffer, |s| String::from_utf8(s.to_vec())).parse(input)
}
pub fn write_var_string<W: Write, S: AsRef<str>>(buffer: &mut W, input: S) -> Result<(), Error> {
let bytes = input.as_ref().as_bytes();
write_var_buffer(buffer, bytes)?;
Ok(())
}
#[cfg(test)]
mod tests {
use nom::{
AsBytes, Err,
error::{Error, ErrorKind},
};
use super::*;
#[test]
fn test_read_var_string() {
let input = [0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F];
let expected_output = "hello".to_string();
let result = read_var_string(&input);
assert_eq!(result, Ok((&[][..], expected_output)));
let input = [0x68, 0x65, 0x6C, 0x6C, 0x6F];
let result = read_var_string(&input);
assert_eq!(result, Err(Err::Error(Error::new(&input[1..], ErrorKind::Eof))));
let input = [0x05, 0x68, 0x65, 0x6C, 0x6C];
let result = read_var_string(&input);
assert_eq!(result, Err(Err::Error(Error::new(&input[1..], ErrorKind::Eof))));
let input = [0xFF, 0x01, 0x02, 0x03, 0x04];
let result = read_var_string(&input);
assert_eq!(result, Err(Err::Error(Error::new(&input[2..], ErrorKind::Eof))));
let input = [0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01];
let result = read_var_string(&input);
assert_eq!(result, Err(Err::Error(Error::new(&input[7..], ErrorKind::Eof))));
let input = [0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
let result = read_var_string(&input);
assert_eq!(result, Err(Err::Error(Error::new(&input[..], ErrorKind::MapRes))));
}
#[test]
fn test_var_str_codec() {
test_var_str_enc_dec("".to_string());
test_var_str_enc_dec(" ".to_string());
test_var_str_enc_dec("abcde".to_string());
test_var_str_enc_dec("🃒🃓🃟☗🀥🀫∺∼≂≇⓵➎⓷➏".to_string());
}
fn test_var_str_enc_dec(input: String) {
let mut buf = Vec::<u8>::new();
write_var_string(&mut buf, input.clone()).unwrap();
let (rest, decoded_str) = read_var_string(buf.as_bytes()).unwrap();
assert_eq!(decoded_str, input);
assert_eq!(rest.len(), 0);
}
}