made_client/
ceremonies.rs1use made_proto::v1::{
2 CeremonyInstanceState, GetCeremonyInstanceRequest, ListCeremonyInstancesRequest,
3 SearchCeremonyInstancesRequest,
4};
5use std::collections::{BTreeSet, VecDeque};
6
7use crate::{CeremonySearchPage, CeremonyTree, MadeClient, MadeClientError};
8
9impl MadeClient {
10 pub async fn get_ceremony(
11 &self,
12 ceremony_id: impl Into<String>,
13 ) -> Result<CeremonyInstanceState, MadeClientError> {
14 let mut rpc = self.rpc();
15 let response = rpc
16 .get_ceremony_instance(Self::request(
17 &self.context(),
18 "/underpass.made.v1.MadeService/GetCeremonyInstance",
19 GetCeremonyInstanceRequest {
20 ceremony_id: ceremony_id.into(),
21 },
22 ))
23 .await
24 .map_err(MadeClientError::from_status)?
25 .into_inner();
26 response.instance.ok_or_else(|| {
27 MadeClientError::ProtocolViolation("get ceremony response has no instance".to_owned())
28 })
29 }
30
31 pub async fn list_ceremonies(&self) -> Result<Vec<CeremonyInstanceState>, MadeClientError> {
33 let mut rpc = self.rpc();
34 let response = rpc
35 .list_ceremony_instances(Self::request(
36 &self.context(),
37 "/underpass.made.v1.MadeService/ListCeremonyInstances",
38 ListCeremonyInstancesRequest {},
39 ))
40 .await
41 .map_err(MadeClientError::from_status)?
42 .into_inner();
43 Ok(response.instances)
44 }
45
46 pub async fn search_ceremonies(
49 &self,
50 query: SearchCeremonyInstancesRequest,
51 ) -> Result<CeremonySearchPage, MadeClientError> {
52 let mut rpc = self.rpc();
53 let response = rpc
54 .search_ceremony_instances(Self::request(
55 &self.context(),
56 "/underpass.made.v1.MadeService/SearchCeremonyInstances",
57 query,
58 ))
59 .await
60 .map_err(MadeClientError::from_status)?
61 .into_inner();
62 Ok(CeremonySearchPage::new(
63 response.instances,
64 (!response.next_cursor.is_empty()).then_some(response.next_cursor),
65 ))
66 }
67
68 pub async fn ceremony_tree(
69 &self,
70 root_id: impl Into<String>,
71 max_nodes: usize,
72 ) -> Result<CeremonyTree, MadeClientError> {
73 let root_id = root_id.into();
74 let mut pending = VecDeque::from([root_id]);
75 let mut seen = BTreeSet::new();
76 let mut instances = Vec::new();
77 while let Some(ceremony_id) = pending.pop_front() {
78 if !seen.insert(ceremony_id.clone()) {
79 continue;
80 }
81 if seen.len() > max_nodes {
82 return Err(MadeClientError::ProtocolViolation(format!(
83 "ceremony tree exceeds the requested {max_nodes} node limit"
84 )));
85 }
86 let instance = self.get_ceremony(ceremony_id).await?;
87 for child in instance
88 .child_groups
89 .iter()
90 .flat_map(|group| group.children.iter())
91 {
92 pending.push_back(child.child_id.clone());
93 }
94 instances.push(instance);
95 }
96 CeremonyTree::from_instances(instances)
97 }
98}