1use crate::value::Value;
2use derive_more::Display;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use uuid::Uuid;
6
7use crate::gen_bb_uuid;
8
9#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
58#[display("KV({:?})", fields)]
59pub struct KeyValue {
60 pub id: Uuid,
61 pub fields: HashMap<String, KeyValueField>,
62}
63
64impl Default for KeyValue {
65 fn default() -> Self {
66 Self::new()
67 }
68}
69
70impl KeyValue {
71 pub fn new() -> Self {
72 KeyValue::new_with_id(gen_bb_uuid())
73 }
74
75 pub fn new_with_id(id: Uuid) -> Self {
76 Self {
77 id,
78 fields: HashMap::new(),
79 }
80 }
81
82 pub fn set_field(&mut self, field: KeyValueField) {
83 self.fields.insert(field.name.clone(), field);
84 }
85
86 pub fn set_field_value(&mut self, key: &str, value: Value) {
87 let key_str = key.to_string();
88 if let Some(existing_field) = self.fields.get_mut(&key_str) {
89 existing_field.value = Some(Box::new(value));
91 } else {
92 let field = KeyValueField::new(key_str.clone(), value);
94 self.fields.insert(key_str, field);
95 }
96 }
97
98 pub fn get_fields(&self) -> &HashMap<String, KeyValueField> {
99 &self.fields
100 }
101
102 pub fn get_field_keys(&self) -> Vec<String> {
103 self.fields.keys().cloned().collect()
104 }
105
106 pub fn get_field(&self, key: &str) -> Option<&KeyValueField> {
107 self.fields.get(key)
108 }
109
110 pub fn as_value(self) -> Value {
111 Value::KeyValue(self)
112 }
113}
114
115#[derive(Debug, Clone, Display, Serialize, Deserialize, PartialEq)]
116#[display("{} ({}): {:?}", name, id, value)]
117pub struct KeyValueField {
118 pub id: Uuid,
119 pub name: String,
120 pub value: Option<Box<Value>>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
127pub struct KeyValueItems(pub Vec<KeyValueField>);
128
129impl std::ops::Deref for KeyValueItems {
130 type Target = [KeyValueField];
131 fn deref(&self) -> &Self::Target {
132 &self.0
133 }
134}
135
136impl IntoIterator for KeyValueItems {
137 type Item = KeyValueField;
138 type IntoIter = std::vec::IntoIter<KeyValueField>;
139 fn into_iter(self) -> Self::IntoIter {
140 self.0.into_iter()
141 }
142}
143
144impl From<Vec<KeyValueField>> for KeyValueItems {
145 fn from(v: Vec<KeyValueField>) -> Self {
146 let mut kvis = KeyValueItems::new();
148 for f in v.into_iter() {
149 kvis.set(f);
150 }
151 kvis
152 }
153}
154
155impl<'a> From<&'a [KeyValueField]> for KeyValueItems {
156 fn from(slice: &'a [KeyValueField]) -> Self {
157 let mut kvis = KeyValueItems::new();
158 for f in slice.iter().cloned() {
159 kvis.set(f);
160 }
161 kvis
162 }
163}
164
165impl From<KeyValueItems> for Vec<KeyValueField> {
166 fn from(kvs: KeyValueItems) -> Self {
167 kvs.0
168 }
169}
170
171impl KeyValueItems {
172 pub fn new() -> Self {
173 Self(Vec::new())
174 }
175 pub fn set(&mut self, field: KeyValueField) -> Option<KeyValueField> {
179 if let Some(idx) = self.0.iter().position(|f| f.name == field.name) {
180 let mut old = field; std::mem::swap(&mut self.0[idx], &mut old);
182 Some(old)
183 } else {
184 self.0.push(field);
185 None
186 }
187 }
188
189 pub fn is_empty(&self) -> bool {
190 self.0.is_empty()
191 }
192 pub fn len(&self) -> usize {
193 self.0.len()
194 }
195 pub fn into_inner(self) -> Vec<KeyValueField> {
196 self.0
197 }
198 pub fn iter(&self) -> std::slice::Iter<'_, KeyValueField> {
199 self.0.iter()
200 }
201 pub fn get(&self, name: &str) -> Option<&KeyValueField> {
202 self.0.iter().find(|f| f.name == name)
203 }
204
205 pub fn from_hash<K>(pairs: impl IntoIterator<Item = (K, KeyValueField)>) -> KeyValueItems
206 where
207 K: Into<String>,
208 {
209 use std::collections::HashMap; let mut map: HashMap<String, KeyValueField> = HashMap::new();
211 for (k, v) in pairs.into_iter() {
212 map.insert(k.into(), v); }
214 KeyValueItems(map.into_values().collect())
215 }
216}
217
218impl AsRef<[KeyValueField]> for KeyValueItems {
219 fn as_ref(&self) -> &[KeyValueField] {
220 &self.0
221 }
222}
223
224impl KeyValueField {
225 pub fn new<S: Into<String>>(name: S, value: Value) -> Self {
226 Self::new_with_option(name, Some(value))
227 }
228
229 pub fn new_with_option<S: Into<String>>(name: S, value: Option<Value>) -> Self {
230 Self::new_with_id_and_option(name, gen_bb_uuid(), value)
231 }
232
233 pub fn new_with_id<S: Into<String>>(name: S, id: Uuid, value: Value) -> Self {
234 Self {
235 name: name.into(),
236 id,
237 value: Some(Box::new(value)),
238 }
239 }
240
241 pub fn new_with_id_and_option<S: Into<String>>(name: S, id: Uuid, value: Option<Value>) -> Self {
242 Self {
243 name: name.into(),
244 id,
245 value: value.map(Box::new),
246 }
247 }
248
249 pub fn new_nested_kv<S: Into<String>, F: AsRef<[KeyValueField]>>(kv_name: S, fields: &F) -> Self {
250 Self::new_nested_kv_with_kv_id(kv_name, gen_bb_uuid(), fields)
251 }
252
253 pub fn new_nested_kv_with_kv_id<S: Into<String>, F: AsRef<[KeyValueField]>>(
254 kv_name: S,
255 kv_id: Uuid,
256 fields: &F,
257 ) -> Self {
258 Self::new_nested_kv_with_both_ids(kv_name, gen_bb_uuid(), kv_id, fields)
259 }
260
261 pub fn new_nested_kv_with_both_ids<S: Into<String>, F: AsRef<[KeyValueField]>>(
262 kv_name: S,
263 field_id: Uuid,
264 kv_id: Uuid,
265 fields: &F,
266 ) -> Self {
267 let kv: KeyValue = (kv_id, fields.as_ref()).into();
269 KeyValueField::new_with_id(kv_name, field_id, kv.into())
270 }
271}
272
273impl From<KeyValue> for Value {
278 fn from(kv: KeyValue) -> Self {
279 kv.as_value()
280 }
281}
282
283impl From<Vec<KeyValueField>> for KeyValue {
284 fn from(fields: Vec<KeyValueField>) -> Self {
285 let id = gen_bb_uuid();
286 (id, fields).into()
287 }
288}
289
290impl From<&[KeyValueField]> for KeyValue {
291 fn from(fields: &[KeyValueField]) -> Self {
292 let id = gen_bb_uuid();
293 (id, fields).into()
294 }
295}
296
297impl<const N: usize> From<[KeyValueField; N]> for KeyValue {
298 fn from(arr: [KeyValueField; N]) -> Self {
299 let id = gen_bb_uuid();
300 (id, arr.into_iter().collect::<Vec<_>>()).into()
301 }
302}
303
304impl From<KeyValueItems> for KeyValue {
305 fn from(set: KeyValueItems) -> Self {
306 let id = gen_bb_uuid();
307 (id, set.0).into()
308 }
309}
310
311impl From<(Uuid, Vec<KeyValueField>)> for KeyValue {
312 fn from((id, fields): (Uuid, Vec<KeyValueField>)) -> Self {
313 let mut map = HashMap::with_capacity(fields.len());
314 for f in fields.into_iter() {
315 map.insert(f.name.clone(), f); }
317 KeyValue { id, fields: map }
318 }
319}
320
321impl From<(Uuid, &[KeyValueField])> for KeyValue {
322 fn from((id, fields): (Uuid, &[KeyValueField])) -> Self {
323 let mut map = HashMap::with_capacity(fields.len());
324 for f in fields.iter().cloned() {
325 map.insert(f.name.clone(), f);
326 }
327 KeyValue { id, fields: map }
328 }
329}
330
331impl From<(Uuid, KeyValueItems)> for KeyValue {
332 fn from((id, set): (Uuid, KeyValueItems)) -> Self {
333 (id, set.0).into()
334 }
335}
336
337impl From<(Uuid, HashMap<String, KeyValueField>)> for KeyValue {
338 fn from((id, map): (Uuid, HashMap<String, KeyValueField>)) -> Self {
339 KeyValue { id, fields: map }
340 }
341}
342
343impl<const N: usize> From<(Uuid, [KeyValueField; N])> for KeyValue {
344 fn from((id, arr): (Uuid, [KeyValueField; N])) -> Self {
345 (id, arr.into_iter().collect::<Vec<_>>()).into()
346 }
347}
348
349impl From<HashMap<String, KeyValueField>> for KeyValue {
350 fn from(map: HashMap<String, KeyValueField>) -> Self {
351 let id = gen_bb_uuid();
352 (id, map).into()
353 }
354}
355
356#[cfg(test)]
359mod tests {
360 use super::*;
361 use crate::value::Value;
362
363 #[test]
364 fn test_keyvalue_new() {
365 let uuid = gen_bb_uuid();
366 let kv = KeyValue::new_with_id(uuid);
367 assert_eq!(kv.id, uuid);
368 assert!(kv.fields.is_empty());
369 }
370
371 #[test]
372 fn test_keyvalue_set_field_value_new() {
373 let mut kv = KeyValue::new();
374 let health_value = Value::I32(100);
375
376 kv.set_field_value("health", health_value.clone());
379
380 assert_eq!(kv.fields.len(), 1);
381 assert!(kv.fields.contains_key("health"));
382
383 let field = kv.get_field("health").unwrap();
384 match field.value.as_deref() {
385 Some(Value::I32(value)) => assert_eq!(*value, 100),
386 _ => panic!("Expected I32 value"),
387 }
388 }
389
390 #[test]
391 fn test_keyvalue_set_field_value_update_existing() {
392 let mut kv = KeyValue::new();
393
394 kv.set_field_value("health", Value::I32(100));
396
397 kv.set_field_value("health", Value::I32(50));
399
400 assert_eq!(kv.fields.len(), 1);
401 let field = kv.get_field("health").unwrap();
402 match field.value.as_deref() {
403 Some(Value::I32(value)) => assert_eq!(*value, 50),
404 _ => panic!("Expected I32 value"),
405 }
406 }
407
408 #[test]
409 fn test_keyvalue_set_field() {
410 let mut kv = KeyValue::new();
411 let field = KeyValueField::new("health_id", Value::I32(100));
412
413 kv.set_field(field.clone());
416
417 assert_eq!(kv.fields.len(), 1);
418 assert!(kv.fields.contains_key("health_id"));
419 assert_eq!(kv.get_field("health_id"), Some(&field));
420 }
421
422 #[test]
423 fn test_keyvalue_get_field_keys() {
424 let mut kv = KeyValue::new();
425 kv.set_field_value("health", Value::I32(100));
426 kv.set_field_value("mana", Value::I32(50));
427 kv.set_field_value("level", Value::I32(5));
428
429 let keys = kv.get_field_keys();
430 assert_eq!(keys.len(), 3);
431 assert!(keys.contains(&"health".to_string()));
432 assert!(keys.contains(&"mana".to_string()));
433 assert!(keys.contains(&"level".to_string()));
434 }
435
436 #[test]
437 fn test_keyvalue_get_field_nonexistent() {
438 let kv = KeyValue::new();
439 assert_eq!(kv.get_field("nonexistent"), None);
440 }
441
442 #[test]
443 fn test_keyvalue_field_new() {
444 let field = KeyValueField::new("test_id", Value::String("test_value".to_string()));
445 assert_eq!(field.name, "test_id");
446 match field.value.as_deref() {
447 Some(Value::String(value)) => assert_eq!(value, "test_value"),
448 _ => panic!("Expected String value"),
449 }
450 }
451
452 #[test]
453 fn test_keyvalue_field_simple_nested_keyvalue() {
454 let id = gen_bb_uuid();
455 let inner_kv = KeyValue::new_with_id(id);
456 let field = KeyValueField::new("test_id", inner_kv.as_value());
457
458 assert_eq!(field.name, "test_id");
459 match field.value.as_deref() {
460 Some(Value::KeyValue(kv)) => assert_eq!(kv.id, id),
461 _ => panic!("Expected KeyValue variant"),
462 }
463 }
464
465 #[test]
466 fn test_simple_make_kv_from_fields() {
467 let fields = vec![
468 KeyValueField::new("health", Value::I32(100)),
469 KeyValueField::new("mana", Value::I32(50)),
470 ];
471 let id = gen_bb_uuid();
472 let kv: KeyValue = KeyValue::from((id, fields));
473 assert_eq!(kv.id, id);
474 assert_eq!(kv.fields.len(), 2);
475 assert!(kv.fields.contains_key("health"));
476 assert!(kv.fields.contains_key("mana"));
477 match kv.fields.get("health").unwrap().value.as_deref() {
478 Some(Value::I32(value)) => assert_eq!(*value, 100),
479 _ => panic!("Expected I32 value"),
480 }
481
482 match kv.fields.get("mana").unwrap().value.as_deref() {
483 Some(Value::I32(value)) => assert_eq!(*value, 50),
484 _ => panic!("Expected I32 value"),
485 }
486 }
487
488 #[test]
489 fn test_keyvalue_nested_structure_without_ids() {
490 let player: KeyValue = {
492 let fields = [
493 KeyValueField::new("health", Value::I32(100)),
494 KeyValueField::new_nested_kv(
495 "stats",
496 &KeyValueItems::from(vec![
497 KeyValueField::new("strength", Value::I32(50)),
498 KeyValueField::new("agility", Value::I32(75)),
499 ]),
500 ),
501 KeyValueField::new_nested_kv(
502 "position",
503 &KeyValueItems::from(vec![
504 KeyValueField::new("x", Value::F32(10.0)),
505 KeyValueField::new("y", Value::F32(20.0)),
506 ]),
507 ),
508 ];
509 KeyValue::from(fields)
510 };
511
512 assert_eq!(player.fields.len(), 3);
514
515 let health_field = player.get_field("health").expect("health field");
517 match health_field.value.as_deref() {
518 Some(Value::I32(100)) => {}
519 other => panic!("Expected I32(100) got {:?}", other),
520 }
521
522 let stats_field = player.get_field("stats").expect("stats field");
524 match stats_field.value.as_deref() {
525 Some(Value::KeyValue(stats_kv)) => {
526 assert_eq!(stats_kv.fields.len(), 2);
527 match stats_kv.get_field("strength").unwrap().value.as_deref() {
529 Some(Value::I32(50)) => {}
530 other => panic!("Expected strength=50 got {:?}", other),
531 }
532 match stats_kv.get_field("agility").unwrap().value.as_deref() {
534 Some(Value::I32(75)) => {}
535 other => panic!("Expected agility=75 got {:?}", other),
536 }
537 }
538 other => panic!("Expected KeyValue for stats got {:?}", other),
539 }
540
541 let position_field = player.get_field("position").expect("position field");
543 match position_field.value.as_deref() {
544 Some(Value::KeyValue(pos_kv)) => {
545 assert_eq!(pos_kv.fields.len(), 2);
546 match pos_kv.get_field("x").unwrap().value.as_deref() {
547 Some(Value::F32(f)) if (*f - 10.0).abs() < f32::EPSILON => {}
548 other => panic!("Expected x=10.0 got {:?}", other),
549 }
550 match pos_kv.get_field("y").unwrap().value.as_deref() {
551 Some(Value::F32(f)) if (*f - 20.0).abs() < f32::EPSILON => {}
552 other => panic!("Expected y=20.0 got {:?}", other),
553 }
554 }
555 other => panic!("Expected KeyValue for position got {:?}", other),
556 }
557 }
558
559 #[test]
560 fn test_make_kv_from_fields_duplicate_names_last_wins() {
561 let fields = vec![
562 KeyValueField::new("health", Value::I32(100)),
563 KeyValueField::new("health", Value::I32(150)), ];
565 let kv: KeyValue = KeyValue::from(fields);
566 assert_eq!(kv.fields.len(), 1); let health_field = kv.get_field("health").unwrap();
568 match health_field.value.as_deref() {
569 Some(Value::I32(150)) => {}
570 other => panic!("Expected 150 got {:?}", other),
571 }
572 }
573
574 #[test]
575 fn test_keyvalue_nested_structure_with_ids() {
576 let outer_id = gen_bb_uuid();
577 let health_id = gen_bb_uuid();
578 let inner_field_id = gen_bb_uuid();
579 let inner_kv_id = gen_bb_uuid();
580 let strength_id = gen_bb_uuid();
581 let agility_id = gen_bb_uuid();
582
583 let stats_set = KeyValueItems::from(vec![
584 KeyValueField::new_with_id("strength", strength_id, Value::I32(50)),
585 KeyValueField::new_with_id("agility", agility_id, Value::I32(75)),
586 ]);
587
588 let player = KeyValue::from((
589 outer_id,
590 vec![
591 KeyValueField::new_with_id("health", health_id, Value::I32(100)),
592 KeyValueField::new_nested_kv_with_both_ids(
593 "stats",
594 inner_field_id,
595 inner_kv_id,
596 &stats_set,
597 ),
598 ],
599 ));
600
601 assert_eq!(player.id, outer_id);
602 assert_eq!(player.fields.len(), 2);
603 let health_field = player.get_field("health").unwrap();
604 assert_eq!(health_field.id, health_id);
605 match health_field.value.as_ref().unwrap().as_ref() {
606 Value::I32(100) => {}
607 _ => panic!("Expected I32(100)"),
608 }
609 let stats_field = player.get_field("stats").unwrap();
610 assert_eq!(stats_field.id, inner_field_id);
611 match stats_field.value.as_deref() {
612 Some(Value::KeyValue(stats_kv)) => {
613 assert_eq!(stats_kv.id, inner_kv_id);
614 assert_eq!(stats_kv.fields.len(), 2);
615 let strength_field = stats_kv.get_field("strength").unwrap();
616 assert_eq!(strength_field.id, strength_id);
617 match strength_field.value.as_deref() {
618 Some(Value::I32(50)) => {}
619 other => panic!("Expected I32(50) got {:?}", other),
620 }
621 let agility_field = stats_kv.get_field("agility").unwrap();
622 assert_eq!(agility_field.id, agility_id);
623 match agility_field.value.as_deref() {
624 Some(Value::I32(75)) => {}
625 other => panic!("Expected I32(75) got {:?}", other),
626 }
627 }
628 other => panic!("Expected KeyValue for stats got {:?}", other),
629 }
630 }
631
632 #[test]
633 fn test_keyvalue_display() {
634 let mut kv = KeyValue::new();
635 kv.set_field_value("key1", Value::String("value1".to_string()));
636 kv.set_field_value("key2", Value::I32(42));
637
638 let display_str = format!("{}", kv);
639 assert!(display_str.contains("KV("));
640 assert!(display_str.contains("key1"));
641 assert!(display_str.contains("key2"));
642 }
643
644 #[test]
645 fn test_keyvalue_field_display() {
646 let field = KeyValueField::new("test_field", Value::String("test_value".to_string()));
647 let display_str = format!("{}", field);
648 assert!(display_str.contains("test_field"));
649 assert!(display_str.contains("test_value"));
650 }
651
652 #[test]
653 fn test_keyvalue_clone_and_equality() {
654 let mut original = KeyValue::new();
655 original.set_field_value("health", Value::I32(100));
656 original.set_field_value("level", Value::I32(5));
657
658 let cloned = original.clone();
659
660 assert_eq!(original, cloned);
661 assert_eq!(original.id, cloned.id);
662 assert_eq!(original.fields.len(), cloned.fields.len());
663
664 let mut modified = cloned;
666 modified.set_field_value("health", Value::I32(200));
667
668 assert_ne!(original, modified);
669 }
670
671 #[test]
672 fn test_keyvalue_serialization() {
673 use json5;
674
675 let id = gen_bb_uuid();
676 let mut kv = KeyValue::new_with_id(id);
677 kv.set_field_value("health", Value::I32(100));
678 kv.set_field_value("name", Value::String("Hero".to_string()));
679
680 let json = json5::to_string(&kv).expect("Serialization should succeed");
682 assert!(json.contains(&id.to_string()));
683 assert!(json.contains("health"));
684 assert!(json.contains("name"));
685
686 let deserialized: KeyValue = json5::from_str(&json).expect("Deserialization should succeed");
688 assert_eq!(kv, deserialized);
689 }
690
691 #[test]
692 fn test_keyvalue_empty_operations() {
693 let kv = KeyValue::new();
694
695 assert!(kv.get_field_keys().is_empty());
696 assert!(kv.get_fields().is_empty());
697 assert_eq!(kv.get_field("any_key"), None);
698 }
699
700 #[test]
701 fn test_valueblock_with_different_value_types() {
702 let test_cases = vec![
704 ("bool", Value::Boolean(true)),
705 ("u8", Value::U8(255)),
706 ("u16", Value::U16(65535)),
707 ("u32", Value::U32(4294967295)),
708 ("u64", Value::U64(18446744073709551615)),
709 ("i8", Value::I8(-128)),
710 ("i16", Value::I16(-32768)),
711 ("i32", Value::I32(-2147483648)),
712 ("i64", Value::I64(-9223372036854775808)),
713 ("f32", Value::F32(std::f32::consts::PI)),
714 ("f64", Value::F64(std::f64::consts::E)),
715 ("string", Value::String("test string".to_string())),
716 ("unit", Value::Unit),
717 ];
718
719 for (name, value) in test_cases {
720 let mut kv = KeyValue::new();
721 kv.set_field_value(name, value.clone());
722
723 let retrieved_field = kv.get_field(name).unwrap();
724
725 assert_eq!(
726 retrieved_field.value.as_deref(),
727 Some(&value),
728 "Failed for type: {}",
729 name
730 );
731 }
732 }
733
734 #[test]
735 fn test_keyvalue_field_map_from_hash() {
736 use std::collections::HashMap;
737 let mut map: HashMap<String, KeyValueField> = HashMap::new();
739 map.insert("a".into(), KeyValueField::new("a", Value::I32(1)));
740 map.insert("b".into(), KeyValueField::new("b", Value::I32(2)));
741 map.insert("a".into(), KeyValueField::new("a", Value::I32(10))); let auto_kv: KeyValue = map.clone().into();
745 assert_eq!(auto_kv.fields.len(), 2);
746 match auto_kv.get_field("a").unwrap().value.as_deref() {
747 Some(Value::I32(10)) => {}
748 other => panic!("expected 10 got {:?}", other),
749 }
750 match auto_kv.get_field("b").unwrap().value.as_deref() {
751 Some(Value::I32(2)) => {}
752 other => panic!("expected 2 got {:?}", other),
753 }
754
755 let explicit_id = gen_bb_uuid();
757 let kv_with_id: KeyValue = (explicit_id, map).into();
758 assert_eq!(kv_with_id.id, explicit_id);
759 assert_eq!(kv_with_id.fields.len(), 2);
760 assert!(kv_with_id.get_field("a").is_some());
761 assert!(kv_with_id.get_field("b").is_some());
762 }
763
764 #[test]
766 fn test_keyvalueset_from_vec_deduplicates_last_wins() {
767 let set = KeyValueItems::from(vec![
768 KeyValueField::new("health", Value::I32(100)),
769 KeyValueField::new("mana", Value::I32(50)),
770 KeyValueField::new("health", Value::I32(150)), ]);
772 assert_eq!(set.len(), 2);
773 let health = set.get("health").unwrap();
774 match health.value.as_deref() {
775 Some(Value::I32(150)) => {}
776 other => panic!("expected 150 got {:?}", other),
777 }
778 }
779
780 #[test]
781 fn test_keyvalueitems_set_replaces() {
782 let mut kvis = KeyValueItems::new();
783 let inserted = kvis.set(KeyValueField::new("speed", Value::I32(10)));
784 assert!(inserted.is_none());
785 let inserted2 = kvis.set(KeyValueField::new("speed", Value::I32(20))); assert!(inserted2.is_some());
787 assert_eq!(kvis.len(), 1);
788 match kvis.get("speed").unwrap().value.as_deref() {
789 Some(Value::I32(20)) => {}
790 other => panic!("expected 20 got {:?}", other),
791 }
792 }
793
794 #[test]
795 fn test_keyvalueitems_set_returns_old() {
796 let mut kvis = KeyValueItems::new();
797 assert!(kvis.set(KeyValueField::new("x", Value::I32(1))).is_none());
798 let old = kvis
799 .set(KeyValueField::new("x", Value::I32(2)))
800 .expect("old value");
801 match old.value.as_deref() {
802 Some(Value::I32(1)) => {}
803 other => panic!("expected old=1 got {:?}", other),
804 }
805 match kvis.get("x").unwrap().value.as_deref() {
806 Some(Value::I32(2)) => {}
807 other => panic!("expected new=2 got {:?}", other),
808 }
809 }
810}