From 9fb96bd2c30b31a7a8eb1adebcf1578f64393541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20K=C3=A4nner?= Date: Thu, 25 Jul 2024 13:09:18 +0200 Subject: [PATCH] implement TreeAny --- src/lib.rs | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 08b6435..c0cd1fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -159,7 +159,7 @@ fn generate_helper_struct( let tree_key = generate_tree_key(&new_type_ident, new_type_miniconf_names.iter()); let tree_serialize = generate_tree_serialize(&new_type_ident, &new_type_miniconf_consts[..]); let tree_deserialize = generate_tree_deserialize(&new_type_ident, miniconf_fields); - let tree_any = generate_tree_any(&new_type_ident); + let tree_any = generate_tree_any(&new_type_ident, &new_type_miniconf_consts, miniconf_fields); Some(quote! { #[allow(clippy::derive_partial_eq_without_eq)] @@ -522,7 +522,7 @@ fn generate_tree_deserialize(ident: &Ident, num_keys: usize) -> TokenStream2 { }; let index = ::miniconf::Key::find::(&key).ok_or(::miniconf::Traversal::NotFound(1))?; if !keys.finalize() { - ::core::result::Result::Err(miniconf::Traversal::TooLong(1))?; + ::core::result::Result::Err(::miniconf::Traversal::TooLong(1))?; } match index { 0 => ::miniconf::Error::increment_result((||{ @@ -537,21 +537,49 @@ fn generate_tree_deserialize(ident: &Ident, num_keys: usize) -> TokenStream2 { } } -fn generate_tree_any(ident: &Ident) -> TokenStream2 { +fn generate_tree_any(ident: &Ident, consts: &[Ident], num_keys: usize) -> TokenStream2 { + let matches = consts.iter().enumerate().map(|(i, ident)| { + let index = i + 1; + quote! { + #index => ::core::result::Result::Ok(&Self::#ident), + } + }); quote! { impl ::miniconf::TreeAny<1> for #ident { - fn ref_any_by_key(&self, keys: K) -> Result<&dyn ::core::any::Any, ::miniconf::Traversal> + fn ref_any_by_key(&self, mut keys: K) -> ::core::result::Result<&dyn ::core::any::Any, ::miniconf::Traversal> where K: ::miniconf::Keys, { - unimplemented!(); + let ::core::result::Result::Ok(key) = keys.next::() else { + return ::core::result::Result::Ok(&self.0); + }; + let index = ::miniconf::Key::find::(&key).ok_or(miniconf::Traversal::NotFound(1))?; + if !keys.finalize() { + ::core::result::Result::Err(::miniconf::Traversal::TooLong(1))?; + } + match index { + 0 => ::core::result::Result::Ok(&self.0), + #(#matches)* + _ => unreachable!(), + } } - fn mut_any_by_key(&mut self, keys: K) -> Result<&mut dyn ::core::any::Any, ::miniconf::Traversal> + fn mut_any_by_key(&mut self, mut keys: K) -> ::core::result::Result<&mut dyn ::core::any::Any, ::miniconf::Traversal> where K: ::miniconf::Keys, { - unimplemented!(); + let ::core::result::Result::Ok(key) = keys.next::() else { + return ::core::result::Result::Ok(&mut self.0); + }; + let index = ::miniconf::Key::find::(&key).ok_or(::miniconf::Traversal::NotFound(1))?; + if !keys.finalize() { + ::core::result::Result::Err(::miniconf::Traversal::TooLong(1))?; + } + match index { + 0 => ::core::result::Result::Ok(&mut self.0), + 1..=#num_keys => ::core::result::Result::Err(::miniconf::Traversal::Absent(0)), + _ => unreachable!(), + } } } }