From ce1fb4a11e17acf2a5656de902951b3a3a7710b8 Mon Sep 17 00:00:00 2001 From: Jika Date: Thu, 30 Oct 2025 16:03:58 +0100 Subject: [PATCH] Add support for optional enum field --- src/de.rs | 13 ++++++++++++- tests/deserialize.rs | 7 +++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/de.rs b/src/de.rs index 5d4cae1..024bb3a 100644 --- a/src/de.rs +++ b/src/de.rs @@ -164,7 +164,18 @@ pub fn deserialize_internal( })* _ => (), } - self.__map.take().ok_or(miniserde::Error)?.finish()?; + let mut map = match self.__map.take() { + Some(map) => map, + None => match tag.as_str() { + #( + #struct_variant_names => <#struct_names as miniserde::Deserialize>::begin( + unsafe {&mut *(&mut self.#struct_names as *mut #ex::Option<#struct_names>)} + ).map()?, + )* + _ => return #ex::Err(miniserde::Error), + }, + }; + map.finish()?; match tag.as_str() { #(#struct_variant_names => { self.__out.replace(self.#struct_names.take().ok_or(miniserde::Error)?.as_enum()); diff --git a/tests/deserialize.rs b/tests/deserialize.rs index 5d29d62..9801148 100644 --- a/tests/deserialize.rs +++ b/tests/deserialize.rs @@ -51,10 +51,13 @@ fn test_internal() { x: i32, }, D, + E { + value: Option, + }, } use Internal::*; - let example = r#"[{"type":"renamedB"},{"type":"C","x":2},{"type":"D"}]"#; + let example = r#"[{"type":"renamedB"},{"type":"C","x":2},{"type":"D"},{"type":"E"},{"type":"E","value":5}]"#; let actual: Vec = json::from_str(example).unwrap(); - let expected = [B, C { x: 2 }, D]; + let expected = [B, C { x: 2 }, D, E { value: None }, E { value: Some(5) }]; assert_eq!(actual, expected); }