#![no_std]
use nanojson::{Deserialize, ParseError, ParseErrorKind, Parser, Serialize, SerializeError, Serializer, Write};
struct StringArray<const N: usize> {
buf: [u8; N],
len: usize,
}
#[derive(Serialize, Deserialize, Debug)]
struct MyStruct {
num: f32,
name: StringArray<32>,
}
fn main() {
let json = r#"{"num": 42.3, "name": "hello"}"#;
let my_struct = nanojson::parse_sized::<MyStruct>(&mut [0; 256], json.as_bytes());
if let Ok(my_struct) = my_struct {
let my_struct2 = MyStruct {
num: 420.3,
name: StringArray::try_from("world").unwrap(),
};
let mut buf = [0; 256];
if let Ok(json) = nanojson::stringify_sized(&mut buf, &my_struct2) {
panic!("Parsed: {my_struct:?}\nJSON: {}", json);
}
}
}
impl<const N: usize> TryFrom<&str> for StringArray<N> {
type Error = &'static str;
fn try_from(s: &str) -> Result<Self, Self::Error> {
let mut buf = [0; N];
if s.len() >= N {
return Err("String too large")
}
buf[..s.len()].copy_from_slice(s.as_bytes());
Ok(StringArray { buf, len: s.len() })
}
}
impl<const N: usize> core::fmt::Debug for StringArray<N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(core::str::from_utf8(&self.buf[..self.len]).unwrap())
}
}
impl<const N: usize> Serialize for StringArray<N> {
fn serialize<W: Write>(&self, json: &mut Serializer<W>) -> Result<(), SerializeError<W::Error>> {
json.string_bytes(&self.buf[..self.len])
}
}
impl<'src, const N: usize> Deserialize<'src> for StringArray<N> {
fn deserialize<'buf>(json: &mut Parser<'src, 'buf>) -> Result<Self, ParseError> {
let s = json.string()?;
let len = s.len();
if len > N {
let offset = json.error_offset() + N - len;
return Err(ParseError { kind: ParseErrorKind::StringBufferOverflow, offset });
}
let mut buf = [0; N];
buf[..s.len()].copy_from_slice(s.as_bytes());
Ok(StringArray { buf, len: s.len() })
}
}