wp_model_core/model/data/
storage.rs1use crate::model::DataType;
2use crate::model::FieldRef;
3use crate::model::Value;
4use crate::model::format::LevelFormatAble;
5use crate::model::{FNameStr, FValueStr};
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use std::fmt::{Display, Formatter};
8use std::net::IpAddr;
9use std::sync::Arc;
10
11use super::field::Field;
12use super::record::{RecordItem, RecordItemFactory};
13
14#[derive(Clone, Debug)]
16pub enum ValueStorage {
17 Shared(Arc<Field<Value>>),
19
20 Owned(Field<Value>),
22}
23
24#[derive(Clone, Debug)]
56pub struct FieldStorage {
57 pub(crate) cur_name: Option<FNameStr>,
60
61 value: ValueStorage,
63}
64
65impl FieldStorage {
66 #[inline]
80 pub fn from_shared(field: Arc<Field<Value>>) -> Self {
81 Self {
82 cur_name: None,
83 value: ValueStorage::Shared(field),
84 }
85 }
86
87 #[inline]
100 pub fn from_owned(field: Field<Value>) -> Self {
101 Self {
102 cur_name: None,
103 value: ValueStorage::Owned(field),
104 }
105 }
106
107 #[inline]
126 pub fn set_name(&mut self, name: impl Into<FNameStr>) {
127 self.cur_name = Some(name.into());
128 }
129
130 #[inline]
134 pub fn get_name(&self) -> &str {
135 if let Some(ref name) = self.cur_name {
136 name.as_str()
137 } else {
138 self.as_field().get_name()
139 }
140 }
141
142 #[inline]
151 pub fn as_field(&self) -> &Field<Value> {
152 match &self.value {
153 ValueStorage::Shared(arc) => arc.as_ref(),
154 ValueStorage::Owned(field) => field,
155 }
156 }
157
158 pub fn into_owned(self) -> Field<Value> {
167 let mut field = match self.value {
168 ValueStorage::Shared(arc) => {
169 Arc::try_unwrap(arc).unwrap_or_else(|arc| (*arc).clone())
171 }
172 ValueStorage::Owned(field) => field,
173 };
174
175 if let Some(name) = self.cur_name {
177 field.set_name(name);
178 }
179
180 field
181 }
182
183 #[inline]
185 pub fn is_shared(&self) -> bool {
186 matches!(self.value, ValueStorage::Shared(_))
187 }
188
189 #[inline]
191 pub fn is_owned(&self) -> bool {
192 matches!(self.value, ValueStorage::Owned(_))
193 }
194
195 pub fn shared_count(&self) -> Option<usize> {
199 match &self.value {
200 ValueStorage::Shared(arc) => Some(Arc::strong_count(arc)),
201 ValueStorage::Owned(_) => None,
202 }
203 }
204
205 pub fn as_field_mut(&mut self) -> &mut Field<Value> {
220 if let ValueStorage::Shared(_) = self.value {
222 let old_value = std::mem::replace(
223 &mut self.value,
224 ValueStorage::Owned(Field::new(DataType::Ignore, "", Value::from(false))),
225 );
226 let field = match old_value {
227 ValueStorage::Shared(arc) => {
228 Arc::try_unwrap(arc).unwrap_or_else(|arc| (*arc).clone())
229 }
230 ValueStorage::Owned(field) => field,
231 };
232 self.value = ValueStorage::Owned(field);
233 }
234
235 if let Some(name) = self.cur_name.take()
237 && let ValueStorage::Owned(ref mut field) = self.value
238 {
239 field.set_name(name);
240 }
241
242 match &mut self.value {
243 ValueStorage::Owned(field) => field,
244 ValueStorage::Shared(_) => unreachable!(),
245 }
246 }
247
248 #[inline]
250 pub fn get_value(&self) -> &Value {
251 self.as_field().get_value()
252 }
253
254 #[inline]
256 pub fn get_meta(&self) -> &DataType {
257 self.as_field().get_meta()
258 }
259
260 #[inline]
278 pub fn field_ref(&self) -> FieldRef<'_> {
279 FieldRef { storage: self }
280 }
281}
282
283impl Display for FieldStorage {
285 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
286 self.as_field().fmt(f)
287 }
288}
289
290impl PartialEq for FieldStorage {
292 fn eq(&self, other: &Self) -> bool {
293 self.get_name() == other.get_name()
294 && self.as_field().get_meta() == other.as_field().get_meta()
295 && self.as_field().get_value() == other.as_field().get_value()
296 }
297}
298
299impl Eq for FieldStorage {}
300
301impl Serialize for FieldStorage {
303 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
304 where
305 S: Serializer,
306 {
307 if let Some(ref name) = self.cur_name {
308 let mut field = self.as_field().clone();
310 field.set_name(name.as_str());
311 field.serialize(serializer)
312 } else {
313 self.as_field().serialize(serializer)
314 }
315 }
316}
317
318impl<'de> Deserialize<'de> for FieldStorage {
320 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
321 where
322 D: Deserializer<'de>,
323 {
324 Field::<Value>::deserialize(deserializer).map(FieldStorage::from_owned)
325 }
326}
327
328impl RecordItem for FieldStorage {
330 fn get_name(&self) -> &str {
331 if let Some(ref name) = self.cur_name {
332 name.as_str()
333 } else {
334 self.as_field().get_name()
335 }
336 }
337
338 fn get_meta(&self) -> &DataType {
339 self.as_field().get_meta()
340 }
341
342 fn get_value(&self) -> &Value {
343 self.as_field().get_value()
344 }
345
346 fn get_value_mut(&mut self) -> &mut Value {
347 self.as_field_mut().get_value_mut()
348 }
349}
350
351impl RecordItemFactory for FieldStorage {
353 fn from_digit<S: Into<FNameStr>>(name: S, val: i64) -> Self {
354 FieldStorage::from_owned(Field::from_digit(name, val))
355 }
356
357 fn from_ip<S: Into<FNameStr>>(name: S, ip: IpAddr) -> Self {
358 FieldStorage::from_owned(Field::from_ip(name, ip))
359 }
360
361 fn from_chars<N: Into<FNameStr>, Val: Into<FValueStr>>(name: N, val: Val) -> Self {
362 FieldStorage::from_owned(Field::from_chars(name, val))
363 }
364}
365
366impl LevelFormatAble for FieldStorage {
368 fn level_fmt(&self, f: &mut Formatter<'_>, level: usize) -> std::fmt::Result {
369 if let Some(ref name) = self.cur_name {
370 let meta: String = From::from(self.as_field().get_meta());
371 writeln!(
372 f,
373 "{:width$}[{:<16}] {:<20} : {}",
374 "",
375 meta,
376 name,
377 self.as_field().value,
378 width = level * 6
379 )
380 } else {
381 self.as_field().level_fmt(f, level)
382 }
383 }
384}
385
386impl From<Field<Value>> for FieldStorage {
388 fn from(field: Field<Value>) -> Self {
389 FieldStorage::from_owned(field)
390 }
391}
392
393impl From<Arc<Field<Value>>> for FieldStorage {
394 fn from(arc: Arc<Field<Value>>) -> Self {
395 FieldStorage::from_shared(arc)
396 }
397}
398
399#[cfg(test)]
400mod tests {
401 use super::*;
402 use crate::model::DataType;
403
404 #[test]
405 fn test_field_storage_shared_variant() {
406 let field = Field::new(DataType::Chars, "test", Value::from("hello"));
407 let storage = FieldStorage::from_shared(Arc::new(field.clone()));
408
409 assert_eq!(storage.as_field().get_name(), "test");
411 assert!(storage.is_shared());
412 assert_eq!(storage.shared_count(), Some(1));
413
414 let storage2 = storage.clone();
416 assert_eq!(storage.shared_count(), Some(2));
417 assert_eq!(storage2.shared_count(), Some(2));
418 }
419
420 #[test]
421 fn test_field_storage_owned_variant() {
422 let field = Field::new(DataType::Digit, "test", Value::from(42));
423 let storage = FieldStorage::from_owned(field);
424
425 assert_eq!(storage.as_field().get_name(), "test");
426 assert!(!storage.is_shared());
427 assert_eq!(storage.shared_count(), None);
428 }
429
430 #[test]
431 fn test_into_owned() {
432 let field1 = Field::new(DataType::Chars, "shared_field", Value::from("value"));
434 let storage1 = FieldStorage::from_shared(Arc::new(field1));
435 let owned1 = storage1.into_owned();
436 assert_eq!(owned1.get_name(), "shared_field");
437
438 let field2 = Field::new(DataType::Digit, "owned_field", Value::from(123));
440 let storage2 = FieldStorage::from_owned(field2);
441 let owned2 = storage2.into_owned();
442 assert_eq!(owned2.get_name(), "owned_field");
443 }
444
445 #[test]
446 fn test_from_shared() {
447 let field = Field::new(DataType::Chars, "name", Value::from("Alice"));
448 let storage = FieldStorage::from_shared(Arc::new(field));
449
450 assert!(storage.is_shared());
451 assert_eq!(storage.as_field().get_name(), "name");
452 }
453
454 #[test]
455 fn test_from_owned() {
456 let field = Field::new(DataType::Digit, "count", Value::from(10));
457 let storage = FieldStorage::from_owned(field);
458
459 assert!(!storage.is_shared());
460 assert_eq!(storage.as_field().get_name(), "count");
461 }
462
463 #[test]
464 fn test_display() {
465 let field = Field::new(DataType::Digit, "num", Value::from(42));
466 let storage = FieldStorage::from_owned(field);
467
468 let display = format!("{}", storage);
469 assert!(display.contains("42"));
470 }
471
472 #[test]
473 fn test_equality() {
474 let field1 = Field::new(DataType::Chars, "test", Value::from("value"));
475 let field2 = Field::new(DataType::Chars, "test", Value::from("value"));
476 let field3 = Field::new(DataType::Chars, "test", Value::from("different"));
477
478 let shared1 = FieldStorage::from_shared(Arc::new(field1.clone()));
479 let owned1 = FieldStorage::from_owned(field1);
480 let shared2 = FieldStorage::from_shared(Arc::new(field2));
481 let owned3 = FieldStorage::from_owned(field3);
482
483 assert_eq!(shared1, owned1);
485 assert_eq!(shared1, shared2);
486
487 assert_ne!(shared1, owned3);
489 }
490
491 #[test]
492 fn test_equality_with_cur_name() {
493 let field = Field::new(DataType::Chars, "test", Value::from("value"));
494
495 let mut storage1 = FieldStorage::from_owned(field.clone());
496 storage1.set_name("renamed");
497
498 let storage2 = FieldStorage::from_owned(field);
499
500 assert_ne!(storage1, storage2);
502 }
503
504 #[test]
505 fn test_serde_serialization() {
506 let field1 = Field::new(DataType::Chars, "f1", Value::from("shared"));
507 let field2 = Field::new(DataType::Digit, "f2", Value::from(99));
508
509 let shared = FieldStorage::from_shared(Arc::new(field1));
510 let owned = FieldStorage::from_owned(field2);
511
512 let json_shared = serde_json::to_string(&shared).unwrap();
514 let json_owned = serde_json::to_string(&owned).unwrap();
515
516 let deserialized_shared: FieldStorage = serde_json::from_str(&json_shared).unwrap();
518 let deserialized_owned: FieldStorage = serde_json::from_str(&json_owned).unwrap();
519
520 assert_eq!(deserialized_shared.as_field().get_name(), "f1");
522 assert_eq!(deserialized_owned.as_field().get_name(), "f2");
523
524 assert!(!deserialized_shared.is_shared());
526 assert!(!deserialized_owned.is_shared());
527 }
528
529 #[test]
530 fn test_serde_with_cur_name() {
531 let field = Field::new(DataType::Chars, "original", Value::from("value"));
532 let mut storage = FieldStorage::from_owned(field);
533 storage.set_name("renamed");
534
535 let json = serde_json::to_string(&storage).unwrap();
537 let deserialized: FieldStorage = serde_json::from_str(&json).unwrap();
538
539 assert_eq!(deserialized.get_name(), "renamed");
540 }
541
542 #[test]
543 fn test_clone_performance_difference() {
544 use crate::model::FValueStr;
546 let large_str = FValueStr::from("x".repeat(1000));
547 let field = Field::new(DataType::Chars, "large", Value::from(large_str));
548
549 let shared = FieldStorage::from_shared(Arc::new(field.clone()));
551 let _shared2 = shared.clone();
552 assert_eq!(shared.shared_count(), Some(2));
553
554 let owned = FieldStorage::from_owned(field);
556 let _owned2 = owned.clone();
557 assert!(owned.shared_count().is_none());
558 }
559
560 #[test]
561 fn test_from_arc_to_fieldstorage() {
562 let field = Field::new(DataType::Chars, "name", Value::from("Alice"));
563 let arc = Arc::new(field);
564 let storage: FieldStorage = arc.into();
565
566 assert!(storage.is_shared());
567 assert_eq!(storage.as_field().get_name(), "name");
568 }
569
570 #[test]
571 fn test_is_owned() {
572 let field = Field::new(DataType::Digit, "x", Value::from(1));
573 let owned = FieldStorage::from_owned(field.clone());
574 let shared = FieldStorage::from_shared(Arc::new(field));
575
576 assert!(owned.is_owned());
577 assert!(!shared.is_owned());
578 }
579
580 #[test]
581 fn test_as_field_mut_owned() {
582 let mut storage = FieldStorage::from_owned(Field::from_chars("name", "Alice"));
583 storage.as_field_mut().set_name("renamed");
584 assert_eq!(storage.as_field().get_name(), "renamed");
585 assert!(storage.is_owned());
586 }
587
588 #[test]
589 fn test_as_field_mut_shared() {
590 let field = Field::from_chars("name", "Alice");
591 let mut storage = FieldStorage::from_shared(Arc::new(field));
592 assert!(storage.is_shared());
593
594 storage.as_field_mut().set_name("renamed");
596 assert!(storage.is_owned());
597 assert_eq!(storage.as_field().get_name(), "renamed");
598 }
599
600 #[test]
601 fn test_as_field_mut_applies_cur_name() {
602 let field = Field::from_chars("original", "value");
603 let mut storage = FieldStorage::from_owned(field);
604 storage.set_name("override");
605
606 let field_mut = storage.as_field_mut();
608 assert_eq!(field_mut.get_name(), "override");
609
610 assert_eq!(storage.as_field().get_name(), "override");
612 }
613
614 #[test]
617 fn test_zero_copy_set_name() {
618 let field = Arc::new(Field::from_chars("original", "value"));
620 let original_count = Arc::strong_count(&field);
621
622 let mut storage = FieldStorage::from_shared(Arc::clone(&field));
624 assert_eq!(Arc::strong_count(&field), original_count + 1);
625
626 storage.set_name("renamed");
628
629 assert_eq!(Arc::strong_count(&field), original_count + 1);
631
632 assert_eq!(storage.get_name(), "renamed");
634
635 assert_eq!(field.get_name(), "original");
637
638 assert_eq!(storage.get_value().as_str().unwrap(), "value");
640 }
641
642 #[test]
643 fn test_name_priority() {
644 let field = Field::from_chars("field_name", "value");
645 let mut storage = FieldStorage::from_owned(field);
646
647 assert_eq!(storage.get_name(), "field_name");
649
650 storage.set_name("override_name");
652
653 assert_eq!(storage.get_name(), "override_name");
655
656 assert_eq!(storage.as_field().get_name(), "field_name");
658 }
659
660 #[test]
661 fn test_into_owned_applies_cur_name() {
662 let field = Arc::new(Field::from_chars("original", "value"));
663 let mut storage = FieldStorage::from_shared(field);
664
665 storage.set_name("renamed");
666
667 let owned = storage.into_owned();
668
669 assert_eq!(owned.get_name(), "renamed");
671 assert_eq!(owned.get_value().as_str().unwrap(), "value");
672 }
673
674 #[test]
675 fn test_shared_vs_owned() {
676 let arc_field = Arc::new(Field::from_chars("arc", "value1"));
677 let owned_field = Field::from_chars("owned", "value2");
678
679 let shared = FieldStorage::from_shared(arc_field);
680 let owned = FieldStorage::from_owned(owned_field);
681
682 assert!(shared.is_shared());
683 assert!(!shared.is_owned());
684
685 assert!(!owned.is_shared());
686 assert!(owned.is_owned());
687 }
688
689 #[test]
690 fn test_arc_strong_count() {
691 let field = Arc::new(Field::from_chars("test", "value"));
692 let initial_count = Arc::strong_count(&field);
693
694 let storage1 = FieldStorage::from_shared(Arc::clone(&field));
695 assert_eq!(storage1.shared_count(), Some(initial_count + 1));
696
697 let storage2 = FieldStorage::from_shared(Arc::clone(&field));
698 assert_eq!(storage2.shared_count(), Some(initial_count + 2));
699
700 let owned = FieldStorage::from_owned(Field::from_chars("test", "value"));
701 assert_eq!(owned.shared_count(), None);
702 }
703
704 #[test]
705 fn test_multi_stage_zero_copy() {
706 let field = Arc::new(Field::from_chars("HOST", "192.168.1.1"));
708 let initial_count = Arc::strong_count(&field);
709
710 let mut stage1 = FieldStorage::from_shared(Arc::clone(&field));
712 stage1.set_name("server_ip");
713
714 let mut stage2 = FieldStorage::from_shared(Arc::clone(&field));
716 stage2.set_name("host_address");
717
718 let mut stage3 = FieldStorage::from_shared(Arc::clone(&field));
720 stage3.set_name("ip_addr");
721
722 assert_eq!(stage1.shared_count(), Some(initial_count + 3));
724 assert_eq!(stage2.shared_count(), Some(initial_count + 3));
725 assert_eq!(stage3.shared_count(), Some(initial_count + 3));
726
727 assert_eq!(stage1.get_name(), "server_ip");
729 assert_eq!(stage2.get_name(), "host_address");
730 assert_eq!(stage3.get_name(), "ip_addr");
731
732 assert_eq!(stage1.get_value().as_str().unwrap(), "192.168.1.1");
734 assert_eq!(stage2.get_value().as_str().unwrap(), "192.168.1.1");
735 assert_eq!(stage3.get_value().as_str().unwrap(), "192.168.1.1");
736 }
737
738 #[test]
739 fn test_record_item_get_name_with_cur_name() {
740 let field = Field::from_chars("original", "value");
741 let mut storage = FieldStorage::from_owned(field);
742 storage.set_name("overridden");
743
744 let name: &str = RecordItem::get_name(&storage);
746 assert_eq!(name, "overridden");
747 }
748}