df-derive-macros 0.3.0

Procedural derive macro implementation for df-derive.
Documentation
use syn::Ident;

use super::{AccessChain, NonEmpty, TerminalLeafSpec, VecLayers, WrapperShape};

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ColumnIR {
    Field(FieldColumn),
    TupleStatic(TupleStaticColumn),
    TupleParentOption(TupleParentOptionColumn),
    TupleParentVec(TupleParentVecColumn),
}

impl ColumnIR {
    pub(crate) const fn field(
        name: String,
        source: FieldSource,
        leaf_spec: TerminalLeafSpec,
        wrapper_shape: WrapperShape,
    ) -> Self {
        Self::Field(FieldColumn {
            common: ColumnCommon::new(name, leaf_spec),
            source,
            wrapper_shape,
        })
    }

    pub(crate) const fn tuple_static(
        name: String,
        root: FieldSource,
        path: TupleProjectionPath,
        leaf_spec: TerminalLeafSpec,
        wrapper_shape: WrapperShape,
    ) -> Self {
        Self::TupleStatic(TupleStaticColumn {
            common: ColumnCommon::new(name, leaf_spec),
            root,
            path,
            wrapper_shape,
        })
    }

    pub(crate) const fn tuple_parent_option(
        name: String,
        root: FieldSource,
        path: TupleProjectionPath,
        parent_access: AccessChain,
        leaf_spec: TerminalLeafSpec,
        wrapper_shape: WrapperShape,
    ) -> Self {
        Self::TupleParentOption(TupleParentOptionColumn {
            common: ColumnCommon::new(name, leaf_spec),
            root,
            path,
            parent_access,
            wrapper_shape,
        })
    }

    pub(crate) const fn tuple_parent_vec(
        name: String,
        root: FieldSource,
        terminal_step: TupleProjectionStep,
        projection_layer: usize,
        parent_inner_access: AccessChain,
        leaf_spec: TerminalLeafSpec,
        wrapper_shape: VecLayers,
    ) -> Self {
        Self::TupleParentVec(TupleParentVecColumn {
            common: ColumnCommon::new(name, leaf_spec),
            root,
            terminal_step,
            projection_layer,
            parent_inner_access,
            wrapper_shape,
        })
    }

    pub fn name(&self) -> &str {
        self.common().name()
    }

    pub const fn leaf_spec(&self) -> &TerminalLeafSpec {
        self.common().leaf_spec()
    }

    pub const fn vec_depth(&self) -> usize {
        match self {
            Self::Field(column) => column.wrapper_shape.vec_depth(),
            Self::TupleStatic(column) => column.wrapper_shape.vec_depth(),
            Self::TupleParentOption(column) => column.wrapper_shape.vec_depth(),
            Self::TupleParentVec(column) => column.wrapper_shape.depth(),
        }
    }

    const fn common(&self) -> &ColumnCommon {
        match self {
            Self::Field(column) => &column.common,
            Self::TupleStatic(column) => &column.common,
            Self::TupleParentOption(column) => &column.common,
            Self::TupleParentVec(column) => &column.common,
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ColumnCommon {
    name: String,
    leaf_spec: TerminalLeafSpec,
}

impl ColumnCommon {
    const fn new(name: String, leaf_spec: TerminalLeafSpec) -> Self {
        Self { name, leaf_spec }
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub const fn leaf_spec(&self) -> &TerminalLeafSpec {
        &self.leaf_spec
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FieldColumn {
    common: ColumnCommon,
    source: FieldSource,
    wrapper_shape: WrapperShape,
}

impl FieldColumn {
    pub fn name(&self) -> &str {
        self.common.name()
    }

    pub const fn leaf_spec(&self) -> &TerminalLeafSpec {
        self.common.leaf_spec()
    }

    pub const fn source(&self) -> &FieldSource {
        &self.source
    }

    pub const fn wrapper_shape(&self) -> &WrapperShape {
        &self.wrapper_shape
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TupleStaticColumn {
    common: ColumnCommon,
    root: FieldSource,
    path: TupleProjectionPath,
    wrapper_shape: WrapperShape,
}

impl TupleStaticColumn {
    pub fn name(&self) -> &str {
        self.common.name()
    }

    pub const fn leaf_spec(&self) -> &TerminalLeafSpec {
        self.common.leaf_spec()
    }

    pub const fn root(&self) -> &FieldSource {
        &self.root
    }

    pub const fn path(&self) -> &TupleProjectionPath {
        &self.path
    }

    pub const fn wrapper_shape(&self) -> &WrapperShape {
        &self.wrapper_shape
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TupleParentOptionColumn {
    common: ColumnCommon,
    root: FieldSource,
    path: TupleProjectionPath,
    parent_access: AccessChain,
    wrapper_shape: WrapperShape,
}

impl TupleParentOptionColumn {
    pub fn name(&self) -> &str {
        self.common.name()
    }

    pub const fn leaf_spec(&self) -> &TerminalLeafSpec {
        self.common.leaf_spec()
    }

    pub const fn root(&self) -> &FieldSource {
        &self.root
    }

    pub const fn path(&self) -> &TupleProjectionPath {
        &self.path
    }

    pub const fn parent_access(&self) -> &AccessChain {
        &self.parent_access
    }

    pub const fn wrapper_shape(&self) -> &WrapperShape {
        &self.wrapper_shape
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TupleParentVecColumn {
    common: ColumnCommon,
    root: FieldSource,
    terminal_step: TupleProjectionStep,
    projection_layer: usize,
    parent_inner_access: AccessChain,
    wrapper_shape: VecLayers,
}

impl TupleParentVecColumn {
    pub fn name(&self) -> &str {
        self.common.name()
    }

    pub const fn leaf_spec(&self) -> &TerminalLeafSpec {
        self.common.leaf_spec()
    }

    pub const fn root(&self) -> &FieldSource {
        &self.root
    }

    pub const fn terminal_step(&self) -> TupleProjectionStep {
        self.terminal_step
    }

    pub const fn projection_layer(&self) -> usize {
        self.projection_layer
    }

    pub const fn parent_inner_access(&self) -> &AccessChain {
        &self.parent_inner_access
    }

    pub const fn wrapper_shape(&self) -> &VecLayers {
        &self.wrapper_shape
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TupleProjectionPath {
    steps: NonEmpty<TupleProjectionStep>,
}

impl TupleProjectionPath {
    pub(crate) fn from_vec(steps: Vec<TupleProjectionStep>) -> Option<Self> {
        NonEmpty::from_vec(steps).map(|steps| Self { steps })
    }

    pub fn iter(&self) -> impl Iterator<Item = &TupleProjectionStep> {
        self.steps.iter()
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FieldSource {
    pub name: Ident,
    pub field_index: Option<usize>,
    pub outer_smart_ptr_depth: usize,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TupleProjectionStep {
    pub index: usize,
    pub outer_smart_ptr_depth: usize,
}