1#[doc(hidden)]
222pub use toml_example_derive::TomlExample;
223pub mod traits;
224pub use traits::*;
225
226#[cfg(test)]
227mod tests {
228 use crate as toml_example;
229 use serde_derive::Deserialize;
230 use std::collections::HashMap;
231 use toml_example::TomlExample;
232
233 #[test]
234 fn basic() {
235 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
236 #[allow(dead_code)]
237 struct Config {
238 a: usize,
240 b: String,
242 }
243 assert_eq!(
244 Config::toml_example(),
245 r#"# Config.a should be a number
246a = 0
247
248# Config.b should be a string
249b = ""
250
251"#
252 );
253 assert_eq!(
254 toml::from_str::<Config>(&Config::toml_example()).unwrap(),
255 Config::default()
256 );
257 let mut tmp_file = std::env::temp_dir();
258 tmp_file.push("config.toml");
259 Config::to_toml_example(&tmp_file.as_path().to_str().unwrap()).unwrap();
260 assert_eq!(
261 std::fs::read_to_string(tmp_file).unwrap(),
262 r#"# Config.a should be a number
263a = 0
264
265# Config.b should be a string
266b = ""
267
268"#
269 );
270 }
271
272 #[test]
273 fn option() {
274 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
275 #[allow(dead_code)]
276 struct Config {
277 a: Option<usize>,
279 b: Option<String>,
281 }
282 assert_eq!(
283 Config::toml_example(),
284 r#"# Config.a is an optional number
285# a = 0
286
287# Config.b is an optional string
288# b = ""
289
290"#
291 );
292 assert_eq!(
293 toml::from_str::<Config>(&Config::toml_example()).unwrap(),
294 Config::default()
295 )
296 }
297
298 #[test]
299 fn vec() {
300 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
301 #[allow(dead_code)]
302 struct Config {
303 a: Vec<usize>,
305 b: Vec<String>,
307 c: Vec<Option<usize>>,
309 d: Option<Vec<usize>>,
311 }
312 assert_eq!(
313 Config::toml_example(),
314 r#"# Config.a is a list of number
315a = [ 0, ]
316
317# Config.b is a list of string
318b = [ "", ]
319
320# Config.c
321c = [ 0, ]
322
323# Config.d
324# d = [ 0, ]
325
326"#
327 );
328 assert!(toml::from_str::<Config>(&Config::toml_example()).is_ok())
329 }
330
331 #[test]
332 fn struct_doc() {
333 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
336 #[allow(dead_code)]
337 struct Config {
338 a: usize,
341 }
342 assert_eq!(
343 Config::toml_example(),
344 r#"# Config is to arrange something or change the controls on a computer or other device
345# so that it can be used in a particular way
346# Config.a should be a number
347# the number should be greater or equal zero
348a = 0
349
350"#
351 );
352 assert_eq!(
353 toml::from_str::<Config>(&Config::toml_example()).unwrap(),
354 Config::default()
355 )
356 }
357
358 #[test]
359 fn serde_default() {
360 fn default_a() -> usize {
361 7
362 }
363 fn default_b() -> String {
364 "default".into()
365 }
366 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
367 #[allow(dead_code)]
368 struct Config {
369 #[serde(default = "default_a")]
371 a: usize,
372 #[serde(default = "default_b")]
374 b: String,
375 #[serde(default)]
377 c: usize,
378 #[serde(default)]
380 d: String,
381 #[serde(default)]
382 e: Option<usize>,
383 }
384 assert_eq!(
385 Config::toml_example(),
386 r#"# Config.a should be a number
387a = 7
388
389# Config.b should be a string
390b = "default"
391
392# Config.c should be a number
393c = 0
394
395# Config.d should be a string
396d = ""
397
398# e = 0
399
400"#
401 );
402 }
403
404 #[test]
405 fn toml_example_default() {
406 fn default_str() -> String {
407 "seven".into()
408 }
409 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
410 #[allow(dead_code)]
411 struct Config {
412 #[toml_example(default = 7)]
414 a: usize,
415 #[toml_example(default = "default")]
417 #[serde(default = "default_str")]
418 b: String,
419 #[serde(default = "default_str")]
420 #[toml_example(default = "default")]
421 c: String,
422 #[toml_example(default = [ "default", ])]
423 e: Vec<String>,
424 #[toml_example(
425 default = "super looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong string"
426 )]
427 f: String,
428 #[toml_example(default = [ "super looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong string",
429 "second",
430 "third",
431 ])]
432 g: Vec<String>,
433 #[toml_example(default = "#FAFAFA")]
435 color: String,
436 }
437 assert_eq!(
438 Config::toml_example(),
439 r##"# Config.a should be a number
440a = 7
441
442# Config.b should be a string
443b = "seven"
444
445c = "default"
446
447e = ["default",]
448
449f = "super looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong string"
450
451g = ["super looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong string",
452"second", "third",]
453
454# Config.color should be a hex color code
455color = "#FAFAFA"
456
457"##
458 );
459 }
460
461 #[test]
462 fn struct_serde_default() {
463 #[derive(TomlExample, Deserialize, PartialEq)]
464 #[serde(default)]
465 struct Foo {
466 bar: String,
467 #[serde(default)]
468 x: usize,
469 }
470 impl Default for Foo {
471 fn default() -> Self {
472 Foo {
473 bar: String::from("hello world"),
474 x: 12,
475 }
476 }
477 }
478 assert_eq!(
479 Foo::toml_example(),
480 r##"bar = "hello world"
481
482x = 0
483
484"##
485 );
486 }
487
488 #[test]
489 fn struct_serde_default_fn() {
490 #[derive(TomlExample, Deserialize, PartialEq)]
491 #[serde(default = "default")]
492 struct Foo {
493 bar: String,
494 #[toml_example(default = "field override")]
495 baz: String,
496 }
497 fn default() -> Foo {
498 Foo {
499 bar: String::from("hello world"),
500 baz: String::from("custom default"),
501 }
502 }
503 assert_eq!(
504 Foo::toml_example(),
505 r##"bar = "hello world"
506
507baz = "field override"
508
509"##
510 );
511 }
512
513 #[test]
514 fn struct_toml_example_default() {
515 #[derive(TomlExample, Deserialize, PartialEq)]
516 #[toml_example(default)]
517 struct Foo {
518 #[serde(default = "paru")]
519 yay: &'static str,
520 aur_is_useful: bool,
521 }
522 impl Default for Foo {
523 fn default() -> Self {
524 Foo {
525 yay: "yay!",
526 aur_is_useful: true,
527 }
528 }
529 }
530 fn paru() -> &'static str {
531 "no, paru!"
532 }
533 assert_eq!(
534 Foo::toml_example(),
535 r##"yay = "no, paru!"
536
537aur_is_useful = true
538
539"##
540 );
541 }
542
543 #[test]
544 fn no_nesting() {
545 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
547 #[allow(dead_code)]
548 struct Inner {
549 a: usize,
551 }
552 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
553 #[allow(dead_code)]
554 struct Outer {
555 inner: Inner,
557 }
558 assert_eq!(
559 Outer::toml_example(),
560 r#"# Outer.inner is a complex struct
561inner = ""
562
563"#
564 );
565 }
566
567 #[test]
568 fn nesting() {
569 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
571 #[allow(dead_code)]
572 struct Inner {
573 a: usize,
575 }
576 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
577 #[allow(dead_code)]
578 struct Outer {
579 #[toml_example(nesting)]
581 inner: Inner,
582 }
583 assert_eq!(
584 Outer::toml_example(),
585 r#"# Outer.inner is a complex struct
586# Inner is a config live in Outer
587[inner]
588# Inner.a should be a number
589a = 0
590
591"#
592 );
593 assert_eq!(
594 toml::from_str::<Outer>(&Outer::toml_example()).unwrap(),
595 Outer::default()
596 );
597 }
598
599 #[test]
600 fn nesting_by_section() {
601 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
603 #[allow(dead_code)]
604 struct Inner {
605 a: usize,
607 }
608 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
609 #[allow(dead_code)]
610 struct Outer {
611 #[toml_example(nesting = section)]
613 inner: Inner,
614 }
615 assert_eq!(
616 Outer::toml_example(),
617 r#"# Outer.inner is a complex struct
618# Inner is a config live in Outer
619[inner]
620# Inner.a should be a number
621a = 0
622
623"#
624 );
625 assert_eq!(
626 toml::from_str::<Outer>(&Outer::toml_example()).unwrap(),
627 Outer::default()
628 );
629 }
630
631 #[test]
632 fn nesting_by_prefix() {
633 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
635 #[allow(dead_code)]
636 struct Inner {
637 a: usize,
639 }
640 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
641 #[allow(dead_code)]
642 struct Outer {
643 #[toml_example(nesting = prefix)]
645 inner: Inner,
646 }
647 assert_eq!(
648 Outer::toml_example(),
649 r#"# Outer.inner is a complex struct
650# Inner is a config live in Outer
651# Inner.a should be a number
652inner.a = 0
653
654"#
655 );
656 assert_eq!(
657 toml::from_str::<Outer>(&Outer::toml_example()).unwrap(),
658 Outer::default()
659 );
660 }
661
662 #[test]
663 fn nesting_vector() {
664 #[derive(TomlExample, Deserialize)]
666 #[allow(dead_code)]
667 struct Service {
668 port: usize,
670 }
671 #[derive(TomlExample, Deserialize)]
672 #[allow(dead_code)]
673 struct Node {
674 #[toml_example(nesting)]
676 services: Vec<Service>,
677 }
678 assert_eq!(
679 Node::toml_example(),
680 r#"# Services are running in the node
681# Service with specific port
682[[services]]
683# port should be a number
684port = 0
685
686"#
687 );
688 assert!(toml::from_str::<Node>(&Node::toml_example()).is_ok());
689 }
690
691 #[test]
692 fn nesting_hashmap() {
693 #[derive(TomlExample, Deserialize)]
695 #[allow(dead_code)]
696 struct Service {
697 port: usize,
699 }
700 #[derive(TomlExample, Deserialize)]
701 #[allow(dead_code)]
702 struct Node {
703 #[toml_example(nesting)]
705 services: HashMap<String, Service>,
706 }
707 assert_eq!(
708 Node::toml_example(),
709 r#"# Services are running in the node
710# Service with specific port
711[services.example]
712# port should be a number
713port = 0
714
715"#
716 );
717 assert!(toml::from_str::<Node>(&Node::toml_example()).is_ok());
718 }
719
720 #[test]
721 fn optional_nesting() {
722 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
724 #[allow(dead_code)]
725 struct Inner {
726 a: usize,
728 }
729 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
730 #[allow(dead_code)]
731 struct Outer {
732 #[toml_example(nesting)]
734 inner: Option<Inner>,
735 }
736 assert_eq!(
737 Outer::toml_example(),
738 r#"# Outer.inner is a complex struct
739# Inner is a config live in Outer
740# [inner]
741# Inner.a should be a number
742# a = 0
743
744"#
745 );
746 assert_eq!(
747 toml::from_str::<Outer>(&Outer::toml_example()).unwrap(),
748 Outer::default()
749 );
750 }
751
752 #[test]
753 fn optional_nesting_by_section() {
754 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
756 #[allow(dead_code)]
757 struct Inner {
758 a: usize,
760 }
761 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
762 #[allow(dead_code)]
763 struct Outer {
764 #[toml_example(nesting = section)]
766 inner: Option<Inner>,
767 }
768 assert_eq!(
769 Outer::toml_example(),
770 r#"# Outer.inner is a complex struct
771# Inner is a config live in Outer
772# [inner]
773# Inner.a should be a number
774# a = 0
775
776"#
777 );
778 assert_eq!(
779 toml::from_str::<Outer>(&Outer::toml_example()).unwrap(),
780 Outer::default()
781 );
782 }
783
784 #[test]
785 fn optional_nesting_by_prefix() {
786 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
788 #[allow(dead_code)]
789 struct Inner {
790 a: usize,
792 }
793 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
794 #[allow(dead_code)]
795 struct Outer {
796 #[toml_example(nesting = prefix)]
798 inner: Option<Inner>,
799 }
800 assert_eq!(
801 Outer::toml_example(),
802 r#"# Outer.inner is a complex struct
803# Inner is a config live in Outer
804# Inner.a should be a number
805# inner.a = 0
806
807"#
808 );
809 assert_eq!(
810 toml::from_str::<Outer>(&Outer::toml_example()).unwrap(),
811 Outer::default()
812 );
813 }
814
815 #[test]
816 fn optional_nesting_vector() {
817 #[derive(TomlExample, Deserialize)]
819 #[allow(dead_code)]
820 struct Service {
821 port: usize,
823 }
824 #[derive(TomlExample, Deserialize)]
825 #[allow(dead_code)]
826 struct Node {
827 #[toml_example(nesting)]
829 services: Option<Vec<Service>>,
830 }
831 assert_eq!(
832 Node::toml_example(),
833 r#"# Services are running in the node
834# Service with specific port
835# [[services]]
836# port should be a number
837# port = 0
838
839"#
840 );
841 assert!(toml::from_str::<Node>(&Node::toml_example()).is_ok());
842 }
843
844 #[test]
845 fn optional_nesting_hashmap() {
846 #[derive(TomlExample, Deserialize)]
848 #[allow(dead_code)]
849 struct Service {
850 port: usize,
852 }
853 #[derive(TomlExample, Deserialize)]
854 #[allow(dead_code)]
855 struct Node {
856 #[toml_example(nesting)]
858 services: Option<HashMap<String, Service>>,
859 }
860 assert_eq!(
861 Node::toml_example(),
862 r#"# Services are running in the node
863# Service with specific port
864# [services.example]
865# port should be a number
866# port = 0
867
868"#
869 );
870 assert!(toml::from_str::<Node>(&Node::toml_example()).is_ok());
871 }
872
873 #[test]
874 fn nesting_hashmap_with_default_name() {
875 #[derive(TomlExample, Deserialize)]
877 #[allow(dead_code)]
878 struct Service {
879 #[toml_example(default = 80)]
881 port: usize,
882 }
883 #[derive(TomlExample, Deserialize)]
884 #[allow(dead_code)]
885 struct Node {
886 #[toml_example(nesting)]
888 #[toml_example(default = http)]
889 services: HashMap<String, Service>,
890 }
891 assert_eq!(
892 Node::toml_example(),
893 r#"# Services are running in the node
894# Service with specific port
895[services.http]
896# port should be a number
897port = 80
898
899"#
900 );
901 assert!(toml::from_str::<Node>(&Node::toml_example()).is_ok());
902 }
903
904 #[test]
905 fn nesting_hashmap_with_dash_name() {
906 #[derive(TomlExample, Deserialize)]
908 #[allow(dead_code)]
909 struct Service {
910 #[toml_example(default = 80)]
912 port: usize,
913 }
914 #[derive(TomlExample, Deserialize)]
915 #[allow(dead_code)]
916 struct Node {
917 #[toml_example(nesting)]
919 #[toml_example(default = http.01)]
920 services: HashMap<String, Service>,
921 }
922 assert_eq!(
923 Node::toml_example(),
924 r#"# Services are running in the node
925# Service with specific port
926[services.http-01]
927# port should be a number
928port = 80
929
930"#
931 );
932 assert!(toml::from_str::<Node>(&Node::toml_example()).is_ok());
933 }
934
935 #[test]
936 fn recursive_nesting() {
937 #[derive(TomlExample, Default, Debug, Deserialize, PartialEq)]
938 struct Outer {
939 #[toml_example(nesting)]
940 _middle: Middle,
941 }
942 #[derive(TomlExample, Default, Debug, Deserialize, PartialEq)]
943 struct Middle {
944 #[toml_example(nesting)]
945 _inner: Inner,
946 }
947 #[derive(TomlExample, Default, Debug, Deserialize, PartialEq)]
948 struct Inner {
949 _value: usize,
950 }
951 let example = Outer::toml_example();
952 assert_eq!(toml::from_str::<Outer>(&example).unwrap(), Outer::default());
953 assert_eq!(
954 example,
955 r#"[_middle]
956[_middle._inner]
957_value = 0
958
959"#
960 );
961 }
962
963 #[test]
964 fn recursive_nesting_and_flatten() {
965 #[derive(TomlExample, Default, Debug, Deserialize, PartialEq)]
966 struct Outer {
967 #[toml_example(nesting)]
968 middle: Middle,
969 #[toml_example(default = false)]
970 flag: bool,
972 }
973 #[derive(TomlExample, Default, Debug, Deserialize, PartialEq)]
974 struct Middle {
975 #[serde(flatten)]
976 #[toml_example(nesting)]
977 inner: Inner,
979 }
980 #[derive(TomlExample, Default, Debug, Deserialize, PartialEq)]
981 struct Inner {
982 #[toml_example(nesting)]
983 extra: Extra,
985 value: usize,
987 }
988 #[derive(TomlExample, Debug, Deserialize, PartialEq)]
989 #[toml_example(default)]
990 struct Extra {
991 name: String,
992 }
993 impl Default for Extra {
994 fn default() -> Self {
995 Self {
996 name: String::from("ferris"),
997 }
998 }
999 }
1000 let example = Outer::toml_example();
1001 assert_eq!(toml::from_str::<Outer>(&example).unwrap(), Outer::default());
1002 assert_eq!(
1003 example,
1004 r#"# Some toggle
1005flag = false
1006
1007[middle]
1008# Values of [Inner] are flattened into [Middle]
1009# `value` is defined below `extra`, but shown above
1010value = 0
1011
1012# [Extra] is flattened into [Middle]
1013[middle.extra]
1014name = "ferris"
1015
1016"#
1017 );
1018 }
1019
1020 #[test]
1021 fn require() {
1022 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
1023 #[allow(dead_code)]
1024 struct Config {
1025 #[toml_example(require)]
1027 a: Option<usize>,
1028 #[toml_example(require)]
1030 b: Option<String>,
1031 #[toml_example(require)]
1032 #[toml_example(default = "third")]
1033 c: Option<String>,
1034 }
1035 assert_eq!(
1036 Config::toml_example(),
1037 r#"# Config.a is an optional number
1038a = 0
1039
1040# Config.b is an optional string
1041b = ""
1042
1043c = "third"
1044
1045"#
1046 );
1047 }
1048
1049 #[test]
1050 fn skip() {
1051 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
1052 #[allow(dead_code)]
1053 struct Config {
1054 a: usize,
1056 #[toml_example(skip)]
1057 b: usize,
1058 #[serde(skip)]
1059 c: usize,
1060 #[serde(skip_deserializing)]
1061 d: usize,
1062 }
1063 assert_eq!(
1064 Config::toml_example(),
1065 r#"# Config.a is a number
1066a = 0
1067
1068"#
1069 );
1070 }
1071
1072 #[test]
1073 fn is_enum() {
1074 fn b() -> AB {
1075 AB::B
1076 }
1077 #[derive(TomlExample, Deserialize, Default, PartialEq, Debug)]
1078 #[allow(dead_code)]
1079 struct Config {
1080 #[toml_example(enum, default)]
1082 ab: AB,
1083 #[toml_example(is_enum)]
1085 #[serde(default)]
1086 ab2: AB,
1087 #[toml_example(is_enum)]
1089 #[serde(default = "b")]
1090 ab3: AB,
1091 }
1092 #[derive(Debug, Default, Deserialize, PartialEq)]
1093 enum AB {
1094 #[default]
1095 A,
1096 B,
1097 }
1098 assert_eq!(
1099 Config::toml_example(),
1100 r#"# Config.ab is an enum
1101ab = "A"
1102
1103# Config.ab2 is an enum too
1104ab2 = "A"
1105
1106# Config.ab3 is an enum as well
1107ab3 = "B"
1108
1109"#
1110 );
1111 }
1112
1113 #[test]
1114 fn flatten() {
1115 #[derive(TomlExample)]
1116 struct ItemWrapper {
1117 #[toml_example(flatten, nesting)]
1118 _item: Item,
1119 }
1120 #[derive(TomlExample)]
1121 struct Item {
1122 _value: String,
1123 }
1124 assert_eq!(ItemWrapper::toml_example(), Item::toml_example());
1125 }
1126
1127 #[test]
1128 fn flatten_order() {
1129 #[derive(TomlExample)]
1130 struct Outer {
1131 #[toml_example(nesting)]
1132 _nested: Item,
1133 #[toml_example(flatten, nesting)]
1134 _flattened: Item,
1135 }
1136 #[derive(TomlExample)]
1137 struct Item {
1138 _value: String,
1139 }
1140 assert_eq!(
1141 Outer::toml_example(),
1142 r#"_value = ""
1143
1144[_nested]
1145_value = ""
1146
1147"#
1148 );
1149 }
1150
1151 #[test]
1152 fn multi_attr_escaping() {
1153 #[derive(TomlExample, Deserialize, PartialEq)]
1154 struct ConfigWrapper {
1155 #[toml_example(default = ["hello", "{nice :)\""], require)]
1156 vec: Option<Vec<String>>,
1157
1158 #[toml_example(require, default = ["\"\\\n}])", "super (fancy\\! :-) )"])]
1159 list: Option<[String; 2]>,
1160 }
1161
1162 assert_eq!(
1163 ConfigWrapper::toml_example(),
1164 r#"vec = ["hello", "{nice :)\""]
1165
1166list = ["\"\\\n}])", "super (fancy\\! :-) )"]
1167
1168"#
1169 );
1170 }
1171
1172 #[test]
1173 fn r_sharp_field() {
1174 #[derive(TomlExample)]
1175 #[allow(dead_code)]
1176 struct Config {
1177 r#type: usize,
1179 }
1180 assert_eq!(
1181 Config::toml_example(),
1182 r#"# Config.type is a number
1183type = 0
1184
1185"#
1186 );
1187 }
1188
1189 #[test]
1190 fn non_nesting_field_should_be_first() {
1191 #[derive(TomlExample)]
1192 #[allow(dead_code)]
1193 struct Foo {
1194 a: String,
1195 }
1196
1197 #[derive(TomlExample)]
1198 #[allow(dead_code)]
1199 struct Bar {
1200 #[toml_example(nesting)]
1201 foo: Foo,
1202 b: String,
1203 }
1204
1205 assert_eq!(
1206 Bar::toml_example(),
1207 r#"b = ""
1208
1209[foo]
1210a = ""
1211
1212"#
1213 );
1214 }
1215
1216 #[test]
1217 fn rename() {
1218 use serde::Serialize;
1219
1220 #[derive(Deserialize, Serialize, TomlExample)]
1221 struct Config {
1222 #[serde(rename = "bb")]
1223 b: usize,
1224 }
1225 assert_eq!(
1226 Config::toml_example(),
1227 r#"bb = 0
1228
1229"#
1230 );
1231 }
1232
1233 #[test]
1234 fn rename_all() {
1235 use serde::Serialize;
1236
1237 #[derive(Deserialize, Serialize, TomlExample)]
1238 #[serde(rename_all = "kebab-case")]
1239 struct Config {
1240 a_a: usize,
1241 }
1242 assert_eq!(
1243 Config::toml_example(),
1244 r#"a-a = 0
1245
1246"#
1247 );
1248 }
1249
1250 #[test]
1251 fn hashset_and_struct() {
1252 use std::collections::HashMap;
1253
1254 #[derive(TomlExample)]
1255 #[allow(dead_code)]
1256 struct Foo {
1257 a: String,
1258 }
1259
1260 #[derive(TomlExample)]
1261 #[allow(dead_code)]
1262 struct Bar {
1263 #[toml_example(nesting)]
1265 default: Foo,
1266
1267 #[toml_example(nesting)]
1269 instance: HashMap<String, Foo>,
1270 }
1271
1272 assert_eq!(
1273 Bar::toml_example(),
1274 r#"# Default instances doc
1275[default]
1276a = ""
1277
1278# Instances doc
1279[instance.example]
1280a = ""
1281
1282"#
1283 );
1284 }
1285
1286 #[test]
1287 fn optional_long_vector_field() {
1288 #[derive(TomlExample)]
1289 #[allow(dead_code)]
1290 struct Foo {
1291 #[toml_example(default = ["a", "b", "c"])]
1293 array_value_example: Option<Vec<String>>,
1294
1295 #[toml_example(default = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1297 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
1298 "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
1299 "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
1300 ])]
1301 array_long_value_example: Option<Vec<String>>,
1302
1303 #[toml_example(default = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"])]
1305 array_long_value_no_space_example: Option<Vec<String>>,
1306 }
1307 assert_eq!(
1308 Foo::toml_example(),
1309 r#"# Option<Vec<String>>, with small default values
1310# array_value_example = ["a", "b", "c"]
1311
1312# Option<Vec<String>>, with long default values
1313# array_long_value_example = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1314# "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
1315# "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
1316# "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"]
1317
1318# Option<Vec<String>>, with a long default value but no space after comma
1319# array_long_value_no_space_example = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"]
1320
1321"#
1322 );
1323 }
1324}