use std::collections::HashSet;
use std::mem;
use surrealdb_core::dbs::NewPlannerStrategy;
use surrealdb_core::dbs::capabilities::{
Capabilities as CoreCapabilities, ExperimentalTarget, FuncTarget, ParseFuncTargetError,
ParseNetTargetError, Targets,
};
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum PlannerStrategy {
BestEffort,
ComputeOnly,
AllReadOnly,
}
#[doc(hidden)]
impl From<PlannerStrategy> for NewPlannerStrategy {
fn from(strategy: PlannerStrategy) -> Self {
match strategy {
PlannerStrategy::BestEffort => NewPlannerStrategy::BestEffortReadOnlyStatements,
PlannerStrategy::ComputeOnly => NewPlannerStrategy::ComputeOnly,
PlannerStrategy::AllReadOnly => NewPlannerStrategy::AllReadOnlyStatements,
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[non_exhaustive]
pub enum ExperimentalFeature {
Files,
Surrealism,
}
#[doc(hidden)]
impl From<&ExperimentalFeature> for ExperimentalTarget {
fn from(feature: &ExperimentalFeature) -> Self {
match feature {
ExperimentalFeature::Files => ExperimentalTarget::Files,
ExperimentalFeature::Surrealism => ExperimentalTarget::Surrealism,
}
}
}
#[cfg_attr(feature = "kv-rocksdb", doc = "```no_run")]
#[cfg_attr(not(feature = "kv-rocksdb"), doc = "```ignore")]
#[cfg_attr(feature = "kv-rocksdb", doc = "```no_run")]
#[cfg_attr(not(feature = "kv-rocksdb"), doc = "```ignore")]
#[derive(Debug, Clone)]
pub struct Capabilities {
cap: CoreCapabilities,
}
impl Default for Capabilities {
fn default() -> Self {
Self::new()
}
}
impl Capabilities {
pub fn new() -> Self {
Capabilities {
cap: CoreCapabilities::default()
.with_functions(Targets::All)
.without_functions(Targets::None)
.with_network_targets(Targets::None)
.without_network_targets(Targets::None),
}
}
pub fn all() -> Self {
Capabilities {
cap: CoreCapabilities::all()
.with_functions(Targets::All)
.without_functions(Targets::None)
.with_network_targets(Targets::All)
.without_network_targets(Targets::None),
}
}
pub fn none() -> Self {
Capabilities {
cap: CoreCapabilities::none()
.with_functions(Targets::None)
.without_functions(Targets::None)
.with_network_targets(Targets::None)
.without_network_targets(Targets::None),
}
}
pub fn with_scripting(self, enabled: bool) -> Self {
Self {
cap: self.cap.with_scripting(enabled),
}
}
pub fn with_guest_access(self, enabled: bool) -> Self {
Self {
cap: self.cap.with_guest_access(enabled),
}
}
pub fn with_live_query_notifications(self, enabled: bool) -> Self {
Self {
cap: self.cap.with_live_query_notifications(enabled),
}
}
pub fn with_planner_strategy(self, strategy: PlannerStrategy) -> Self {
Self {
cap: self.cap.with_planner_strategy(strategy.into()),
}
}
pub fn allow_all_functions(&mut self) -> &mut Self {
*self.cap.allowed_functions_mut() = Targets::All;
self
}
pub fn with_all_functions_allowed(mut self) -> Self {
self.allow_all_functions();
self
}
pub fn deny_all_functions(&mut self) -> &mut Self {
*self.cap.denied_functions_mut() = Targets::All;
self
}
pub fn with_all_functions_denied(mut self) -> Self {
self.deny_all_functions();
self
}
pub fn allow_no_functions(&mut self) -> &mut Self {
*self.cap.allowed_functions_mut() = Targets::None;
self
}
pub fn with_no_functions_allowed(mut self) -> Self {
self.allow_no_functions();
self
}
pub fn deny_no_functions(&mut self) -> &mut Self {
*self.cap.denied_functions_mut() = Targets::None;
self
}
pub fn with_no_functions_denied(mut self) -> Self {
self.deny_no_functions();
self
}
pub fn allow_function<S: AsRef<str>>(
&mut self,
func: S,
) -> Result<&mut Self, ParseFuncTargetError> {
self.allow_function_str(func.as_ref())
}
pub fn with_function_allowed<S: AsRef<str>>(
mut self,
func: S,
) -> Result<Self, ParseFuncTargetError> {
self.allow_function(func)?;
Ok(self)
}
fn allow_function_str(&mut self, s: &str) -> Result<&mut Self, ParseFuncTargetError> {
let target: FuncTarget = s.parse()?;
match self.cap.allowed_functions_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.insert(target);
self.cap = mem::take(&mut self.cap).with_functions(Targets::Some(set));
}
Targets::Some(x) => {
x.insert(target);
}
}
Ok(self)
}
pub fn deny_function<S: AsRef<str>>(
&mut self,
func: S,
) -> Result<&mut Self, ParseFuncTargetError> {
self.deny_function_str(func.as_ref())
}
pub fn with_function_denied<S: AsRef<str>>(
mut self,
func: S,
) -> Result<Self, ParseFuncTargetError> {
self.deny_function(func)?;
Ok(self)
}
fn deny_function_str(&mut self, s: &str) -> Result<&mut Self, ParseFuncTargetError> {
let target: FuncTarget = s.parse()?;
match self.cap.denied_functions_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.insert(target);
*self.cap.denied_functions_mut() = Targets::Some(set);
}
Targets::Some(x) => {
x.insert(target);
}
}
Ok(self)
}
pub fn allow_all_net_targets(&mut self) -> &mut Self {
*self.cap.allowed_network_targets_mut() = Targets::All;
self
}
pub fn with_all_net_targets_allowed(mut self) -> Self {
self.allow_all_net_targets();
self
}
pub fn deny_all_net_targets(&mut self) -> &mut Self {
*self.cap.denied_network_targets_mut() = Targets::All;
self
}
pub fn with_all_net_targets_denied(mut self) -> Self {
self.deny_all_net_targets();
self
}
pub fn allow_no_net_targets(&mut self) -> &mut Self {
*self.cap.allowed_network_targets_mut() = Targets::None;
self
}
pub fn with_no_net_targets_allowed(mut self) -> Self {
self.allow_no_net_targets();
self
}
pub fn deny_no_net_targets(&mut self) -> &mut Self {
*self.cap.denied_network_targets_mut() = Targets::None;
self
}
pub fn with_no_net_targets_denied(mut self) -> Self {
self.deny_no_net_targets();
self
}
pub fn allow_net_target<S: AsRef<str>>(
&mut self,
func: S,
) -> Result<&mut Self, ParseNetTargetError> {
self.allow_net_target_str(func.as_ref())
}
pub fn with_net_target_allowed<S: AsRef<str>>(
mut self,
func: S,
) -> Result<Self, ParseNetTargetError> {
self.allow_net_target(func)?;
Ok(self)
}
fn allow_net_target_str(&mut self, s: &str) -> Result<&mut Self, ParseNetTargetError> {
let target = s.parse()?;
match self.cap.allowed_network_targets_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.insert(target);
*self.cap.allowed_network_targets_mut() = Targets::Some(set);
}
Targets::Some(x) => {
x.insert(target);
}
}
Ok(self)
}
pub fn deny_net_target<S: AsRef<str>>(
&mut self,
func: S,
) -> Result<&mut Self, ParseNetTargetError> {
self.deny_net_target_str(func.as_ref())
}
pub fn with_net_target_denied<S: AsRef<str>>(
mut self,
func: S,
) -> Result<Self, ParseNetTargetError> {
self.deny_net_target(func)?;
Ok(self)
}
fn deny_net_target_str(&mut self, s: &str) -> Result<&mut Self, ParseNetTargetError> {
let target = s.parse()?;
match self.cap.denied_network_targets_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.insert(target);
*self.cap.denied_network_targets_mut() = Targets::Some(set);
}
Targets::Some(x) => {
x.insert(target);
}
}
Ok(self)
}
pub fn allow_all_experimental_features(&mut self) -> &mut Self {
*self.cap.allowed_experimental_features_mut() = Targets::All;
self
}
pub fn with_all_experimental_features_allowed(mut self) -> Self {
self.allow_all_experimental_features();
self
}
pub fn allow_experimental_features(&mut self, features: &[ExperimentalFeature]) -> &mut Self {
let features = features.iter().map(ExperimentalTarget::from);
match self.cap.allowed_experimental_features_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.extend(features);
*self.cap.allowed_experimental_features_mut() = Targets::Some(set);
}
Targets::Some(set) => {
set.extend(features);
}
}
self
}
pub fn with_experimental_features_allowed(mut self, features: &[ExperimentalFeature]) -> Self {
self.allow_experimental_features(features);
self
}
pub fn allow_experimental_feature(&mut self, feature: ExperimentalFeature) -> &mut Self {
let feature = ExperimentalTarget::from(&feature);
match self.cap.allowed_experimental_features_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.insert(feature);
*self.cap.allowed_experimental_features_mut() = Targets::Some(set);
}
Targets::Some(set) => {
set.insert(feature);
}
}
self
}
pub fn with_experimental_feature_allowed(mut self, feature: ExperimentalFeature) -> Self {
self.allow_experimental_feature(feature);
self
}
pub fn allow_no_experimental_features(&mut self) -> &mut Self {
*self.cap.allowed_experimental_features_mut() = Targets::None;
self
}
pub fn with_no_experimental_features_allowed(mut self) -> Self {
self.allow_no_experimental_features();
self
}
pub fn deny_all_experimental_features(&mut self) -> &mut Self {
*self.cap.denied_experimental_features_mut() = Targets::All;
self
}
pub fn with_all_experimental_features_denied(mut self) -> Self {
self.deny_all_experimental_features();
self
}
pub fn deny_experimental_features(&mut self, features: &[ExperimentalFeature]) -> &mut Self {
let features = features.iter().map(ExperimentalTarget::from);
match self.cap.denied_experimental_features_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.extend(features);
*self.cap.denied_experimental_features_mut() = Targets::Some(set);
}
Targets::Some(set) => {
set.extend(features);
}
}
self
}
pub fn with_experimental_features_denied(mut self, features: &[ExperimentalFeature]) -> Self {
self.deny_experimental_features(features);
self
}
pub fn deny_experimental_feature(&mut self, feature: ExperimentalFeature) -> &mut Self {
let feature = ExperimentalTarget::from(&feature);
match self.cap.denied_experimental_features_mut() {
Targets::None | Targets::All => {
let mut set = HashSet::new();
set.insert(feature);
*self.cap.denied_experimental_features_mut() = Targets::Some(set);
}
Targets::Some(set) => {
set.insert(feature);
}
}
self
}
pub fn with_experimental_feature_denied(mut self, feature: ExperimentalFeature) -> Self {
self.deny_experimental_feature(feature);
self
}
pub fn deny_no_experimental_features(&mut self) -> &mut Self {
*self.cap.denied_experimental_features_mut() = Targets::None;
self
}
pub fn with_no_experimental_features_denied(mut self) -> Self {
self.deny_no_experimental_features();
self
}
}
#[doc(hidden)]
impl From<Capabilities> for CoreCapabilities {
fn from(
Capabilities {
cap,
}: Capabilities,
) -> Self {
cap
}
}
#[doc(hidden)]
impl From<CoreCapabilities> for Capabilities {
fn from(cap: CoreCapabilities) -> Self {
Self {
cap,
}
}
}