Repository: paritytech/substrate
File: frame/ranked-collective/src/lib.rs (Rust)

Code before:
/// - ...with an excess rank of 4 gets 5 votes.
pub struct Linear;
impl Convert<Rank, Votes> for Linear {
	fn convert(r: Rank) -> Votes {
		(r + 1) as Votes
	}
}

/// Vote-weight scheme where all voters get one vote plus additional votes for every excess rank
/// they have incrementing by one vote for each excess rank. I.e.:
///
/// - Each member with an excess rank of 0 gets 1 vote;
/// - ...with an excess rank of 1 gets 3 votes;
/// - ...with an excess rank of 2 gets 6 votes;
/// - ...with an excess rank of 3 gets 10 votes;
/// - ...with an excess rank of 4 gets 15 votes.
pub struct Geometric;
impl Convert<Rank, Votes> for Geometric {
	fn convert(r: Rank) -> Votes {
		let v = (r + 1) as Votes;
		v * (v + 1) / 2
	}
}

/// Trait for getting the maximum number of voters for a given rank.
pub trait MaxRankVoters {
	/// Return the maximum number of voters for the rank `r`.
	fn max_rank_voters(r: Rank) -> MemberIndex;
}
impl<T: Config<I>, I: 'static> MaxRankVoters for Pallet<T, I> {
	fn max_rank_voters(r: Rank) -> MemberIndex {
		MemberCount::<T, I>::get(r)
	}
}

/// Trait for getting the maximum number of voters for a given poll class.
pub trait MaxClassVoters {
	/// Poll class type.
	type Class;
	/// Return the maximum number of voters for the class `c`.
	fn max_class_voters(c: Self::Class) -> MemberIndex;
}
impl<T: Config<I>, I: 'static> MaxClassVoters for Pallet<T, I> {
	type Class = ClassOf<T, I>;
	fn max_class_voters(c: Self::Class) -> MemberIndex {
		<Self as MaxRankVoters>::max_rank_voters(T::MinRankOfClass::convert(c))
	}
}

/// Guard to ensure that the given origin is a member of the collective. The rank of the member is
/// the `Success` value.

Review comment (suggestion):
Could be a single trait, generic over some `id`, but by default the rank and the class are same type u16.
Keeping it scoped for the purpose of the pr and simple. 

Code after:
/// Vote-weight scheme where all voters get one vote plus an additional vote for every excess rank
/// they have. I.e.:
///
/// - Each member with an excess rank of 0 gets 1 vote;
/// - ...with an excess rank of 1 gets 2 votes;
/// - ...with an excess rank of 2 gets 3 votes;
/// - ...with an excess rank of 3 gets 4 votes;
/// - ...with an excess rank of 4 gets 5 votes.
pub struct Linear;
impl Convert<Rank, Votes> for Linear {
	fn convert(r: Rank) -> Votes {
		(r + 1) as Votes
	}
}

/// Vote-weight scheme where all voters get one vote plus additional votes for every excess rank
/// they have incrementing by one vote for each excess rank. I.e.:
///
/// - Each member with an excess rank of 0 gets 1 vote;
/// - ...with an excess rank of 1 gets 3 votes;
/// - ...with an excess rank of 2 gets 6 votes;
/// - ...with an excess rank of 3 gets 10 votes;
/// - ...with an excess rank of 4 gets 15 votes.
pub struct Geometric;
impl Convert<Rank, Votes> for Geometric {
	fn convert(r: Rank) -> Votes {
		let v = (r + 1) as Votes;
		v * (v + 1) / 2
	}
}

/// Trait for getting the maximum number of voters for a given poll class.
pub trait GetMaxVoters {
	/// Poll class type.
	type Class;
	/// Return the maximum number of voters for the poll class `c`.
	fn get_max_voters(c: Self::Class) -> MemberIndex;
}
impl<T: Config<I>, I: 'static> GetMaxVoters for Pallet<T, I> {
	type Class = ClassOf<T, I>;
	fn get_max_voters(c: Self::Class) -> MemberIndex {
		MemberCount::<T, I>::get(T::MinRankOfClass::convert(c))
	}
}

/// Guard to ensure that the given origin is a member of the collective. The rank of the member is
/// the `Success` value.
pub struct EnsureRanked<T, I, const MIN_RANK: u16>(PhantomData<(T, I)>);
impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigin>
	for EnsureRanked<T, I, MIN_RANK>
{