Repository: paritytech/substrate
File: frame/support/procedural/src/pallet/parse/storage.rs (Rust)

Code before:
					.remove("Hasher")
					.map(|binding| binding.ty)
					.unwrap_or(syn::parse_quote!(Blake2_128Concat)),
				key: parsed
					.remove("Key")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				value: parsed
					.remove("Value")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
				on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
				max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
			}
		},
		StorageKind::CountedMap => {
			let mandatory_generics: &[&str];
			let optional_generics: &[&str];
			if dev_mode {
				mandatory_generics = &["Key", "Value"];
				optional_generics = &["Hasher", "QueryKind", "OnEmpty", "MaxValues"];
			} else {
				mandatory_generics = &["Hasher", "Key", "Value"];
				optional_generics = &["QueryKind", "OnEmpty", "MaxValues"];
			}

			check_generics(
				&parsed,
				mandatory_generics,
				optional_generics,
				"CountedStorageMap",
				args_span,
			)?;

			StorageGenerics::CountedMap {
				hasher: parsed
					.remove("Hasher")
					.map(|binding| binding.ty)
					.unwrap_or(syn::Type::Verbatim(quote::quote! { Blake2_128Concat })),
				key: parsed
					.remove("Key")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				value: parsed
					.remove("Value")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
				on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
				max_values: parsed.remove("MaxValues").map(|binding| binding.ty),

Review comment (suggestion):
```suggestion
			let mut mandatory_generics = vec!["Key", "Value"];
			let mut optional_generics = vec!["QueryKind", "OnEmpty", "MaxValues"];

			if dev_mode {
				optional_generics.push("Hasher");
			} else {
				mandatory_generics.push("Hasher");
			}
```
Less repetition -> less typos :sparkles:  
(and then use them with a `&` below)

Code after:
					.unwrap_or(syn::parse_quote!(Blake2_128Concat)),
				key: parsed
					.remove("Key")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				value: parsed
					.remove("Value")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
				on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
				max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
			}
		},
		StorageKind::CountedMap => {
			check_generics(
				&parsed,
				&map_mandatory_generics,
				&map_optional_generics,
				"CountedStorageMap",
				args_span,
			)?;

			StorageGenerics::CountedMap {
				hasher: parsed
					.remove("Hasher")
					.map(|binding| binding.ty)
					.unwrap_or(syn::Type::Verbatim(quote::quote! { Blake2_128Concat })),
				key: parsed
					.remove("Key")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				value: parsed
					.remove("Value")
					.map(|binding| binding.ty)
					.expect("checked above as mandatory generic"),
				query_kind: parsed.remove("QueryKind").map(|binding| binding.ty),
				on_empty: parsed.remove("OnEmpty").map(|binding| binding.ty),
				max_values: parsed.remove("MaxValues").map(|binding| binding.ty),
			}
		},
		StorageKind::DoubleMap => {
			let mut double_map_mandatory_generics = vec!["Key1", "Key2", "Value"];
			if dev_mode {
				map_optional_generics.extend(["Hasher1", "Hasher2"]);
			} else {
				double_map_mandatory_generics.extend(["Hasher1", "Hasher2"]);
			}

			check_generics(
				&parsed,