Skip to main content

agentic_core/utils/
common.rs

1use chrono::Utc;
2use uuid::Uuid;
3
4#[must_use]
5pub fn uuid7_str(prefix: &str) -> String {
6    format!("{}{}", prefix, Uuid::now_v7())
7}
8
9#[must_use]
10pub fn utcnow_str() -> i64 {
11    Utc::now().timestamp()
12}
13
14/// Serialize any type to JSON string.
15///
16/// Strict serialization - returns error if serialization fails.
17/// Used in persistence operations where we control the data types.
18///
19/// # Errors
20///
21/// Returns `serde_json::Error` if serialization fails.
22pub fn serialize_to_string<T: serde::Serialize>(value: &T) -> Result<String, serde_json::Error> {
23    serde_json::to_string(value)
24}
25
26/// Serialize any type to a `serde_json::Value`.
27///
28/// # Errors
29///
30/// Returns `serde_json::Error` if serialization fails.
31pub fn serialize_to_value<T: serde::Serialize>(value: &T) -> Result<serde_json::Value, serde_json::Error> {
32    serde_json::to_value(value)
33}
34
35/// Serializes `value` to a `serde_json::Value` and passes it to `then`,
36/// logging `message` at `debug` level and returning `default` if
37/// serialization fails.
38///
39/// Graceful serialization - used where callers fall back to a default result
40/// rather than propagate a serialization error.
41pub fn serialize_to_value_or_custom_default<T: serde::Serialize, R>(
42    value: &T,
43    message: &str,
44    then: impl FnOnce(serde_json::Value) -> R,
45    default: R,
46) -> R {
47    match serde_json::to_value(value) {
48        Ok(config) => then(config),
49        Err(error) => {
50            tracing::debug!(error = %error, message);
51            default
52        }
53    }
54}
55
56/// Deserialize JSON string to any type.
57///
58/// Strict deserialization - returns error if deserialization fails.
59/// Used when we need explicit error handling for data integrity.
60///
61/// # Errors
62///
63/// Returns `serde_json::Error` if deserialization fails.
64pub fn deserialize_from_str<T: serde::de::DeserializeOwned>(json_str: &str) -> Result<T, serde_json::Error> {
65    serde_json::from_str(json_str)
66}
67
68/// Deserialize JSON string to any type with Default fallback.
69///
70/// Graceful deserialization - returns default value on error or empty string.
71/// Used in read operations where we accept corrupted data gracefully.
72#[must_use]
73pub fn deserialize_from_str_or_default<T: serde::de::DeserializeOwned + Default>(json_str: &str) -> T {
74    serde_json::from_str(json_str).unwrap_or_default()
75}
76
77/// Deserialize JSON string to any type, returning None on error.
78///
79/// Optional deserialization - returns None if JSON is invalid.
80/// Convenience function for cases where None represents missing data.
81#[must_use]
82pub fn deserialize_from_str_opt<T: serde::de::DeserializeOwned>(json_str: &str) -> Option<T> {
83    serde_json::from_str(json_str).ok()
84}
85
86/// Deserialize optional JSON String to any type, returning default on error or if None.
87///
88/// Graceful optional deserialization - returns default value for T if missing or invalid.
89#[must_use]
90pub fn deserialize_from_string_opt_or_default<T: serde::de::DeserializeOwned + Default>(
91    json_str: &Option<String>,
92) -> T {
93    json_str
94        .as_ref()
95        .and_then(|s| deserialize_from_str_opt::<T>(s))
96        .unwrap_or_default()
97}
98
99/// Deserialize optional JSON String to any type, returning None on error or if None.
100///
101/// Optional deserialization - returns None if missing or invalid JSON.
102#[must_use]
103pub fn deserialize_from_string_opt<T: serde::de::DeserializeOwned>(json_str: &Option<String>) -> Option<T> {
104    json_str.as_ref().and_then(|s| deserialize_from_str_opt::<T>(s))
105}
106
107/// Deserialize a `serde_json::Value` into `T`.
108///
109/// # Errors
110///
111/// Returns `serde_json::Error` if the value's shape does not match `T`.
112pub fn deserialize_from_value<T: serde::de::DeserializeOwned>(
113    value: serde_json::Value,
114) -> Result<T, serde_json::Error> {
115    serde_json::from_value(value)
116}
117
118/// Deserializes a `serde_json::Value` and passes it to `then`, logging
119/// `message` at `debug` level and returning `default` if deserialization fails.
120///
121/// Graceful deserialization - used where callers fall back to a default result
122/// rather than propagate a deserialization error.
123pub fn deserialize_from_value_or_custom_default<T: serde::de::DeserializeOwned, R>(
124    value: serde_json::Value,
125    message: &str,
126    then: impl FnOnce(T) -> R,
127    default: R,
128) -> R {
129    match serde_json::from_value(value) {
130        Ok(value) => then(value),
131        Err(error) => {
132            tracing::debug!(error = %error, message);
133            default
134        }
135    }
136}
137
138/// Deserialize a `serde_json::Value` into `T`, returning `None` on type mismatch.
139#[must_use]
140pub fn deserialize_from_value_opt<T: serde::de::DeserializeOwned>(value: serde_json::Value) -> Option<T> {
141    serde_json::from_value(value).ok()
142}
143
144/// Serialize any type to JSON bytes, returning an empty `Vec` on error.
145#[must_use]
146pub fn serialize_to_vec_or_default<T: serde::Serialize>(value: &T) -> Vec<u8> {
147    serde_json::to_vec(value).unwrap_or_default()
148}