1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//! Data validation and soul reference detection
//!
//! This module validates data values according to Gun's rules and detects soul references.
//! Based on Gun.js `valid.js` - matches the exact validation logic.
//!
//! ## Valid Data Types
//!
//! - `null` - Valid (represents deletion)
//! - `string` - Always valid
//! - `boolean` - Always valid
//! - `number` - Valid if not `Infinity` or `NaN`
//! - Soul reference - Object with only `{"#": "soul_id"}` key
//! - Objects - Not directly valid (must be stored as nodes)
//! - Arrays - Not directly supported
use Value;
/// Validate a value according to Gun's rules and detect soul references
///
/// This is the main validation function matching Gun.js `valid()`. It checks if
/// a value is valid for storage in Gun and detects if it's a soul reference.
///
/// # Arguments
/// * `value` - The JSON value to validate
///
/// # Returns
///
/// - `Ok(true)` - Valid simple value (null, string, boolean, or valid number)
/// - `Err(Some(soul))` - It's a soul reference object `{"#": soul}`
/// - `Ok(false)` - Invalid value (Infinity, NaN, array, or complex object)
///
/// # Example
///
/// ```rust,no_run
/// use gun::valid::valid;
/// use serde_json::json;
///
/// // Valid simple value
/// assert_eq!(valid(&json!("hello")), Ok(true));
///
/// // Valid number
/// assert_eq!(valid(&json!(42)), Ok(true));
///
/// // Invalid number
/// assert_eq!(valid(&json!(f64::INFINITY)), Ok(false));
///
/// // Soul reference
/// match valid(&json!({"#": "user_123"})) {
/// Err(Some(soul)) => println!("Found soul reference: {}", soul),
/// _ => {}
/// }
/// ```
/// Check if a value is a valid soul reference
///
/// This checks if a value represents a soul reference, either as:
/// - A soul reference object: `{"#": "soul_id"}`
/// - A string that could be a soul ID
///
/// # Arguments
/// * `value` - The JSON value to check
///
/// # Returns
/// `Some(soul_string)` if it's a soul reference, `None` otherwise.
///
/// # Example
///
/// ```rust,no_run
/// use gun::valid::valid_soul;
/// use serde_json::json;
///
/// // Soul reference object
/// assert_eq!(valid_soul(&json!({"#": "user_123"})), Some("user_123".to_string()));
///
/// // Soul string
/// assert_eq!(valid_soul(&json!("user_123")), Some("user_123".to_string()));
///
/// // Not a soul
/// assert_eq!(valid_soul(&json!("hello")), Some("hello".to_string())); // Strings are treated as potential souls
/// ```
/// Check if data is valid for storage in Gun
///
/// This is a convenience function that returns `true` if the value is either:
/// - A valid simple value (validated by [`valid`](valid))
/// - A soul reference
///
/// # Arguments
/// * `value` - The JSON value to check
///
/// # Returns
/// `true` if the value is valid for Gun, `false` otherwise.
///
/// # Example
///
/// ```rust,no_run
/// use gun::valid::is_valid_data;
/// use serde_json::json;
///
/// assert!(is_valid_data(&json!("hello")));
/// assert!(is_valid_data(&json!(42)));
/// assert!(is_valid_data(&json!({"#": "user_123"})));
/// assert!(!is_valid_data(&json!(f64::INFINITY)));
/// ```