essential_hash/solution_set_addr.rs
1//! A small collection of helper functions to assist in the calculation of an
2//! solution's content address.
3
4use essential_types::{solution::SolutionSet, ContentAddress};
5
6/// Determine the content address for the given `SolutionSet`.
7///
8/// If you have already calculated the content address for each `Solution` consider
9/// using [`from_solution_addrs`] or [`from_solution_addrs_slice`].
10pub fn from_set(set: &SolutionSet) -> ContentAddress {
11 let solution_addrs = set.solutions.iter().map(crate::content_addr);
12 from_solution_addrs(solution_addrs)
13}
14
15/// Given the content address for each `Solution` in the `SolutionSet`, produce the
16/// solution set's content address.
17///
18/// This collects all yielded content addresses into a `Vec`, sorts them and then
19/// hashes the result to produce the solution address.
20///
21/// If you have already collected the content address for each `Solution` into a
22/// slice, consider [`from_solution_addrs_slice`].
23pub fn from_solution_addrs(
24 solution_addrs: impl IntoIterator<Item = ContentAddress>,
25) -> ContentAddress {
26 let mut solution_addrs: Vec<_> = solution_addrs.into_iter().collect();
27 from_solution_addrs_slice(&mut solution_addrs)
28}
29
30/// Given the content address for each `Solution` in the `SolutionSet`, produce the
31/// solution's content address.
32///
33/// This first sorts `solution_addrs` before producing the content address of the
34/// slice, ensuring that the address maintains "set" semantics (i.e. the order
35/// of its inner `Solution`s does not matter).
36pub fn from_solution_addrs_slice(solution_addrs: &mut [ContentAddress]) -> ContentAddress {
37 solution_addrs.sort();
38 ContentAddress(crate::hash_bytes_iter(
39 solution_addrs.iter().map(|addr| &addr.0[..]),
40 ))
41}