use crate::{Aggregator, BindingKind, FilterKind};
use std::collections::BTreeSet;
#[derive(
Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize,
)]
pub enum DatalogFeature {
StratifiedNegation,
TripleTerms,
SkolemGeneration,
Filter(FilterKind),
Binding(BindingKind),
Aggregate(Aggregator),
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct DatalogCapabilities(BTreeSet<DatalogFeature>);
impl DatalogCapabilities {
#[must_use]
pub fn positive() -> Self {
Self::default()
}
#[must_use]
pub fn with(mut self, feature: DatalogFeature) -> Self {
self.0.insert(feature);
self
}
#[must_use]
pub fn contains(&self, feature: &DatalogFeature) -> bool {
self.0.contains(feature)
}
pub fn iter(&self) -> impl Iterator<Item = &DatalogFeature> {
self.0.iter()
}
#[must_use]
pub fn all_model_features() -> Self {
let mut result = Self::positive()
.with(DatalogFeature::StratifiedNegation)
.with(DatalogFeature::TripleTerms)
.with(DatalogFeature::SkolemGeneration);
for kind in FilterKind::ALL {
result.0.insert(DatalogFeature::Filter(*kind));
}
for kind in BindingKind::ALL {
result.0.insert(DatalogFeature::Binding(*kind));
}
for kind in [
Aggregator::Count,
Aggregator::Sum,
Aggregator::Min,
Aggregator::Max,
Aggregator::Avg,
] {
result.0.insert(DatalogFeature::Aggregate(kind));
}
result
}
pub(crate) fn insert(&mut self, feature: DatalogFeature) {
self.0.insert(feature);
}
pub(crate) fn missing_from(&self, supported: &Self) -> Self {
Self(self.0.difference(&supported.0).copied().collect())
}
pub(crate) fn is_empty(&self) -> bool {
self.0.is_empty()
}
}