diff --git a/src/helpers.rs b/src/helpers.rs index 10a1285..83a032e 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,7 +1,25 @@ use crate::ser::SerResult; use std::io::Write; -pub(crate) fn tuple_converter(mut output: impl Write, len: usize) -> SerResult { +pub(crate) fn tuple_converter(output: impl Write, len: usize) -> SerResult { + if len > 0 { + non_zero_size(output, len) + } else { + zero_size(output) + } +} + +fn zero_size(mut output: impl Write) -> SerResult { + write!(output, " + #[inline] + fn convert(_: ()) -> [T; 0] {{ + [] + }} + ")?; + Ok(()) +} + +fn non_zero_size(mut output: impl Write, len: usize) -> SerResult { write!( output, " diff --git a/src/lib.rs b/src/lib.rs index 629b92f..deac393 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -174,6 +174,21 @@ //! assert_eq!(arr, [1, 2, 3, 4]); //! ``` //! +//! #### Zero-sized arrays +//! Since the code presented above would work only for non-empty tuples, we have to handle the "empty tuple" case +//! differently. Fortunately for us, the "real" empty tuple is handled as a unit, so we can directly emit the code +//! which yields an empty array: +//! ``` +//! let arr: [i32; 0] = { +//! #[inline] +//! fn convert(_: ()) -> [T; 0] { +//! [] +//! } +//! +//! convert(()) +//! }; +//! ``` +//! //! ### Maps //! //! Since Rust doesn't have the notion of map literals, we can't construct one directly. However, standard map-like diff --git a/test_fixtures/data.toml b/test_fixtures/data.toml index c6a3652..93de5aa 100644 --- a/test_fixtures/data.toml +++ b/test_fixtures/data.toml @@ -118,4 +118,14 @@ pub struct Container(pub [u8; 2]); """ value = """ definition::Container([1, 2]) +""" + +[empty_array] +main_type = "ZeroSizeContainer" +definition = """ +#[derive(PartialEq, Debug, Serialize)] +pub struct ZeroSizeContainer(pub [u8; 0]); +""" +value = """ +definition::ZeroSizeContainer([]) """ \ No newline at end of file