pub trait Action {
const ACTION: &'static str;
#[cfg(feature = "serde")]
fn to_json_slice<'buf>(
&self,
buf: &'buf mut [u8],
) -> Result<&'buf [u8], serde_json_core::ser::Error>
where
Self: serde::Serialize,
{
let len = serde_json_core::to_slice(self, buf)?;
Ok(&buf[..len])
}
#[cfg(feature = "serde")]
fn to_json_str<'buf>(
&self,
buf: &'buf mut [u8],
) -> Result<&'buf str, serde_json_core::ser::Error>
where
Self: serde::Serialize,
{
let bytes = self.to_json_slice(buf)?;
Ok(core::str::from_utf8(bytes).expect("serde-json-core always emits valid UTF-8"))
}
#[cfg(feature = "serde")]
fn from_json_slice(data: &[u8]) -> Result<Self, serde_json_core::de::Error>
where
Self: Sized + serde::de::DeserializeOwned,
{
serde_json_core::from_slice(data).map(|(value, _remainder)| value)
}
#[cfg(feature = "serde")]
fn from_json_str(data: &str) -> Result<Self, serde_json_core::de::Error>
where
Self: Sized + serde::de::DeserializeOwned,
{
serde_json_core::from_str(data).map(|(value, _remainder)| value)
}
}
#[cfg(all(test, feature = "serde"))]
mod tests {
use super::*;
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
struct SampleRequest {
#[serde(rename = "idTag")]
id_tag: heapless::String<20>,
}
impl Action for SampleRequest {
const ACTION: &'static str = "Sample";
}
fn sample() -> SampleRequest {
SampleRequest {
id_tag: heapless::String::try_from("ABC123").unwrap(),
}
}
#[test]
fn to_json_slice_writes_json_into_the_given_buffer() {
let mut buf = [0u8; 64];
let json = sample().to_json_slice(&mut buf).unwrap();
assert_eq!(json, br#"{"idTag":"ABC123"}"#);
}
#[test]
fn to_json_slice_errors_when_the_buffer_is_too_small() {
let mut buf = [0u8; 4];
assert!(sample().to_json_slice(&mut buf).is_err());
}
#[test]
fn to_json_str_writes_json_into_the_given_buffer_as_utf8() {
let mut buf = [0u8; 64];
let json = sample().to_json_str(&mut buf).unwrap();
assert_eq!(json, r#"{"idTag":"ABC123"}"#);
}
#[test]
fn from_json_slice_parses_bytes_back_into_the_struct() {
let parsed = SampleRequest::from_json_slice(br#"{"idTag":"ABC123"}"#).unwrap();
assert_eq!(parsed, sample());
}
#[test]
fn from_json_str_parses_a_str_back_into_the_struct() {
let parsed = SampleRequest::from_json_str(r#"{"idTag":"ABC123"}"#).unwrap();
assert_eq!(parsed, sample());
}
#[test]
fn round_trips_through_bytes() {
let mut buf = [0u8; 64];
let json = sample().to_json_slice(&mut buf).unwrap();
let parsed = SampleRequest::from_json_slice(json).unwrap();
assert_eq!(parsed, sample());
}
}