From 7cf1cabc4f5ed416ee49519f66f7ac2a86c2058f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=85=E8=AF=BA=E7=8B=90?= <212194964+foxcyber907@users.noreply.github.com> Date: Sun, 31 May 2026 20:09:13 +0800 Subject: [PATCH] feat: support HashSet and BTreeSet as TOML arrays Treat HashSet and BTreeSet identically to Vec in parse_type so that struct fields using these collection types can derive TomlExample without manual TomlExample impls. Both serialize to TOML arrays via serde, so the existing Vec codegen path applies unchanged. Adds test hashset_btreeset covering required, optional, and BTreeSet forms. --- derive/src/lib.rs | 4 ++-- lib/src/lib.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 294e486..85864cc 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -170,7 +170,7 @@ fn default_value(ty: String) -> String { .to_string() } -/// return type and unwrap with Option and Vec; or return the value type of HashMap and BTreeMap +/// return type and unwrap with Option, Vec, HashSet, BTreeSet; or return the value type of HashMap and BTreeMap fn parse_type( ty: &Type, default: &mut String, @@ -194,7 +194,7 @@ fn parse_type( r#type = parse_type(ty, default, &mut false, nesting_format); } } - } else if id == "Vec" { + } else if id == "Vec" || id == "HashSet" || id == "BTreeSet" { if nesting_format.is_some() { *nesting_format = Some(NestingFormat::Section(NestingType::Vec)); } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 961e758..69e5bdd 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -348,6 +348,36 @@ c = [ 0, ] # Config.d # d = [ 0, ] +"# + ); + assert!(toml::from_str::(&Config::toml_example()).is_ok()) + } + + #[test] + fn hashset_btreeset() { + use std::collections::{BTreeSet, HashSet}; + + #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)] + #[allow(dead_code)] + struct Config { + /// Config.a is a set of string + a: HashSet, + /// Config.b is a set of number + b: BTreeSet, + /// Config.c is optional + c: Option>, + } + assert_eq!( + Config::toml_example(), + r#"# Config.a is a set of string +a = [ "", ] + +# Config.b is a set of number +b = [ 0, ] + +# Config.c is optional +# c = [ "", ] + "# ); assert!(toml::from_str::(&Config::toml_example()).is_ok())