vantage_vista/capabilities/
set.rs1use std::fmt;
4
5use serde::de::{Deserializer, MapAccess, Visitor};
6use serde::ser::{SerializeMap, Serializer};
7use serde::{Deserialize, Serialize};
8
9use super::{ALL, Capability};
10
11#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
18pub struct VistaCapabilities {
19 bits: u16,
20}
21
22impl VistaCapabilities {
23 pub fn new() -> Self {
25 Self::default()
26 }
27
28 pub fn with(mut self, capability: Capability) -> Self {
30 self.bits |= capability.bit();
31 self
32 }
33
34 pub fn without(mut self, capability: Capability) -> Self {
36 self.bits &= !capability.bit();
37 self
38 }
39
40 pub fn has(&self, capability: Capability) -> bool {
41 self.bits & capability.bit() != 0
42 }
43
44 pub fn iter(&self) -> impl Iterator<Item = Capability> + '_ {
46 Capability::iter().filter(|c| self.has(*c))
47 }
48}
49
50impl FromIterator<Capability> for VistaCapabilities {
51 fn from_iter<I: IntoIterator<Item = Capability>>(iter: I) -> Self {
52 iter.into_iter().fold(Self::new(), Self::with)
53 }
54}
55
56impl fmt::Debug for VistaCapabilities {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 f.debug_set().entries(self.iter()).finish()
59 }
60}
61
62impl Serialize for VistaCapabilities {
63 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
64 let mut map = serializer.serialize_map(Some(ALL.len()))?;
65 for capability in Capability::iter() {
66 map.serialize_entry(capability.as_str(), &self.has(capability))?;
67 }
68 map.end()
69 }
70}
71
72impl<'de> Deserialize<'de> for VistaCapabilities {
73 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
74 struct SetVisitor;
75 impl<'de> Visitor<'de> for SetVisitor {
76 type Value = VistaCapabilities;
77 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 f.write_str("a map from capability name to bool")
79 }
80 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
81 let mut set = VistaCapabilities::new();
82 while let Some((capability, on)) = map.next_entry::<Capability, bool>()? {
83 if on {
84 set = set.with(capability);
85 }
86 }
87 Ok(set)
88 }
89 }
90 deserializer.deserialize_map(SetVisitor)
91 }
92}