#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum AggregateKind {
List,
Set,
Bag,
Array,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Bound {
Integer(u64),
Unbounded,
Expression(String),
}
impl Bound {
#[must_use]
pub const fn as_integer(&self) -> Option<u64> {
match self {
Self::Integer(value) => Some(*value),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct Aggregation {
pub kind: AggregateKind,
pub lower: Bound,
pub upper: Bound,
pub unique: bool,
pub optional_elements: bool,
}
impl Aggregation {
#[must_use]
pub const fn new(kind: AggregateKind, lower: Bound, upper: Bound) -> Self {
Self {
kind,
lower,
upper,
unique: false,
optional_elements: false,
}
}
#[must_use]
pub const fn unique(mut self) -> Self {
self.unique = true;
self
}
#[must_use]
pub const fn optional_elements(mut self) -> Self {
self.optional_elements = true;
self
}
#[must_use]
pub const fn forbids_duplicates(&self) -> bool {
self.unique || matches!(self.kind, AggregateKind::Set)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct Attribute {
pub name: String,
pub type_name: String,
pub optional: bool,
pub aggregate: bool,
pub aggregation: Vec<Aggregation>,
}
impl Attribute {
#[must_use]
pub fn new(name: impl Into<String>, type_name: impl Into<String>) -> Self {
Self {
name: name.into(),
type_name: type_name.into(),
optional: false,
aggregate: false,
aggregation: Vec::new(),
}
}
#[must_use]
pub const fn optional(mut self) -> Self {
self.optional = true;
self
}
#[must_use]
pub const fn aggregate(mut self) -> Self {
self.aggregate = true;
self
}
#[must_use]
pub fn with_aggregation(mut self, aggregation: Aggregation) -> Self {
self.aggregation.push(aggregation);
self.aggregate = true;
self
}
}