use serde::{Deserialize, Serialize};
use serde::{Deserializer, Serializer};
use alloc::string::String;
use alloc::string::ToString;
macro_rules! make_deserialize_string_fn {
($name:ident, $limit:expr) => {
pub fn $name<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let bytes = <[u8; $limit]>::deserialize(deserializer)?;
let s = String::from_utf8_lossy(&bytes).to_string();
let s = s.trim_matches(char::from(0)).trim().to_string(); Ok(s)
}
};
}
make_deserialize_string_fn!(deserialize_string_17, 17);
make_deserialize_string_fn!(deserialize_string_20, 20);
make_deserialize_string_fn!(deserialize_string_21, 21);
make_deserialize_string_fn!(deserialize_string_22, 22);
macro_rules! make_serialize_string_fn {
($name:ident, $limit:expr) => {
pub fn $name<S>(value: &String, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let bytes = value.as_bytes();
let mut count = 0;
let mut i = 0;
while i < bytes.len() && count < $limit {
let ch = bytes[i];
let width = utf8_char_width(ch);
if count + width > $limit {
break;
}
count += width;
i += width;
}
let mut array = [0u8; $limit];
array[..i].copy_from_slice(&bytes[..i]);
array.serialize(serializer)
}
};
}
fn utf8_char_width(ch: u8) -> usize {
match ch {
0..=127 => 1,
128..=191 => 0,
192..=223 => 2,
224..=239 => 3,
240..=247 => 4,
248..=255 => 0,
}
}
make_serialize_string_fn!(serialize_string_17, 17);
make_serialize_string_fn!(serialize_string_20, 20);
make_serialize_string_fn!(serialize_string_21, 21);
make_serialize_string_fn!(serialize_string_22, 22);