1use crate::{
4 Attributes,
5 AttributeSet,
6 ItemAttribute,
7 StrangePart,
8 TryFromIntAttributeValue,
9};
10use crate::error::InsertError;
11use crate::serialize;
12use std::collections::HashSet;
13use std::fmt;
14use std::hash::{Hash, Hasher};
15use std::ops::{BitAnd, Sub};
16use serde::{Deserialize, Deserializer, Serialize, Serializer};
17use serde::de::{self, SeqAccess, Visitor};
18
19const STRANGE_PART_COUNT: usize = 3;
20
21#[derive(Default, Clone, Copy, Eq, PartialOrd, Ord)]
64pub struct StrangePartSet {
65 inner: [Option<StrangePart>; STRANGE_PART_COUNT],
66}
67
68impl StrangePartSet {
69 pub fn new() -> Self {
78 Self::default()
79 }
80
81 pub fn single(strange_part: StrangePart) -> Self {
94 Self::from([
95 Some(strange_part),
96 None,
97 None,
98 ])
99 }
100
101 pub fn double(
117 strange_part1: StrangePart,
118 strange_part2: StrangePart,
119 ) -> Self {
120 Self::from([
121 Some(strange_part1),
122 Some(strange_part2),
123 None,
124 ])
125 }
126
127 pub fn triple(
144 strange_part1: StrangePart,
145 strange_part2: StrangePart,
146 strange_part3: StrangePart,
147 ) -> Self {
148 Self::from([
149 Some(strange_part1),
150 Some(strange_part2),
151 Some(strange_part3),
152 ])
153 }
154}
155
156impl AttributeSet for StrangePartSet {
157 const MAX_COUNT: usize = STRANGE_PART_COUNT;
159 const NONE: Self = Self {
161 inner: [None, None, None],
162 };
163 type Item = StrangePart;
165
166 fn clear(&mut self) {
182 self.inner = [None, None, None];
183 }
184
185 fn insert(&mut self, strange_part: StrangePart) -> bool {
211 self.try_insert(strange_part).is_ok()
212 }
213
214 fn try_insert(&mut self, strange_part: StrangePart) -> Result<(), InsertError> {
215 if self.contains(&strange_part) {
216 return Err(InsertError::Duplicate);
217 }
218
219 if let Some(slot) = self.inner.iter_mut().find(|slot| slot.is_none()) {
220 *slot = Some(strange_part);
221 return Ok(());
222 }
223
224 Err(InsertError::Full)
226 }
227
228 fn insert_or_replace_last(&mut self, strange_part: StrangePart) -> bool {
229 if self.contains(&strange_part) {
230 return false;
231 }
232
233 if let Some(slot) = self.inner.iter_mut().find(|slot| slot.is_none()) {
234 *slot = Some(strange_part);
235 return true;
236 }
237
238 self.inner[Self::MAX_COUNT - 1] = Some(strange_part);
240 true
241 }
242
243 fn remove(&mut self, strange_part: &StrangePart) -> bool {
255 for s in self.inner.iter_mut() {
256 if *s == Some(*strange_part) {
257 *s = None;
258 return true;
259 }
260 }
261
262 false
263 }
264
265 fn take(&mut self, strange_part: &StrangePart) -> Option<StrangePart> {
267 for s in self.inner.iter_mut() {
268 if *s == Some(*strange_part) {
269 *s = None;
270 return Some(*strange_part);
271 }
272 }
273
274 None
275 }
276
277 fn replace(&mut self, strange_part: &StrangePart, new_strange_part: StrangePart) -> bool {
280 if !self.contains(strange_part) {
281 return false;
282 }
283
284 for s in self.inner.iter_mut() {
285 if *s == Some(*strange_part) {
286 *s = Some(new_strange_part);
287 return true;
288 }
289 }
290
291 false
292 }
293
294 fn iter_attributes(&self) -> impl Iterator<Item = ItemAttribute> {
297 self
298 .into_iter()
299 .zip(StrangePart::DEFINDEX.iter())
300 .map(|(part, defindex)| ItemAttribute {
301 defindex: *defindex,
302 value: part.attribute_value(),
303 float_value: part.attribute_float_value(),
304 })
305 }
306
307 fn as_slice(&self) -> &[Option<StrangePart>] {
309 &self.inner
310 }
311
312 fn as_mut_slice(&mut self) -> &mut [Option<StrangePart>] {
314 &mut self.inner
315 }
316}
317
318impl Sub for StrangePartSet {
321 type Output = Self;
322
323 fn sub(self, other: Self) -> Self::Output {
324 self.difference(&other)
325 }
326}
327
328impl Sub for &StrangePartSet {
329 type Output = StrangePartSet;
330
331 fn sub(self, other: &StrangePartSet) -> Self::Output {
332 self.difference(other)
333 }
334}
335
336impl BitAnd for StrangePartSet {
337 type Output = Self;
338
339 fn bitand(self, other: Self) -> Self::Output {
340 self.intersection(&other)
341 }
342}
343
344impl BitAnd for &StrangePartSet {
345 type Output = StrangePartSet;
346
347 fn bitand(self, other: &StrangePartSet) -> Self::Output {
348 self.intersection(other)
349 }
350}
351
352impl PartialEq<Self> for StrangePartSet {
353 fn eq(&self, other: &Self) -> bool {
354 let mut a = self.inner;
355 let mut b = other.inner;
356
357 a.sort_unstable();
358 b.sort_unstable();
359
360 a == b
361 }
362}
363
364impl Hash for StrangePartSet {
365 fn hash<H: Hasher>(&self, state: &mut H) {
366 let mut values = self.inner;
367
368 values.sort_unstable();
369
370 for value in values {
371 value.hash(state);
372 }
373 }
374}
375
376impl From<[Option<StrangePart>; STRANGE_PART_COUNT]> for StrangePartSet {
377 fn from(inner: [Option<StrangePart>; STRANGE_PART_COUNT]) -> Self {
378 let mut inner = inner;
379
380 for i in 0..STRANGE_PART_COUNT {
382 if let Some(val_i) = inner[i] {
383 for j in (i + 1)..STRANGE_PART_COUNT {
385 if inner[j] == Some(val_i) {
386 inner[i] = None;
388 break;
389 }
390 }
391 }
392 }
393
394 Self {
395 inner,
396 }
397 }
398}
399
400impl From<StrangePartSet> for Vec<StrangePart>{
401 fn from(spell_set: StrangePartSet) -> Self {
402 spell_set.into_iter().collect()
403 }
404}
405
406impl From<&StrangePartSet> for Vec<StrangePart> {
407 fn from(spell_set: &StrangePartSet) -> Self {
408 (*spell_set).into()
409 }
410}
411
412impl FromIterator<StrangePart> for StrangePartSet {
413 fn from_iter<I: IntoIterator<Item = StrangePart>>(iter: I) -> Self {
414 let mut strange_parts = Self::new();
415
416 for strange_part in iter {
417 strange_parts.insert(strange_part);
418 }
419
420 strange_parts
421 }
422}
423
424impl<'a> FromIterator<&'a StrangePart> for StrangePartSet {
425 fn from_iter<I: IntoIterator<Item = &'a StrangePart>>(iter: I) -> Self {
426 let mut strange_part_set = Self::new();
427
428 for strange_part in iter {
429 strange_part_set.insert(*strange_part);
430 }
431
432 strange_part_set
433 }
434}
435
436impl FromIterator<Option<StrangePart>> for StrangePartSet {
437 fn from_iter<I: IntoIterator<Item = Option<StrangePart>>>(iter: I) -> Self {
438 let mut set = Self::new();
439
440 for val in iter.into_iter().flatten() {
441 set.insert(val);
442 }
443
444 set
445 }
446}
447
448impl<'a> FromIterator<Option<&'a StrangePart>> for StrangePartSet {
449 fn from_iter<I: IntoIterator<Item = Option<&'a StrangePart>>>(iter: I) -> Self {
450 let mut set = Self::new();
451
452 for val in iter.into_iter().flatten() {
453 set.insert(*val);
454 }
455
456 set
457 }
458}
459
460impl IntoIterator for StrangePartSet {
461 type Item = StrangePart;
462 type IntoIter = StrangePartSetIterator;
463
464 fn into_iter(self) -> Self::IntoIter {
465 StrangePartSetIterator {
466 inner: self.inner.into_iter(),
467 }
468 }
469}
470
471impl IntoIterator for &StrangePartSet {
472 type Item = StrangePart;
473 type IntoIter = StrangePartSetIterator;
474
475 fn into_iter(self) -> Self::IntoIter {
476 (*self).into_iter()
477 }
478}
479
480#[derive(Debug, Clone)]
482pub struct StrangePartSetIterator {
483 inner: std::array::IntoIter<Option<StrangePart>, STRANGE_PART_COUNT>,
484}
485
486impl Iterator for StrangePartSetIterator {
487 type Item = StrangePart;
488
489 fn next(&mut self) -> Option<Self::Item> {
490 let iter = self.inner.by_ref();
491
492 for opt in iter {
493 if opt.is_some() {
494 return opt;
495 }
496 }
497
498 None
499 }
500}
501
502impl fmt::Display for StrangePartSet {
503 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
504 let mut iter = self.into_iter();
505
506 if let Some(first) = iter.next() {
507 write!(f, "{first}")?;
508
509 for s in iter {
510 write!(f, ", {s}")?;
511 }
512 }
513
514 Ok(())
515 }
516}
517
518impl fmt::Debug for StrangePartSet {
519 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
520 f.write_str("{")?;
521 let mut first = true;
522 for part in self {
523 if !first {
524 f.write_str(", ")?;
525 }
526 write!(f, "{:?}", part as u32)?;
527 first = false;
528 }
529 f.write_str("}")
530 }
531}
532
533impl Serialize for StrangePartSet {
534 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
535 where
536 S: Serializer,
537 {
538 serialize::serialize_attribute_set(self, serializer)
539 }
540}
541
542impl<'de> Deserialize<'de> for StrangePartSet {
543 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
544 where
545 D: Deserializer<'de>,
546 {
547 struct StrangePartSetVisitor;
548
549 impl<'de> Visitor<'de> for StrangePartSetVisitor {
550 type Value = StrangePartSet;
551
552 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
553 formatter.write_str("an array of maps with defindex, float_value")
554 }
555
556 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
557 where
558 A: SeqAccess<'de>,
559 {
560 let mut set = Self::Value::new();
561 let mut defindex_map = HashSet::new();
562
563 while let Some(map) = seq.next_element::<ItemAttribute>()? {
564 if !<Self::Value as AttributeSet>::Item::DEFINDEX.contains(&map.defindex) {
565 continue;
567 }
568
569 if defindex_map.contains(&map.defindex) {
570 continue;
572 }
573
574 defindex_map.insert(map.defindex);
575
576 let float_value = map.float_value
577 .ok_or_else(|| de::Error::missing_field(
578 "float_value"
579 ))?;
580 let part = <Self::Value as AttributeSet>::Item::try_from_attribute_float_value(
581 float_value
582 )
583 .ok_or_else(|| de::Error::custom(
584 "cannot convert from float_value"
585 ))?;
586
587 set.insert(part);
588 }
589
590 Ok(set)
591 }
592 }
593
594 deserializer.deserialize_seq(StrangePartSetVisitor)
595 }
596}
597
598#[cfg(test)]
599mod tests {
600 use super::*;
601 use crate::traits::Attributes;
602
603 #[test]
604 fn serializes() {
605 let strange_parts = StrangePartSet::from([
606 Some(StrangePart::TauntKills),
607 None,
608 None,
609 ]);
610 let json = serde_json::to_string(&strange_parts).unwrap();
611 let expected = r#"[{"defindex":380,"value":1117388800,"float_value":77}]"#;
612
613 assert_eq!(json, expected);
614 }
615
616 #[test]
617 fn deserializes() {
618 let raw = r#"[{"defindex":380,"float_value":77},{"defindex":382,"float_value":34},{"defindex":384,"float_value":33}]"#;
620 let strange_parts: StrangePartSet = serde_json::from_str(raw).unwrap();
621 let expected = StrangePartSet::from([
622 Some(StrangePart::TauntKills),
623 Some(StrangePart::KillsWhileExplosiveJumping),
624 Some(StrangePart::CriticalKills),
625 ]);
626
627 assert_eq!(strange_parts, expected);
628 }
629
630 #[test]
631 fn deserializes_backpack() {
632 let raw = r#"[
635 {
636 "defindex": 189,
637 "value": 1093664768,
638 "float_value": 11
639 },
640 {
641 "defindex": 214,
642 "value": 1847,
643 "float_value": 2.58819826360793713e-42
644 },
645 {
646 "defindex": 379,
647 "value": 1085,
648 "float_value": 1.52040883379242652e-42
649 },
650 {
651 "defindex": 380,
652 "value": 1101004800,
653 "float_value": 20
654 },
655 {
656 "defindex": 381,
657 "value": 91,
658 "float_value": 1.27518160253558353e-43
659 },
660 {
661 "defindex": 382,
662 "value": 1106771968,
663 "float_value": 31
664 },
665 {
666 "defindex": 383,
667 "value": 457,
668 "float_value": 6.40393398196441401e-43
669 },
670 {
671 "defindex": 384,
672 "value": 1107296256,
673 "float_value": 32
674 },
675 {
676 "defindex": 719,
677 "value": "models/weapons/c_models/stattrack.mdl"
678 },
679 {
680 "defindex": 731,
681 "value": 1065353216,
682 "float_value": 1
683 },
684 {
685 "defindex": 841,
686 "value": 0,
687 "float_value": 0
688 },
689 {
690 "defindex": 843,
691 "value": 1091043328,
692 "float_value": 8.5
693 },
694 {
695 "defindex": 865,
696 "value": 1112014848,
697 "float_value": 50
698 },
699 {
700 "defindex": 844,
701 "value": 1159274496,
702 "float_value": 2450
703 },
704 {
705 "defindex": 839,
706 "value": 1077097267,
707 "float_value": 2.79999995231628418
708 },
709 {
710 "defindex": 862,
711 "value": 1058642330,
712 "float_value": 0.60000002384185791
713 },
714 {
715 "defindex": 863,
716 "value": 1036831949,
717 "float_value": 0.100000001490116119
718 },
719 {
720 "defindex": 783,
721 "value": 1101004800,
722 "float_value": 20
723 },
724 {
725 "defindex": 724,
726 "value": 1065353216,
727 "float_value": 1
728 },
729 {
730 "defindex": 796,
731 "value": "10 0 -10"
732 }
733 ]"#;
734 let strange_parts = serde_json::from_str::<StrangePartSet>(raw).unwrap();
735
736 assert_eq!(
737 strange_parts.to_string(),
738 "Projectiles Reflected, Posthumous Kills, Teammates Extinguished"
739 );
740 }
741
742 #[test]
743 fn iterates_strange_parts() {
744 let strange_parts = StrangePartSet::from([
745 Some(StrangePart::TauntKills),
746 Some(StrangePart::KillsWhileExplosiveJumping),
747 Some(StrangePart::CriticalKills),
748 ]);
749 let mut iter = strange_parts.into_iter();
750
751 assert_eq!(iter.next(), Some(StrangePart::TauntKills));
752 assert_eq!(iter.next(), Some(StrangePart::KillsWhileExplosiveJumping));
753 assert_eq!(iter.next(), Some(StrangePart::CriticalKills));
754 assert_eq!(iter.next(), None);
755
756 let mut count = 0;
757
758 for _strange_part in &strange_parts {
759 count += 1;
760 }
761
762 assert_eq!(count, 3);
763 }
764
765 #[test]
766 fn mutates_strange_parts() {
767 let mut strange_parts = StrangePartSet::from([
768 Some(StrangePart::TauntKills),
769 Some(StrangePart::KillsWhileExplosiveJumping),
770 Some(StrangePart::CriticalKills),
771 ]);
772
773 assert_eq!(strange_parts.len(), 3);
774 assert!(strange_parts.contains(&StrangePart::CriticalKills));
775
776 strange_parts.remove(&StrangePart::CriticalKills);
777
778 assert!(!strange_parts.contains(&StrangePart::CriticalKills));
779 assert_eq!(strange_parts.len(), 2);
780
781 strange_parts.insert(StrangePart::DamageDealt);
782
783 assert!(strange_parts.contains(&StrangePart::DamageDealt));
784 assert_eq!(strange_parts.len(), 3);
785 }
786
787 #[test]
788 fn strange_parts_no_duplicates() {
789 assert_eq!(StrangePartSet::from([
790 Some(StrangePart::CriticalKills),
791 Some(StrangePart::CriticalKills),
792 Some(StrangePart::CriticalKills),
793 ]), StrangePartSet::from([
794 Some(StrangePart::CriticalKills),
795 None,
796 None,
797 ]));
798 }
799
800 #[test]
801 fn is_empty() {
802 assert!(StrangePartSet::from([
803 None,
804 None,
805 None,
806 ]).is_empty());
807 }
808
809 #[test]
810 fn iter_zip() {
811 let strange_parts = StrangePartSet::from([
812 Some(StrangePart::TauntKills),
813 Some(StrangePart::KillsWhileExplosiveJumping),
814 Some(StrangePart::CriticalKills),
815 ]);
816 let with_attribute_defindex = strange_parts.into_iter()
817 .zip(StrangePart::DEFINDEX.to_owned())
818 .collect::<Vec<_>>();
819
820 assert_eq!(with_attribute_defindex, vec![
821 (StrangePart::TauntKills, 380),
822 (StrangePart::KillsWhileExplosiveJumping, 382),
823 (StrangePart::CriticalKills, 384),
824 ]);
825 }
826
827 #[test]
828 fn gets_first_and_last() {
829 let strange_parts = StrangePartSet::from([
830 Some(StrangePart::TauntKills),
831 Some(StrangePart::KillsWhileExplosiveJumping),
832 Some(StrangePart::CriticalKills),
833 ]);
834
835 assert_eq!(strange_parts.first(), Some(&StrangePart::TauntKills));
836 assert_eq!(strange_parts.last(), Some(&StrangePart::CriticalKills));
837 }
838
839 #[test]
840 fn stringify() {
841 let strange_parts = StrangePartSet::from([
842 Some(StrangePart::TauntKills),
843 Some(StrangePart::KillsWhileExplosiveJumping),
844 Some(StrangePart::CriticalKills),
845 ]);
846
847 assert_eq!(strange_parts.to_string(), "Taunt Kills, Kills While Explosive-Jumping, Critical Kills");
848 }
849
850 #[test]
851 fn retains() {
852 let mut strange_parts = StrangePartSet::from([
853 Some(StrangePart::TauntKills),
854 Some(StrangePart::KillsWhileExplosiveJumping),
855 Some(StrangePart::Assists),
856 ]);
857
858 strange_parts.retain(|part| part.is_cosmetic_part());
859
860 assert_eq!(strange_parts.first(), Some(&StrangePart::Assists));
861 }
862
863 #[test]
864 fn bit_and() {
865 let set1 = StrangePartSet::from([
866 Some(StrangePart::TauntKills),
867 Some(StrangePart::KillsWhileExplosiveJumping),
868 Some(StrangePart::CriticalKills),
869 ]);
870 let set2 = StrangePartSet::from([
871 Some(StrangePart::TauntKills),
872 Some(StrangePart::DamageDealt),
873 None,
874 ]);
875 let intersection = set1 & set2;
876 assert_eq!(intersection, StrangePartSet::from([
877 Some(StrangePart::TauntKills),
878 None,
879 None,
880 ]));
881 }
882
883 #[test]
884 fn iterate_borrowed() {
885 let strange_parts = StrangePartSet::from([
886 Some(StrangePart::TauntKills),
887 Some(StrangePart::KillsWhileExplosiveJumping),
888 Some(StrangePart::CriticalKills),
889 ]);
890
891 for strange_part in &strange_parts {
892 assert!(strange_parts.contains(&strange_part));
893 }
894 }
895}