1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2use std::time::Duration;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct TimeoutConfig {
7 #[serde(
9 default,
10 serialize_with = "ser_opt_duration",
11 deserialize_with = "de_opt_duration"
12 )]
13 pub node_timeout: Option<Duration>,
14 #[serde(
16 default,
17 serialize_with = "ser_opt_duration",
18 deserialize_with = "de_opt_duration"
19 )]
20 pub workflow_timeout: Option<Duration>,
21 #[serde(
24 default = "default_heartbeat",
25 serialize_with = "ser_duration",
26 deserialize_with = "de_duration"
27 )]
28 pub heartbeat_interval: Duration,
29 #[serde(
31 default,
32 serialize_with = "ser_opt_duration",
33 deserialize_with = "de_opt_duration"
34 )]
35 pub approval_timeout: Option<Duration>,
36}
37
38fn default_heartbeat() -> Duration {
39 Duration::from_secs(30)
40}
41
42impl Default for TimeoutConfig {
43 fn default() -> Self {
44 Self {
45 node_timeout: Some(Duration::from_secs(300)), workflow_timeout: None,
47 heartbeat_interval: default_heartbeat(),
48 approval_timeout: None,
49 }
50 }
51}
52
53fn ser_duration<S: Serializer>(d: &Duration, s: S) -> Result<S::Ok, S::Error> {
55 s.serialize_u64(d.as_secs())
56}
57
58fn ser_opt_duration<S: Serializer>(d: &Option<Duration>, s: S) -> Result<S::Ok, S::Error> {
59 match d {
60 Some(d) => s.serialize_some(&d.as_secs()),
61 None => s.serialize_none(),
62 }
63}
64
65fn de_duration<'de, D: Deserializer<'de>>(d: D) -> Result<Duration, D::Error> {
67 #[derive(Deserialize)]
68 #[serde(untagged)]
69 enum DurationRepr {
70 Secs(u64),
71 Struct { secs: u64, nanos: u32 },
72 }
73 match DurationRepr::deserialize(d)? {
74 DurationRepr::Secs(s) => Ok(Duration::from_secs(s)),
75 DurationRepr::Struct { secs, nanos } => Ok(Duration::new(secs, nanos)),
76 }
77}
78
79fn de_opt_duration<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Duration>, D::Error> {
80 #[derive(Deserialize)]
81 #[serde(untagged)]
82 enum OptDurationRepr {
83 Null,
84 Secs(u64),
85 Struct { secs: u64, nanos: u32 },
86 }
87 match Option::<OptDurationRepr>::deserialize(d)? {
88 None | Some(OptDurationRepr::Null) => Ok(None),
89 Some(OptDurationRepr::Secs(s)) => Ok(Some(Duration::from_secs(s))),
90 Some(OptDurationRepr::Struct { secs, nanos }) => Ok(Some(Duration::new(secs, nanos))),
91 }
92}