use std::fmt;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use vantage_core::{Result, VantageError, error};
mod set;
#[cfg(test)]
mod tests;
pub use set::VistaCapabilities;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[non_exhaustive]
pub enum Capability {
Insert,
Update,
Delete,
Import,
Subscribe,
Order,
Search,
FilterOps,
NativeConditions,
Window,
Cursor,
Traverse,
ConfineWrites,
}
const ALL: [Capability; 13] = [
Capability::Insert,
Capability::Update,
Capability::Delete,
Capability::Import,
Capability::Subscribe,
Capability::Order,
Capability::Search,
Capability::FilterOps,
Capability::NativeConditions,
Capability::Window,
Capability::Cursor,
Capability::Traverse,
Capability::ConfineWrites,
];
impl Capability {
pub fn iter() -> impl Iterator<Item = Capability> {
ALL.into_iter()
}
pub fn as_str(self) -> &'static str {
match self {
Capability::Insert => "insert",
Capability::Update => "update",
Capability::Delete => "delete",
Capability::Import => "import",
Capability::Subscribe => "subscribe",
Capability::Order => "order",
Capability::Search => "search",
Capability::FilterOps => "filter_ops",
Capability::NativeConditions => "native_conditions",
Capability::Window => "window",
Capability::Cursor => "cursor",
Capability::Traverse => "traverse",
Capability::ConfineWrites => "confine_writes",
}
}
pub(crate) fn parse(name: &str) -> Option<Capability> {
Capability::iter().find(|c| c.as_str() == name)
}
fn bit(self) -> u16 {
1 << (self as u16)
}
}
impl fmt::Display for Capability {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl Serialize for Capability {
fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
impl<'de> Deserialize<'de> for Capability {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> std::result::Result<Self, D::Error> {
let name = String::deserialize(deserializer)?;
Capability::parse(&name)
.ok_or_else(|| serde::de::Error::custom(format!("unknown capability `{name}`")))
}
}
pub fn unsupported<T>(capability: Capability) -> Result<T> {
Err(error!(
"capability is not supported; method refused",
capability = capability.as_str()
)
.mark_unsupported()
.traced_debug())
}
pub fn unknown_relation(relation: &str) -> VantageError {
error!("unknown relation", relation = relation).mark_not_found()
}