lastid_sdk/types/
request_status.rs1use serde::{Deserialize, Serialize};
4
5use super::RequestId;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(tag = "status", rename_all = "lowercase")]
28#[non_exhaustive]
29pub enum RequestStatus {
30 Pending {
32 request_id: RequestId,
34 created_at: String,
36 },
37
38 Fulfilled {
40 request_id: RequestId,
42 presentation: String,
44 fulfilled_at: String,
46 },
47
48 Denied {
50 request_id: RequestId,
52 reason: String,
54 denied_at: String,
56 },
57
58 Expired {
60 request_id: RequestId,
62 expired_at: String,
64 },
65
66 NotFound {
68 request_id: RequestId,
70 message: String,
72 },
73
74 Timeout {
76 request_id: RequestId,
78 elapsed_seconds: u64,
80 },
81}
82
83impl RequestStatus {
84 #[must_use]
86 pub const fn is_terminal(&self) -> bool {
87 !matches!(self, Self::Pending { .. })
88 }
89
90 #[must_use]
92 pub const fn is_fulfilled(&self) -> bool {
93 matches!(self, Self::Fulfilled { .. })
94 }
95
96 #[must_use]
98 pub const fn request_id(&self) -> &RequestId {
99 match self {
100 Self::Pending { request_id, .. }
101 | Self::Fulfilled { request_id, .. }
102 | Self::Denied { request_id, .. }
103 | Self::Expired { request_id, .. }
104 | Self::NotFound { request_id, .. }
105 | Self::Timeout { request_id, .. } => request_id,
106 }
107 }
108
109 #[must_use]
111 pub fn presentation(&self) -> Option<&str> {
112 match self {
113 Self::Fulfilled { presentation, .. } => Some(presentation),
114 _ => None,
115 }
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn test_pending_not_terminal() {
125 let status = RequestStatus::Pending {
126 request_id: RequestId::new("req_123"),
127 created_at: "2026-01-16T12:00:00Z".into(),
128 };
129 assert!(!status.is_terminal());
130 assert!(!status.is_fulfilled());
131 }
132
133 #[test]
134 fn test_fulfilled_is_terminal() {
135 let status = RequestStatus::Fulfilled {
136 request_id: RequestId::new("req_123"),
137 presentation: "sdjwt".into(),
138 fulfilled_at: "2026-01-16T12:05:00Z".into(),
139 };
140 assert!(status.is_terminal());
141 assert!(status.is_fulfilled());
142 assert_eq!(status.presentation(), Some("sdjwt"));
143 }
144
145 #[test]
146 fn test_denied_is_terminal() {
147 let status = RequestStatus::Denied {
148 request_id: RequestId::new("req_123"),
149 reason: "User declined".into(),
150 denied_at: "2026-01-16T12:05:00Z".into(),
151 };
152 assert!(status.is_terminal());
153 assert!(!status.is_fulfilled());
154 }
155
156 #[test]
157 fn test_request_id_extraction() {
158 let status = RequestStatus::Pending {
159 request_id: RequestId::new("req_abc"),
160 created_at: "2026-01-16T12:00:00Z".into(),
161 };
162 assert_eq!(status.request_id().as_str(), "req_abc");
163 }
164
165 #[test]
166 fn test_serialize_pending() {
167 let status = RequestStatus::Pending {
168 request_id: RequestId::new("req_123"),
169 created_at: "2026-01-16T12:00:00Z".into(),
170 };
171
172 let json = serde_json::to_value(&status).unwrap();
173 assert_eq!(json["status"], "pending");
174 assert_eq!(json["request_id"], "req_123");
175 }
176
177 #[test]
178 fn test_deserialize_fulfilled() {
179 let json = r#"{
180 "status": "fulfilled",
181 "request_id": "req_123",
182 "presentation": "eyJhbGciOiJFUzI1NiJ9...",
183 "fulfilled_at": "2026-01-16T12:05:00Z"
184 }"#;
185
186 let status: RequestStatus = serde_json::from_str(json).unwrap();
187 assert!(status.is_fulfilled());
188 assert_eq!(status.request_id().as_str(), "req_123");
189 }
190
191 #[test]
192 fn test_notfound_is_terminal() {
193 let status = RequestStatus::NotFound {
194 request_id: RequestId::new("req_123"),
195 message: "Verification request not found".into(),
196 };
197 assert!(status.is_terminal());
198 assert!(!status.is_fulfilled());
199 assert_eq!(status.request_id().as_str(), "req_123");
200 }
201
202 #[test]
203 fn test_serialize_notfound() {
204 let status = RequestStatus::NotFound {
205 request_id: RequestId::new("req_404"),
206 message: "Request deleted or expired".into(),
207 };
208
209 let json = serde_json::to_value(&status).unwrap();
210 assert_eq!(json["status"], "notfound");
211 assert_eq!(json["request_id"], "req_404");
212 assert_eq!(json["message"], "Request deleted or expired");
213 }
214
215 #[test]
216 fn test_deserialize_notfound() {
217 let json = r#"{
218 "status": "notfound",
219 "request_id": "req_404",
220 "message": "Verification request not found"
221 }"#;
222
223 let status: RequestStatus = serde_json::from_str(json).unwrap();
224 assert!(status.is_terminal());
225 assert!(!status.is_fulfilled());
226 assert_eq!(status.request_id().as_str(), "req_404");
227 }
228}