1use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6use crate::ids::{CaseId, CaseRevision, WorkflowKey};
7
8#[derive(
11 Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
12)]
13pub struct CaseKey {
14 pub workflow: WorkflowKey,
16 pub case_id: CaseId,
18}
19
20impl CaseKey {
21 #[must_use]
23 pub fn new(workflow: impl Into<WorkflowKey>, case_id: impl Into<CaseId>) -> Self {
24 Self {
25 workflow: workflow.into(),
26 case_id: case_id.into(),
27 }
28 }
29
30 #[must_use]
32 pub fn at(self, expected_revision: CaseRevision) -> CaseRef {
33 CaseRef {
34 workflow: self.workflow,
35 case_id: self.case_id,
36 expected_revision,
37 }
38 }
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
46pub struct CaseRef {
47 pub workflow: WorkflowKey,
49 pub case_id: CaseId,
51 pub expected_revision: CaseRevision,
53}
54
55impl CaseRef {
56 #[must_use]
58 pub fn new(
59 workflow: impl Into<WorkflowKey>,
60 case_id: impl Into<CaseId>,
61 expected_revision: CaseRevision,
62 ) -> Self {
63 Self {
64 workflow: workflow.into(),
65 case_id: case_id.into(),
66 expected_revision,
67 }
68 }
69
70 #[must_use]
72 pub fn key(&self) -> CaseKey {
73 CaseKey {
74 workflow: self.workflow.clone(),
75 case_id: self.case_id.clone(),
76 }
77 }
78
79 #[must_use]
81 pub fn with_revision(&self, revision: CaseRevision) -> Self {
82 Self {
83 workflow: self.workflow.clone(),
84 case_id: self.case_id.clone(),
85 expected_revision: revision,
86 }
87 }
88
89 #[must_use]
92 pub fn same_case(&self, other: &CaseRef) -> bool {
93 self.workflow == other.workflow && self.case_id == other.case_id
94 }
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
99pub struct Versioned<T> {
100 pub value: T,
102 pub revision: CaseRevision,
104}
105
106impl<T> Versioned<T> {
107 #[must_use]
109 pub const fn new(value: T, revision: CaseRevision) -> Self {
110 Self { value, revision }
111 }
112
113 #[must_use]
115 pub const fn as_ref(&self) -> Versioned<&T> {
116 Versioned {
117 value: &self.value,
118 revision: self.revision,
119 }
120 }
121
122 #[must_use]
124 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Versioned<U> {
125 Versioned {
126 value: f(self.value),
127 revision: self.revision,
128 }
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn case_ref_key_and_revision_helpers() {
138 let r = CaseRef::new("trip", "trip-1", CaseRevision(4));
139 assert_eq!(r.key(), CaseKey::new("trip", "trip-1"));
140 assert_eq!(
141 r.with_revision(CaseRevision(5)).expected_revision,
142 CaseRevision(5)
143 );
144 assert!(r.same_case(&r.with_revision(CaseRevision(9))));
145 assert_eq!(CaseKey::new("trip", "trip-1").at(CaseRevision(4)), r);
146 }
147
148 #[test]
149 fn versioned_map_keeps_revision() {
150 let v = Versioned::new(2_u32, CaseRevision(7)).map(|n| n * 2);
151 assert_eq!(v.value, 4);
152 assert_eq!(v.revision, CaseRevision(7));
153 }
154}