stablekernel/aqueduct

@Bind.query('--') to Enum gives "No static parse method error" while static parse method is defined in Extension on that Enum.

Closed this issue · 6 comments

enum Roles {
  owner,
  admin,
  user,
}

extension rolesParser on Roles {
  static Roles parse(String value) {
    final Roles role = tryParse(value);
    if (role != null)
      return role;
  }
  static Roles tryParse(String input) {
    final String value = input.trim();
    return Roles.values.firstWhere((element) => element.toString().split('.')[1].toUpperCase() == value.toUpperCase());
  }
}

Bad state: Bad state: Invalid binding 'role' on 'UsersController.getUsers': Parameter type does not implement static parse method.
**** Stacktrace

  • #0 _enforceTypeCanBeParsedFromString (package:aqueduct/src/runtime/resource_controller_impl.dart:313:5)
  • #1 ResourceControllerRuntimeImpl.getParameterForVariable (package:aqueduct/src/runtime/resource_controller_impl.dart:203:15)
  • #2 ResourceControllerRuntimeImpl.getOperationForMethod. (package:aqueduct/src/runtime/resource_controller_impl.dart:277:26)
  • #3 MappedIterator.moveNext (dart:_internal/iterable.dart:395:20)
  • #4 new List.from (dart:core-patch/array_patch.dart:47:19)
  • #5 Iterable.toList (dart:core/iterable.dart:400:12)
  • #6 ResourceControllerRuntimeImpl.getOperationForMethod (package:aqueduct/src/runtime/resource_controller_impl.dart:281:14)
  • #7 MappedIterator.moveNext (dart:_internal/iterable.dart:395:20)
  • #8 new List.from (dart:core-patch/array_patch.dart:47:19)
  • #9 Iterable.toList (dart:core/iterable.dart:400:12)
  • #10 new ResourceControllerRuntimeImpl (package:aqueduct/src/runtime/resource_controller_impl.dart:31:10)
  • #11 new ControllerRuntimeImpl (package:aqueduct/src/runtime/impl.dart:146:28)
  • #12 AqueductCompiler.compile. (package:aqueduct/src/runtime/compiler.dart:21:46)
  • #13 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
  • #14 ListIterator.moveNext (dart:_internal/iterable.dart:346:26)
  • #15 MapMixin.addEntries (dart:collection/maps.dart:172:23)
  • #16 AqueductCompiler.compile (package:aqueduct/src/runtime/compiler.dart:20:7)
  • #17 new MirrorContext._. (package:runtime/src/mirror_context.dart:13:34)
  • #18 List.forEach (dart:core-patch/growable_array.dart:282:8)
  • #19 new MirrorContext._ (package:runtime/src/mirror_context.dart:12:15)
  • #20 instance (package:runtime/src/mirror_context.dart:7:41)
  • #21 instance (package:runtime/src/mirror_context.dart:7:16)
  • #22 RuntimeContext.current (package:runtime/src/context.dart:10:33)
  • #23 GetChannelExecutable.execute (data:application/dart:14:199)
  • #24 main (data:application/dart:10:35)
  • #25 _startIsolate. (dart:isolate-patch/isolate_patch.dart:297:32)
  • #26 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

Please when you post code use a "code block".

enum Roles {
  owner,
  admin,
  user,
}

extension RolesParser on Roles {
  // You can not add static methods extension. The code below allows you do this `RolesParser.parse()` not `Roles.parse()`  
  static Roles parse(String value) {
    final Roles role = tryParse(value);
    if (role != null) return role;
  }

  static Roles tryParse(String input) {
    final String value = input.trim();
    return Roles.values.firstWhere((element) =>
        element.toString().split('.')[1].toUpperCase() == value.toUpperCase());
  }
}

What I would do is either bind to a string and then parse it or do something like:

class RoleBind {
  RoleBind._(this.value);

  final Role value;

  static RoleBind parse(String input) {
    final result = RoleBind.tryParse(input);
    if (result != null) {
      return result;
    }
    throw 'Cound not parse Role';
  }

  static RoleBind tryParse(String input) {
    final value = input.trim();
    final eValue = Role.values.firstWhere((role) =>
      role.toString().split('.').last.toUppperCase() == value.toUpperCase());
    if(eValue != null) {
        return RoleBind._(eValue);
    }
    return null;
  }
}

I would also recommend renaming Roles to Role as it is more natural to say Role.user then Roles.user.

Please when you post code use a "code block".
I apologize, I have done the needful. Thanks.

@Reductions , your advice to make another class called RoleBind worked like a charm. Thanks a ton.