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