vantage_vista/
capabilities.rs1use std::fmt;
5
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use vantage_core::{Result, VantageError, error};
8
9mod set;
10
11pub use set::VistaCapabilities;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
41#[non_exhaustive]
42pub enum Capability {
43 Insert,
44 Update,
45 Delete,
46 DeleteAll,
47 Import,
48 Subscribe,
49 Order,
50 Search,
51 FilterOps,
52 NativeConditions,
53 Window,
54 Cursor,
55 Traverse,
56 ConfineWrites,
57 WritesReachHooks,
58}
59
60const ALL: [Capability; 15] = [
63 Capability::Insert,
64 Capability::Update,
65 Capability::Delete,
66 Capability::DeleteAll,
67 Capability::Import,
68 Capability::Subscribe,
69 Capability::Order,
70 Capability::Search,
71 Capability::FilterOps,
72 Capability::NativeConditions,
73 Capability::Window,
74 Capability::Cursor,
75 Capability::Traverse,
76 Capability::ConfineWrites,
77 Capability::WritesReachHooks,
78];
79
80impl Capability {
81 pub fn iter() -> impl Iterator<Item = Capability> {
84 ALL.into_iter()
85 }
86
87 pub fn as_str(self) -> &'static str {
89 match self {
90 Capability::Insert => "insert",
91 Capability::Update => "update",
92 Capability::Delete => "delete",
93 Capability::DeleteAll => "delete_all",
94 Capability::Import => "import",
95 Capability::Subscribe => "subscribe",
96 Capability::Order => "order",
97 Capability::Search => "search",
98 Capability::FilterOps => "filter_ops",
99 Capability::NativeConditions => "native_conditions",
100 Capability::Window => "window",
101 Capability::Cursor => "cursor",
102 Capability::Traverse => "traverse",
103 Capability::ConfineWrites => "confine_writes",
104 Capability::WritesReachHooks => "writes_reach_hooks",
105 }
106 }
107
108 pub(crate) fn parse(name: &str) -> Option<Capability> {
110 Capability::iter().find(|c| c.as_str() == name)
111 }
112
113 fn bit(self) -> u16 {
114 1 << (self as u16)
115 }
116}
117
118impl fmt::Display for Capability {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 f.write_str(self.as_str())
121 }
122}
123
124impl Serialize for Capability {
125 fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
126 serializer.serialize_str(self.as_str())
127 }
128}
129
130impl<'de> Deserialize<'de> for Capability {
131 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> std::result::Result<Self, D::Error> {
132 let name = String::deserialize(deserializer)?;
133 Capability::parse(&name)
134 .ok_or_else(|| serde::de::Error::custom(format!("unknown capability `{name}`")))
135 }
136}
137
138pub fn unsupported<T>(capability: Capability) -> Result<T> {
142 Err(error!(
143 "capability is not supported; method refused",
144 capability = capability.as_str()
145 )
146 .mark_unsupported()
147 .traced_debug())
148}
149
150pub fn unknown_relation(relation: &str) -> VantageError {
154 error!("unknown relation", relation = relation).mark_not_found()
155}