Skip to content

Consider adding a flow-sensitive type definition builder #232

Open
@popematt

Description

@popematt

We could have a flow-sensitive ISL-typed builder.

Consider the following:

pub struct TypeDefinitionBuilder<V: IslVersion, T: IslType> {
    pub(crate) constraints: Vec<AnyConstraint>,
    open_content: Vec<(Symbol, IonData<Element>)>,
    isl_version: PhantomData<V>,
    isl_type: PhantomData<T>,
}

We could create a set of empty types and marker traits:

enum UnknownType
enum NumberType
enum DecimalType
enum IntegerType
enum FloatType

trait CouldBeDecimalType {}

impl CouldBeDecimalType for DecimalType {}
impl CouldBeDecimalType for UnknownType {}
impl CouldBeDecimalType for NumberType {}

And then use generic builder method implementations that can transition the builder's type-state.

impl <V: IslVersion, T: CouldBeDecimalType> TypeDefinitionBuilder<V, T> {
    pub fn precision(self, range: Range<usize>) -> TypeDefinitionBuilder<V, DecimalType> {
        let { mut constraints, open_content, isl_version, _ } = self;
        constraints.push(AnyConstraint::from(PrecisionConstraint::new(range)));
        TypeDefinitionBuilder { constraints, open_content, isl_version, isl_type: Phantom::<DecimalType>::default() }
    }
}

That would allow things like this to compile successfully:

let my_type = TypeBuilder::new()
    .annotations(Closed, ["foo"])
    .precision(0..=10)
    .exponent(-2)
    .build();

But it would cause a compilation error for cases like this:

let my_type = TypeBuilder::new()
    .annotations(Closed, ["foo"])
    .precision(0..=10)
    .exponent(-2)
    .timestamp_offset(["+00:00"])
    .build();

This is probably not suitable for all use cases, so we would probably need to add a flow-sensitive builder as an option that complements rather than replaces a naive builder.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions