schultek/dart_mappable

Custom mapper for UnmodifiableListView Type

Closed this issue · 4 comments

Hi, I'm tryng to change some class properties from type List to UnmodifiableListView, so facing some errors in the mappers, what should be the correct way to setup a CustomMapper for this type UnmodifiableListView that is from the dart:collection package.

I already tried with SimpleMapper1 or a MappingHook but I coudn't create one that didn't throw an error Failed to decode ...

// user_modifiable.dart file, works out of the box
import 'package:dart_mappable/dart_mappable.dart';

part 'user_modifiable.mapper.dart';

@MappableClass()
class UserModifiable with UserModifiableMappable{
  const UserModifiable({
    required this.userLogs,
    required this.userDeviceIds,
  });
  final List<String> userLogs;
  final List<int> userDeviceIds;
}
// user_unmodifiable.dart file, need a CustomMapper to recognize the UnmodifiableListView type
import 'dart:collection' show UnmodifiableListView;

import 'package:dart_mappable/dart_mappable.dart';

part 'user_unmodifiable.mapper.dart';

@MappableClass()
class UserUnmodifiable with UserUnmodifiableMappable{
  const UserUnmodifiable({
      required this.userLogs,
      required this.userDeviceIds,
  });
  final UnmodifiableListView<String> userLogs;
  final UnmodifiableListView<int> userDeviceIds;
}

CustomMapper/SimpleMapper is the right choice here.
Can you also post the code using that then I can check where the problem is.

I ended up finding out with the FIC example, not sure which option is the best performing

void main() {
  MapperContainer.globals.use(
    UnmodifiableListViewMapper(),
  );
}
class UnmodifiableListViewMapper
    extends SimpleMapper1<UnmodifiableListView<dynamic>> {
  @override
  UnmodifiableListView<T> decode<T>(dynamic value) {
    return UnmodifiableListView<T>(
      (value as Iterable).map((e) => MapperContainer.globals.fromValue<T>(e)),
    );
  }

  @override
  dynamic encode<T>(UnmodifiableListView<T> self) {
    return self
        .map((item) => MapperContainer.globals.toValue<T>(item))
        .toList();
  }

  @override
  // ignore: avoid_dynamic_calls
  Function get typeFactory => <T>(Function f) => f<UnmodifiableListView<T>>();
}

Or just this:

void main(){
  MapperContainer.globals.useAll([
      SerializableMapper<UnmodifiableListView<dynamic>, Object>.arg1(
        decode: <T>(json, fromJsonT) =>
            UnmodifiableListView<T>((json as Iterable).map(fromJsonT)),
        encode: (UnmodifiableListView<dynamic> value) =>
            (Object? Function(dynamic) toJsonT) => value.map(toJsonT).toList(),
        type: <E>(f) => f<UnmodifiableListView<E>>(),
      ),
    ]);
}

I would go with the first one.

Also you might want to add with MapperEqualityMixin< UnmodifiableListView> and implement the equality method to enable equal and hashCode on this type.

Closing this as I think this solves the issue. If not you can reopen.