mod field;
mod id;
use std::{borrow::Cow, fmt};
use crate::{
datamodel::attributes::BlockAttribute,
value::{Array, Constant, Function, Text, Value},
};
pub use field::{IndexFieldInput, UniqueFieldAttribute};
pub use id::{IdDefinition, IdFieldDefinition};
#[derive(Debug)]
pub struct IndexDefinition<'a>(BlockAttribute<'a>);
impl<'a> IndexDefinition<'a> {
pub fn index(fields: impl Iterator<Item = IndexFieldInput<'a>>) -> Self {
Self::new("index", fields)
}
pub fn unique(fields: impl Iterator<Item = IndexFieldInput<'a>>) -> Self {
Self::new("unique", fields)
}
pub fn fulltext(fields: impl Iterator<Item = IndexFieldInput<'a>>) -> Self {
Self::new("fulltext", fields)
}
pub fn name(&mut self, name: impl Into<Cow<'a, str>>) {
self.0.push_param(("name", Text::new(name)));
}
pub fn map(&mut self, map: impl Into<Cow<'a, str>>) {
self.0.push_param(("map", Text::new(map)));
}
pub fn clustered(&mut self, clustered: bool) {
self.0.push_param(("clustered", Constant::new_no_validate(clustered)));
}
pub fn index_type(&mut self, index_type: impl Into<Cow<'a, str>>) {
self.0
.push_param(("type", Constant::new_no_validate(index_type.into())));
}
fn new(index_type: &'static str, fields: impl Iterator<Item = IndexFieldInput<'a>>) -> Self {
let mut inner = Function::new(index_type);
let fields: Vec<_> = fields.map(Function::from).map(Value::Function).collect();
inner.push_param(Value::Array(Array::from(fields)));
Self(BlockAttribute(inner))
}
}
impl<'a> fmt::Display for IndexDefinition<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Clone)]
pub enum InnerOps<'a> {
Managed(Cow<'a, str>),
Raw(Text<Cow<'a, str>>),
}
#[derive(Debug, Clone)]
pub struct IndexOps<'a>(InnerOps<'a>);
impl<'a> IndexOps<'a> {
pub fn managed(ops: impl Into<Cow<'a, str>>) -> Self {
Self(InnerOps::Managed(ops.into()))
}
pub fn raw(ops: impl Into<Cow<'a, str>>) -> Self {
Self(InnerOps::Raw(Text(ops.into())))
}
}
impl<'a> fmt::Display for IndexOps<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
InnerOps::Managed(ref s) => f.write_str(s),
InnerOps::Raw(ref s) => {
write!(f, "raw({s})")
}
}
}
}