greentic_types/
session.rs

1//! Session identity and cursor helpers.
2
3use alloc::borrow::ToOwned;
4use alloc::string::String;
5
6#[cfg(feature = "schemars")]
7use schemars::JsonSchema;
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11/// Unique key referencing a persisted session.
12#[derive(Clone, Debug, PartialEq, Eq, Hash)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14#[cfg_attr(feature = "schemars", derive(JsonSchema))]
15#[cfg_attr(feature = "serde", serde(transparent))]
16pub struct SessionKey(pub String);
17
18impl SessionKey {
19    /// Returns the session key as a string slice.
20    pub fn as_str(&self) -> &str {
21        &self.0
22    }
23
24    /// Creates a new session key from the supplied string.
25    pub fn new(value: impl Into<String>) -> Self {
26        Self(value.into())
27    }
28
29    /// Generates a random session key using [`uuid`], when enabled.
30    #[cfg(feature = "uuid")]
31    pub fn generate() -> Self {
32        Self(uuid::Uuid::new_v4().to_string())
33    }
34}
35
36impl From<String> for SessionKey {
37    fn from(value: String) -> Self {
38        Self(value)
39    }
40}
41
42impl From<&str> for SessionKey {
43    fn from(value: &str) -> Self {
44        Self(value.to_owned())
45    }
46}
47
48impl core::fmt::Display for SessionKey {
49    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50        f.write_str(self.as_str())
51    }
52}
53
54#[cfg(feature = "uuid")]
55impl From<uuid::Uuid> for SessionKey {
56    fn from(value: uuid::Uuid) -> Self {
57        Self(value.to_string())
58    }
59}
60
61/// Cursor pointing at a session's position in a flow graph.
62#[derive(Clone, Debug, PartialEq, Eq, Hash)]
63#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
64#[cfg_attr(feature = "schemars", derive(JsonSchema))]
65pub struct SessionCursor {
66    /// Identifier of the node currently owning the session.
67    pub node_pointer: String,
68    /// Optional wait reason emitted by the node.
69    #[cfg_attr(
70        feature = "serde",
71        serde(default, skip_serializing_if = "Option::is_none")
72    )]
73    pub wait_reason: Option<String>,
74    /// Optional marker describing pending outbox operations.
75    #[cfg_attr(
76        feature = "serde",
77        serde(default, skip_serializing_if = "Option::is_none")
78    )]
79    pub outbox_marker: Option<String>,
80}
81
82impl SessionCursor {
83    /// Creates a new cursor pointing at the provided node identifier.
84    pub fn new(node_pointer: impl Into<String>) -> Self {
85        Self {
86            node_pointer: node_pointer.into(),
87            wait_reason: None,
88            outbox_marker: None,
89        }
90    }
91
92    /// Assigns a wait reason to the cursor.
93    pub fn with_wait_reason(mut self, reason: impl Into<String>) -> Self {
94        self.wait_reason = Some(reason.into());
95        self
96    }
97
98    /// Assigns an outbox marker to the cursor.
99    pub fn with_outbox_marker(mut self, marker: impl Into<String>) -> Self {
100        self.outbox_marker = Some(marker.into());
101        self
102    }
103}