homestar_runtime/event_handler/notification/
receipt.rs1use const_format::formatcp;
4use homestar_invocation::{
5 ipld::{schema, DagJson},
6 Receipt,
7};
8use libipld::{ipld, Cid, Ipld};
9use schemars::{
10 gen::SchemaGenerator,
11 schema::{InstanceType, Metadata, ObjectValidation, Schema, SchemaObject, SingleOrVec},
12 JsonSchema,
13};
14use std::{
15 borrow::Cow,
16 collections::{BTreeMap, BTreeSet},
17 module_path,
18};
19
20#[derive(Debug, Clone, PartialEq)]
22pub struct ReceiptNotification(Ipld);
23
24impl ReceiptNotification {
25 #[allow(dead_code)]
27 pub(crate) fn inner(&self) -> &Ipld {
28 &self.0
29 }
30
31 #[allow(dead_code)]
33 pub(crate) fn into_inner(self) -> Ipld {
34 self.0.to_owned()
35 }
36
37 pub(crate) fn with(receipt: Receipt<Ipld>, cid: Cid, metadata: Option<Ipld>) -> Self {
39 let receipt: Ipld = receipt.into();
40 let data = ipld!({
41 "receipt": receipt,
42 "metadata": metadata.as_ref().map(|m| m.to_owned()).map_or(Ipld::Null, |m| m),
43 "receipt_cid": cid,
44 });
45 ReceiptNotification(data)
46 }
47}
48
49impl DagJson for ReceiptNotification where Ipld: From<ReceiptNotification> {}
50
51impl From<ReceiptNotification> for Ipld {
52 fn from(receipt: ReceiptNotification) -> Self {
53 receipt.0
54 }
55}
56
57impl From<Ipld> for ReceiptNotification {
58 fn from(ipld: Ipld) -> Self {
59 ReceiptNotification(ipld)
60 }
61}
62
63impl JsonSchema for ReceiptNotification {
64 fn schema_name() -> String {
65 "receipt_notification".to_owned()
66 }
67
68 fn schema_id() -> Cow<'static, str> {
69 Cow::Borrowed(formatcp!("{}::ReceiptNotification", module_path!()))
70 }
71
72 fn json_schema(gen: &mut SchemaGenerator) -> Schema {
73 let metadata_schema = SchemaObject {
74 instance_type: Some(SingleOrVec::Single(InstanceType::Object.into())),
75 metadata: Some(Box::new(Metadata {
76 title: Some("Metadata".to_string()),
77 description: Some("Workflow metadata to contextualize the receipt".to_string()),
78 ..Default::default()
79 })),
80 object: Some(Box::new(ObjectValidation {
81 properties: BTreeMap::from([
82 ("name".to_owned(), <String>::json_schema(gen)),
83 ("replayed".to_owned(), <bool>::json_schema(gen)),
84 (
85 "workflow".to_owned(),
86 gen.subschema_for::<schema::IpldLinkStub>(),
87 ),
88 ]),
89 required: BTreeSet::from([
90 "name".to_string(),
91 "receipt".to_string(),
92 "receipt_cid".to_string(),
93 ]),
94 ..Default::default()
95 })),
96 ..Default::default()
97 };
98
99 let schema = SchemaObject {
100 instance_type: Some(SingleOrVec::Single(InstanceType::Object.into())),
101 metadata: Some(Box::new(Metadata {
102 title: Some("Receipt notification".to_string()),
103 description: Some(
104 "A receipt notification associated with a running workflow".to_string(),
105 ),
106 ..Default::default()
107 })),
108 object: Some(Box::new(ObjectValidation {
109 properties: BTreeMap::from([
110 ("metadata".to_owned(), Schema::Object(metadata_schema)),
111 ("receipt".to_owned(), gen.subschema_for::<Receipt<()>>()),
112 (
113 "receipt_cid".to_owned(),
114 gen.subschema_for::<schema::IpldLinkStub>(),
115 ),
116 ]),
117 required: BTreeSet::from(["receipt".to_string(), "receipt_cid".to_string()]),
118 ..Default::default()
119 })),
120 ..Default::default()
121 };
122
123 schema.into()
124 }
125}