Skip to content

ValueObject for enums: how to properly validate? #13

@chikamichi

Description

@chikamichi

Hi 👋,

Continuing on implementing my map project, let’s say I have this enum representing a map layer’s "type"/kind: enum Type { raster, vector, geojson }.

If I wish to have some entity’s attribute be of that kind, as far as I understand (and based on trial/error), it cannot be simply typed as a Type but rather has to be wrapped in a value object — such as this one, although it seems "useless" (see inlined comments as to why):

import "package:freezed_annotation/freezed_annotation.dart";

part 'map_layer_type.modddel.dart';
part 'map_layer_type.freezed.dart';

enum Type { raster, vector, geojson }

@Modddel(
  validationSteps: [
    // It seems like at least one validation step MUST be implemented.
    ValidationStep([Validation("allowed", FailureType<EnumFailure>())]),
  ],
)
class MapLayerType
    extends SingleValueObject<InvalidMapLayerType, ValidMapLayerType>
    with _$MapLayerType {
  MapLayerType._();

  // For value is typed as Type, the "allowed" validation is useless.
  // Code will *not* compile if trying to instanciate a ValueObject with anything
  // but a (valid by design) Type enum value.
  factory MapLayerType(Type value) {
    return _$MapLayerType._create(
      value: value,
    );
  }

  @override
  Option<EnumFailure> validateAllowed(mapLayerType) {
    if (mapLayerType.value is! Type) { // Warning: "Unecessary type check; the result is always 'false'. Try correcting the type check, or removing the type check.
      return some(const EnumFailure.allowed());
    }
    // I guess I could get rid of the type checking then, and simply return none(), period.
    return none();
  }
}

@freezed
class EnumFailure extends ValueFailure with _$EnumFailure {
  const factory EnumFailure.allowed() = _Allowed;
}

Is there a better way?

I feel like enums being sealed by design, having to come up with a dedicated value object is useless boilerplate, but maybe I’m missing something?

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussionOpen-ended topics or questions, likely to be converted to a Github Discussion

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions