`generate_solution_type!() { /* proc-macro */ }`

## Expand description

Re-export the solution generation macro.
Generates a struct to store the election result in a small/compact way. This can encode a
structure which is the equivalent of a `sp_npos_elections::Assignment<_>`

.

The following data types can be configured by the macro.

- The identifier of the voter. This can be any type that supports
`parity-scale-codec`

’s compact encoding. - The identifier of the target. This can be any type that supports
`parity-scale-codec`

’s compact encoding. - The accuracy of the ratios. This must be one of the
`PerThing`

types defined in`sp-arithmetic`

. - The maximum number of voters. This must be of type
`Get<u32>`

. Check https://github.com/paritytech/substrate/issues/10866 for more details. This is used to bound the struct, by leveraging the fact that`votes1.len() < votes2.len() < ... < votesn.len()`

(the details of the struct is explained further below). We know that`sum_i votes_i.len() <= MaxVoters`

, and we know that the maximum size of the struct would be achieved if all voters fall in the last bucket. One can also check the tests and more specifically`max_encoded_len_exact`

for a concrete example.

Moreover, the maximum number of edges per voter (distribution per assignment) also need to be specified. Attempting to convert from/to an assignment with more distributions will fail.

For example, the following generates a public struct with name `TestSolution`

with `u16`

voter
type, `u8`

target type and `Perbill`

accuracy with maximum of 4 edges per voter.

```
generate_solution_type!(pub struct TestSolution::<
VoterIndex = u16,
TargetIndex = u8,
Accuracy = Perbill,
MaxVoters = ConstU32::<10>,
>(4));
```

The output of this macro will roughly look like:

```
struct TestSolution {
voters1: vec![(u16 /* voter */, u8 /* target */)]
voters2: vec![
(u16 /* voter */, [u8 /* first target*/, Perbill /* proportion for first target */], u8 /* last target */)
]
voters3: vec![
(u16 /* voter */, [
(u8 /* first target*/, Perbill /* proportion for first target */ ),
(u8 /* second target */, Perbill /* proportion for second target*/)
], u8 /* last target */)
],
voters4: ...,
}
impl NposSolution for TestSolution {};
impl Solution for TestSolution {};
```

The given struct provides function to convert from/to `Assignment`

as part of
`frame_election_provider_support::NposSolution`

trait:

`fn from_assignment<..>(..)`

`fn into_assignment<..>(..)`

### Compact Encoding

The generated struct is by default deriving both `Encode`

and `Decode`

. This is okay but could
lead to many `0`

s in the solution. If prefixed with `#[compact]`

, then a custom compact encoding
for numbers will be used, similar to how `parity-scale-codec`

’s `Compact`

works.

```
generate_solution_type!(
#[compact]
pub struct TestSolutionCompact::<
VoterIndex = u16,
TargetIndex = u8,
Accuracy = Perbill,
MaxVoters = ConstU32::<10>,
>(8)
);
```