1use std::marker::PhantomData;
2
3use maplit::btreeset;
4
5use crate::quorum::QuorumSet;
6
7pub(crate) trait AsJoint<'d, ID, QS, D>
11where
12 ID: 'static,
13 QS: QuorumSet<ID>,
14{
15 fn as_joint(&'d self) -> Joint<ID, QS, D>
16 where D: 'd;
17}
18
19#[derive(Clone, Debug, Default)]
23#[derive(PartialEq, Eq)]
24#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
25pub(crate) struct Joint<ID, QS, D>
26where
27 ID: 'static,
28 QS: QuorumSet<ID>,
29{
30 data: D,
31 _p: PhantomData<(ID, QS)>,
32}
33
34impl<ID, QS, D> Joint<ID, QS, D>
35where
36 ID: 'static,
37 QS: QuorumSet<ID>,
38{
39 pub(crate) fn new(data: D) -> Self {
40 Self { data, _p: PhantomData }
41 }
42
43 pub(crate) fn children(&self) -> &D {
44 &self.data
45 }
46}
47
48impl<ID, QS> QuorumSet<ID> for Joint<ID, QS, &[QS]>
50where
51 ID: PartialOrd + Ord + 'static,
52 QS: QuorumSet<ID>,
53{
54 type Iter = std::collections::btree_set::IntoIter<ID>;
55
56 fn is_quorum<'a, I: Iterator<Item = &'a ID> + Clone>(&self, ids: I) -> bool {
57 for child in self.data.iter() {
58 if !child.is_quorum(ids.clone()) {
59 return false;
60 }
61 }
62 true
63 }
64
65 fn ids(&self) -> Self::Iter {
66 let mut ids = btreeset! {};
67 for child in self.data.iter() {
68 ids.extend(child.ids())
69 }
70 ids.into_iter()
71 }
72}
73
74impl<ID, QS> QuorumSet<ID> for Joint<ID, QS, Vec<QS>>
76where
77 ID: PartialOrd + Ord + 'static,
78 QS: QuorumSet<ID>,
79{
80 type Iter = std::collections::btree_set::IntoIter<ID>;
81
82 fn is_quorum<'a, I: Iterator<Item = &'a ID> + Clone>(&self, ids: I) -> bool {
83 for child in self.data.iter() {
84 if !child.is_quorum(ids.clone()) {
85 return false;
86 }
87 }
88 true
89 }
90
91 fn ids(&self) -> Self::Iter {
92 let mut ids = btreeset! {};
93 for child in self.data.iter() {
94 ids.extend(child.ids())
95 }
96 ids.into_iter()
97 }
98}