1use std::fmt;
9
10use super::list::List;
12use crate::crdt::{
13 CRDTError, Doc,
14 traits::{CRDT, Data},
15};
16
17#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
81pub enum Value {
82 Null,
85 Bool(bool),
87 Int(i64),
89 Text(String),
91
92 Doc(Doc),
95 List(List),
97
98 Deleted,
101}
102
103impl Value {
104 pub fn is_leaf(&self) -> bool {
106 matches!(
107 self,
108 Value::Null | Value::Bool(_) | Value::Int(_) | Value::Text(_) | Value::Deleted
109 )
110 }
111
112 pub fn is_branch(&self) -> bool {
114 matches!(self, Value::Doc(_) | Value::List(_))
115 }
116
117 pub fn is_deleted(&self) -> bool {
119 matches!(self, Value::Deleted)
120 }
121
122 pub fn is_null(&self) -> bool {
124 matches!(self, Value::Null)
125 }
126
127 pub fn type_name(&self) -> &'static str {
129 match self {
130 Value::Null => "null",
131 Value::Bool(_) => "bool",
132 Value::Int(_) => "int",
133 Value::Text(_) => "text",
134 Value::Doc(_) => "doc",
135 Value::List(_) => "list",
136 Value::Deleted => "deleted",
137 }
138 }
139
140 pub fn as_bool(&self) -> Option<bool> {
142 match self {
143 Value::Bool(b) => Some(*b),
144 _ => None,
145 }
146 }
147
148 pub fn as_bool_or(&self, default: bool) -> bool {
150 self.as_bool().unwrap_or(default)
151 }
152
153 pub fn as_bool_or_false(&self) -> bool {
155 self.as_bool().unwrap_or(false)
156 }
157
158 pub fn as_int(&self) -> Option<i64> {
160 match self {
161 Value::Int(n) => Some(*n),
162 _ => None,
163 }
164 }
165
166 pub fn as_int_or(&self, default: i64) -> i64 {
168 self.as_int().unwrap_or(default)
169 }
170
171 pub fn as_int_or_zero(&self) -> i64 {
173 self.as_int().unwrap_or(0)
174 }
175
176 pub fn as_text(&self) -> Option<&str> {
178 match self {
179 Value::Text(s) => Some(s),
180 _ => None,
181 }
182 }
183
184 pub fn as_text_or_empty(&self) -> &str {
186 self.as_text().unwrap_or("")
187 }
188
189 pub fn as_doc(&self) -> Option<&Doc> {
191 match self {
192 Value::Doc(node) => Some(node),
193 _ => None,
194 }
195 }
196
197 pub fn as_doc_mut(&mut self) -> Option<&mut Doc> {
199 match self {
200 Value::Doc(node) => Some(node),
201 _ => None,
202 }
203 }
204
205 pub fn as_list(&self) -> Option<&List> {
207 match self {
208 Value::List(list) => Some(list),
209 _ => None,
210 }
211 }
212
213 pub fn as_list_mut(&mut self) -> Option<&mut List> {
215 match self {
216 Value::List(list) => Some(list),
217 _ => None,
218 }
219 }
220
221 pub fn merge(&mut self, other: &Value) {
223 if matches!(self, Value::Deleted) {
224 *self = other.clone();
226 return;
227 }
228
229 if matches!(other, Value::Deleted) {
230 *self = Value::Deleted;
232 return;
233 }
234
235 match other {
237 Value::Doc(other_node) => {
238 if let Value::Doc(self_node) = self {
239 match self_node.merge(other_node) {
240 Ok(merged) => *self_node = merged,
241 Err(_) => *self = other.clone(),
242 }
243 } else {
244 *self = other.clone();
245 }
246 }
247 Value::List(other_list) => {
248 if let Value::List(self_list) = self {
249 self_list.merge(other_list);
250 } else {
251 *self = other.clone();
253 }
254 }
255 _ => {
256 *self = other.clone();
258 }
259 }
260 }
261
262 pub fn to_json_string(&self) -> String {
284 match self {
285 Value::Null => "null".to_string(),
286 Value::Bool(b) => b.to_string(),
287 Value::Int(n) => n.to_string(),
288 Value::Text(s) => format!("\"{}\"", s.replace('\"', "\\\"")),
289 Value::Doc(doc) => doc.to_json_string(),
290 Value::List(list) => {
291 let mut result = String::with_capacity(list.len() * 8); result.push('[');
293 for (i, item) in list.iter().enumerate() {
294 if i > 0 {
295 result.push(',');
296 }
297 result.push_str(&item.to_json_string());
298 }
299 result.push(']');
300 result
301 }
302 Value::Deleted => "null".to_string(), }
304 }
305}
306
307impl fmt::Display for Value {
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 match self {
310 Value::Null => write!(f, "null"),
311 Value::Bool(b) => write!(f, "{b}"),
312 Value::Int(n) => write!(f, "{n}"),
313 Value::Text(s) => write!(f, "{s}"),
314 Value::Doc(doc) => write!(f, "{doc}"),
315 Value::List(list) => {
316 write!(f, "[")?;
317 for (i, item) in list.iter().enumerate() {
318 if i > 0 {
319 write!(f, ", ")?;
320 }
321 write!(f, "{item}")?;
322 }
323 write!(f, "]")
324 }
325 Value::Deleted => write!(f, "<deleted>"),
326 }
327 }
328}
329
330impl From<bool> for Value {
332 fn from(value: bool) -> Self {
333 Value::Bool(value)
334 }
335}
336
337impl From<i64> for Value {
338 fn from(value: i64) -> Self {
339 Value::Int(value)
340 }
341}
342
343impl From<u64> for Value {
344 fn from(value: u64) -> Self {
345 Value::Int(value as i64)
347 }
348}
349
350impl From<f64> for Value {
351 fn from(value: f64) -> Self {
352 Value::Int(value as i64)
354 }
355}
356
357impl From<i32> for Value {
358 fn from(value: i32) -> Self {
359 Value::Int(value as i64)
360 }
361}
362
363impl From<u32> for Value {
364 fn from(value: u32) -> Self {
365 Value::Int(value as i64)
366 }
367}
368
369impl From<f32> for Value {
370 fn from(value: f32) -> Self {
371 Value::Int(value as i64)
372 }
373}
374
375impl From<String> for Value {
376 fn from(value: String) -> Self {
377 Value::Text(value)
378 }
379}
380
381impl From<&str> for Value {
382 fn from(value: &str) -> Self {
383 Value::Text(value.to_string())
384 }
385}
386
387impl From<Doc> for Value {
388 fn from(value: Doc) -> Self {
389 Value::Doc(value)
390 }
391}
392
393impl From<List> for Value {
394 fn from(value: List) -> Self {
395 Value::List(value)
396 }
397}
398
399impl TryFrom<&Value> for String {
405 type Error = CRDTError;
406
407 fn try_from(value: &Value) -> Result<Self, Self::Error> {
408 match value {
409 Value::Text(s) => Ok(s.clone()),
410 _ => Err(CRDTError::TypeMismatch {
411 expected: "String".to_string(),
412 actual: format!("{value:?}"),
413 }),
414 }
415 }
416}
417
418impl<'a> TryFrom<&'a Value> for &'a str {
419 type Error = CRDTError;
420
421 fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
422 match value {
423 Value::Text(s) => Ok(s),
424 _ => Err(CRDTError::TypeMismatch {
425 expected: "&str".to_string(),
426 actual: format!("{value:?}"),
427 }),
428 }
429 }
430}
431
432impl TryFrom<&Value> for i64 {
433 type Error = CRDTError;
434
435 fn try_from(value: &Value) -> Result<Self, Self::Error> {
436 match value {
437 Value::Int(n) => Ok(*n),
438 _ => Err(CRDTError::TypeMismatch {
439 expected: "i64".to_string(),
440 actual: format!("{value:?}"),
441 }),
442 }
443 }
444}
445
446impl TryFrom<&Value> for bool {
447 type Error = CRDTError;
448
449 fn try_from(value: &Value) -> Result<Self, Self::Error> {
450 match value {
451 Value::Bool(b) => Ok(*b),
452 _ => Err(CRDTError::TypeMismatch {
453 expected: "bool".to_string(),
454 actual: format!("{value:?}"),
455 }),
456 }
457 }
458}
459
460impl TryFrom<&Value> for Doc {
465 type Error = CRDTError;
466
467 fn try_from(value: &Value) -> Result<Self, Self::Error> {
468 match value {
469 Value::Doc(doc) => Ok(doc.clone()),
470 _ => Err(CRDTError::TypeMismatch {
471 expected: "Doc".to_string(),
472 actual: format!("{value:?}"),
473 }),
474 }
475 }
476}
477
478impl TryFrom<&Value> for List {
479 type Error = CRDTError;
480
481 fn try_from(value: &Value) -> Result<Self, Self::Error> {
482 match value {
483 Value::List(list) => Ok(list.clone()),
484 _ => Err(CRDTError::TypeMismatch {
485 expected: "List".to_string(),
486 actual: format!("{value:?}"),
487 }),
488 }
489 }
490}
491
492impl PartialEq<str> for Value {
494 fn eq(&self, other: &str) -> bool {
495 match self {
496 Value::Text(s) => s == other,
497 _ => false,
498 }
499 }
500}
501
502impl PartialEq<&str> for Value {
503 fn eq(&self, other: &&str) -> bool {
504 self == *other
505 }
506}
507
508impl PartialEq<String> for Value {
509 fn eq(&self, other: &String) -> bool {
510 match self {
511 Value::Text(s) => s == other,
512 _ => false,
513 }
514 }
515}
516
517impl PartialEq<i64> for Value {
518 fn eq(&self, other: &i64) -> bool {
519 match self {
520 Value::Int(n) => n == other,
521 _ => false,
522 }
523 }
524}
525
526impl PartialEq<i32> for Value {
527 fn eq(&self, other: &i32) -> bool {
528 match self {
529 Value::Int(n) => *n == *other as i64,
530 _ => false,
531 }
532 }
533}
534
535impl PartialEq<u32> for Value {
536 fn eq(&self, other: &u32) -> bool {
537 match self {
538 Value::Int(n) => *n == *other as i64,
539 _ => false,
540 }
541 }
542}
543
544impl PartialEq<bool> for Value {
545 fn eq(&self, other: &bool) -> bool {
546 match self {
547 Value::Bool(b) => b == other,
548 _ => false,
549 }
550 }
551}
552
553impl PartialEq<Value> for str {
555 fn eq(&self, other: &Value) -> bool {
556 other == self
557 }
558}
559
560impl PartialEq<Value> for &str {
561 fn eq(&self, other: &Value) -> bool {
562 other == *self
563 }
564}
565
566impl PartialEq<Value> for String {
567 fn eq(&self, other: &Value) -> bool {
568 other == self
569 }
570}
571
572impl PartialEq<Value> for i64 {
573 fn eq(&self, other: &Value) -> bool {
574 other == self
575 }
576}
577
578impl PartialEq<Value> for i32 {
579 fn eq(&self, other: &Value) -> bool {
580 other == self
581 }
582}
583
584impl PartialEq<Value> for u32 {
585 fn eq(&self, other: &Value) -> bool {
586 other == self
587 }
588}
589
590impl PartialEq<Value> for bool {
591 fn eq(&self, other: &Value) -> bool {
592 other == self
593 }
594}
595
596impl Data for Value {}