use crate::{
schema::db::ColumnId,
stmt::{PathFieldSet, Projection},
};
use indexmap::IndexMap;
#[derive(Debug, Clone)]
pub enum Field {
Primitive(FieldPrimitive),
Struct(FieldStruct),
Enum(FieldEnum),
Relation(FieldRelation),
}
impl Field {
pub fn field_mask(&self) -> PathFieldSet {
match self {
Field::Primitive(p) => p.field_mask.clone(),
Field::Struct(s) => s.field_mask.clone(),
Field::Enum(e) => e.field_mask.clone(),
Field::Relation(r) => r.field_mask.clone(),
}
}
pub fn sub_projection(&self) -> &Projection {
static IDENTITY: Projection = Projection::identity();
match self {
Field::Primitive(p) => &p.sub_projection,
Field::Struct(s) => &s.sub_projection,
Field::Enum(e) => &e.sub_projection,
Field::Relation(_) => &IDENTITY,
}
}
pub fn is_relation(&self) -> bool {
matches!(self, Field::Relation(_))
}
pub fn as_primitive(&self) -> Option<&FieldPrimitive> {
match self {
Field::Primitive(p) => Some(p),
_ => None,
}
}
pub fn as_primitive_mut(&mut self) -> Option<&mut FieldPrimitive> {
match self {
Field::Primitive(p) => Some(p),
_ => None,
}
}
pub fn as_struct(&self) -> Option<&FieldStruct> {
match self {
Field::Struct(s) => Some(s),
_ => None,
}
}
pub fn as_enum(&self) -> Option<&FieldEnum> {
match self {
Field::Enum(e) => Some(e),
_ => None,
}
}
pub fn columns(&self) -> impl Iterator<Item = (ColumnId, usize)> + '_ {
match self {
Field::Primitive(fp) => Box::new(std::iter::once((fp.column, fp.lowering)))
as Box<dyn Iterator<Item = (ColumnId, usize)> + '_>,
Field::Struct(fs) => Box::new(fs.columns.iter().map(|(k, v)| (*k, *v))),
Field::Enum(fe) => Box::new(
std::iter::once((fe.discriminant.column, fe.discriminant.lowering)).chain(
fe.variants
.iter()
.flat_map(|v| v.fields.iter().flat_map(|f| f.columns())),
),
),
Field::Relation(_) => Box::new(std::iter::empty()),
}
}
}
#[derive(Debug, Clone)]
pub struct FieldPrimitive {
pub column: ColumnId,
pub lowering: usize,
pub field_mask: PathFieldSet,
pub sub_projection: Projection,
}
#[derive(Debug, Clone)]
pub struct FieldStruct {
pub fields: Vec<Field>,
pub columns: IndexMap<ColumnId, usize>,
pub field_mask: PathFieldSet,
pub sub_projection: Projection,
}
#[derive(Debug, Clone)]
pub struct FieldEnum {
pub discriminant: FieldPrimitive,
pub variants: Vec<EnumVariant>,
pub field_mask: PathFieldSet,
pub sub_projection: Projection,
}
#[derive(Debug, Clone)]
pub struct EnumVariant {
pub discriminant: crate::stmt::Value,
pub fields: Vec<Field>,
}
#[derive(Debug, Clone)]
pub struct FieldRelation {
pub field_mask: PathFieldSet,
}