stackless_cloud/
checkpoint.rs1use stackless_core::substrate::ACTION_RESOURCE_KIND;
8
9pub fn is_ephemeral_resource_kind(kind: &str) -> bool {
11 kind == ACTION_RESOURCE_KIND || kind == "source-ref"
12}
13
14pub fn parse_payload<T: serde::de::DeserializeOwned>(payload: &str) -> Result<Option<T>, String> {
17 let trimmed = payload.trim();
18 if trimmed.is_empty() {
19 return Ok(None);
20 }
21 serde_json::from_str(trimmed)
22 .map(Some)
23 .map_err(|err| format!("malformed checkpoint payload: {err}"))
24}
25
26#[cfg(test)]
27mod tests {
28 use super::*;
29 use serde::Deserialize;
30
31 #[derive(Debug, Deserialize, PartialEq)]
32 struct Sample {
33 id: String,
34 }
35
36 #[test]
37 fn empty_payload_is_none() {
38 assert_eq!(parse_payload::<Sample>("").unwrap(), None);
39 assert_eq!(parse_payload::<Sample>(" ").unwrap(), None);
40 }
41
42 #[test]
43 fn valid_payload_parses() {
44 let got = parse_payload::<Sample>(r#"{"id":"x"}"#).unwrap();
45 assert_eq!(got, Some(Sample { id: "x".into() }));
46 }
47
48 #[test]
49 fn malformed_nonempty_errors() {
50 assert!(parse_payload::<Sample>("{").is_err());
51 }
52
53 #[test]
54 fn ephemeral_kinds() {
55 assert!(is_ephemeral_resource_kind("action"));
56 assert!(is_ephemeral_resource_kind("source-ref"));
57 assert!(!is_ephemeral_resource_kind("render-service"));
58 }
59}