Code Monkey home page Code Monkey logo

fast_immutable_collections's People

Contributors

karabanovbs avatar khoadng avatar lowlevelsubmarine avatar marcglasberg avatar matthias-prevost avatar narumincho avatar psygo avatar ricardodalarme avatar semperos avatar solido avatar tarekkma avatar timwhiting avatar tjarvstrand avatar yehorh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fast_immutable_collections's Issues

Possibly incorrectly exposed classes

Hello!

There seem to be some classes that should not be exposed.

Can class InternalsForTestingPurposesIList, InternalsForTestingPurposesIMap and InternalsForTestingPurposesISet be kept private to not pollute the scope of entities that the package exposes?

I will be more than happy to submit a PR :)

type 'String' is not a subtype of type 'Enum' in type cast

Error:

Unhandled exception:
type 'String' is not a subtype of type 'TestEnum' in type cast
#0      _safeKeyFromJson (package:fast_immutable_collections/src/imap/imap.dart:1444:14)
#1      new IMap.fromJson.<anonymous closure> (package:fast_immutable_collections/src/imap/imap.dart:414:50)
#2      MapMixin.map (dart:collection/maps.dart:170:28)
#3      new IMap.fromJson (package:fast_immutable_collections/src/imap/imap.dart:413:12)
#4      _$TestClassFromJson (package:bug/main.g.dart:10:18)
#5      new TestClass.fromJson (package:bug/main.dart:25:7)
#6      main (package:bug/main.dart:9:13)

Minimal code:

dependencies:
  flutter:
    sdk: flutter

  fast_immutable_collections: ^7.3.1
  json_annotation: ^4.5.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  build_runner: ^2.1.11
  json_serializable: ^6.2.0
import 'dart:convert';

import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:json_annotation/json_annotation.dart';

part 'main.g.dart';

void main() {
  TestClass.fromJson(jsonDecode(jsonEncode(const TestClass(
    testField: IMapConst({
      TestEnum.testValue: true,
    }),
  ))));
}

@JsonSerializable()
class TestClass {
  final IMap<TestEnum, bool> testField;

  const TestClass({
    required this.testField,
  });

  factory TestClass.fromJson(Map<String, Object?> json) =>
      _$TestClassFromJson(json);

  Map<String, Object?> toJson() => _$TestClassToJson(this);
}

enum TestEnum {
  testValue,
}

App crashes when evaluating `toIList` expression in IntelliJ or VSCode using debugger

Put a breakpoint on line 14 and execute the code below using IntelliJ in debug mode:

import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final test = [1, 2].toIList();
    return Container();
  }
}

Execute test as expression in the “Variables” tab of the debugger window.
Notice that the app crashes without printing any exception.

Screenshot 2022-07-07 at 22 42 23

The same also happens when creating a watch on the test expression in VSCode.

Did crash on macOS, iPad, and Android. Did not test other platforms.
The same error also happens when calling toISet. Did not test with other methods.
Did not happen in Flutter < 3.x.x.

IntelliJ Version: 2022.1.3
Flutter Plugin Version: 69.0.4
Flutter Version: 3.0.4

Dart Error: error: illegal recursive type 'IMap<C1X0, C1X1>'

Error:

Launching lib/main.dart on sdk gphone64 x86 64 in debug mode...
lib/main.dart:1
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
E/flutter (15692): [ERROR:flutter/shell/common/shell.cc(93)] Dart Error: error: illegal recursive type 'IMap<C1X0, C1X1>'
E/flutter (15692): [ERROR:flutter/runtime/dart_isolate.cc(143)] Could not prepare isolate.
E/flutter (15692): [ERROR:flutter/runtime/dart_isolate.cc(1098)] error: illegal recursive type 'IMap<C1X0, C1X1>'
E/flutter (15692): [ERROR:flutter/runtime/runtime_controller.cc(385)] Could not create root isolate.
E/flutter (15692): [ERROR:flutter/shell/common/shell.cc(604)] Could not launch engine with configuration.3

Minimal code:

  flutter_riverpod: ^2.0.0-dev.9
  fast_immutable_collections: ^7.4.1
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';


/// Error: illegal recursive type 'IMap<C1X0, C1X1>'
class IdMapStateNotifier<T> extends StateNotifier<IMap<int, T>> {
  IdMapStateNotifier(super.initialState);

  // void addAll(IMap<int, Data> data) {
  //   state = state.addAll(data);
  // }

  // void removeAll(List<int> ids) {
  //   state = state.removeWhere((key, _) => ids.contains(key));
  // }
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
  
    return Scaffold(
      appBar: AppBar(
           title: Text(widget.title),
      ),
      body: Center(
         child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), 
    );
  }
}

flutter doctor:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.2, on Arch Linux 5.19.11-zen1-1-zen, locale zh_CN.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2021.2)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

ListMap: Does not implement operator==

I understand that it's mutable, unlike the others. However, considering that all other collections implement a proper operator ==, I expected ListMap to do the same.

Maybe we can make the documentation reflect that?

test('ListMap Equality', () {
    var map1 = ListMap.of({
      'b': 1,
      'a': 2,
    });

    var map2 = ListMap.of({
      'b': 1,
      'a': 2,
    });

    expect(map1, map2);
    expect(map1 == map2, true);
  });

The second expect fails.

ISet.difference does not always return the correct result

I wrote a small test for the problem:

import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter_test/flutter_test.dart';

enum SomeEnum { foo, bar }

const _sorted = ConfigSet(sort: true);

ISet<T> sortedEnumISet<T extends Enum>(Iterable<T> items) =>
    items is ISet<T> ? items.withConfig(_sorted) : ISet.withConfig(items, _sorted);

void main() {
  test('ISet.union(...).difference(...)', () {
    final emptySet1 = <SomeEnum>{}.lock;
    final emptySet2 = sortedEnumISet<SomeEnum>([]);
    final foo = sortedEnumISet([SomeEnum.foo]);
    expect(emptySet1.union(foo).difference(emptySet2), equals(foo));
  });
}

With fast_immutable_collections version 9.1.5 this test fails with the following output:

package:matcher                                     expect
package:flutter_test/src/widget_tester.dart 454:18  expect
test/fast_immutable_collections_test.dart 16:5      main.<fn>

Expected: ISetImpl<SomeEnum>:[SomeEnum:SomeEnum.foo]
  Actual: ISetImpl<SomeEnum>:[]
   Which: at location [0] is ISetImpl<SomeEnum>:[] which shorter than expected

I guess the cause of the problem is the different config of emptySet1 and emptySet2. However, I think the test should pass.

IList map to return IList rather than Iterable

Thanks for this library, it is helping improve state management for some of our more complex widgets.

What is the reasoning that an IList<T>.map returns an Iterable<T> rather than the more specific IList<T>? If we return another IList we can chain it with other methods and pass it around. I find myself having to explicitly call .toIList() every time anyway.

Use unsafe immutable collections for JSON parsing

When creating collections from JSON, the package is creating copies of the original collections when it doesn't have to.

For example, the IMap.fromJson constructor code:

factory IMap.fromJson(
  Map<String, Object?> json,
  K Function(Object?) fromJsonK,
  V Function(Object?) fromJsonV,
) =>
    json
        .map<K, V>(
            (key, value) => MapEntry(fromJsonK(_safeKeyFromJson<K>(key)), fromJsonV(value)))
        .lock;

Considering the fact that a new map is being created via .map, wouldn't it be safe to use .lockUnsafe here? (And in the other constructors IList and ISet as well.)

IMapOfSets throws Stack Overflow on 'forEach' after too many 'add's

[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: Stack Overflow
#0 FollowedByIterable.iterator (dart:_internal/iterable.dart:784:3)
#1 new FollowedByIterator (dart:_internal/iterable.dart:842:34)
#2 FollowedByIterable.iterator (dart:_internal/iterable.dart:784:35)
#3 new FollowedByIterator (dart:_internal/iterable.dart:842:34)
#4 FollowedByIterable.iterator (dart:_internal/iterable.dart:784:35)
#5 new FollowedByIterator (dart:_internal/iterable.dart:842:34)

JSON Serialization of IMap Keys

Because this uses toJsonK and fromJsonK, non-String keys don't automatically get converted to Strings in the toJson map output, and also don't get converted back from Strings in fromJson.

PR #25 is a temporary solution until json_serializable can detect and handle these cases.

Here is the json_serializable issue
google/json_serializable.dart#396

Sliding

Hi!

Did we forget sliding aka partition aka groupBy(size, offset) ?

ISortedSet

I was very happy to find that https://pub.dev/documentation/fast_immutable_collections/latest/fast_immutable_collections/ISet-class.html can be configured to be sorted. In practice though I'm finding it difficult to ensure that a property that is specified as ISet is forced to remain sorted.

@freezed
abstract class TimelineChartData with _$TimelineChartData {
  const TimelineChartData._();

  factory TimelineChartData({
    @required Extent<DateTime> focusedRange,
    @required ISet<GlucoseReading> glucoseReadings,
    @required ISet<InsulinInjection> insulinInjections,
  }) = _TimelineChartData;

  factory TimelineChartData.from({
    @required Extent<DateTime> focusedRange,
    @required TimelineDataBatch batch,
  }) {
    return TimelineChartData(
      focusedRange: focusedRange,
      glucoseReadings: ISet<GlucoseReading>.withConfig(
          batch.glucoseReadings, ConfigSet(sort: true)),
      insulinInjections: ISet<InsulinInjection>.withConfig(
          batch.insulinInjections, ConfigSet(sort: true)),
    );
  }
}

In this example you can see from the factory TimelineChartData.from that I want both glucoseReadings and insulinInjections to be sorted. The problem is that whenever I replace glucoseReadings or insulinInjections I need to remember to configure the ISet to be sorted. By introducing ISortedSet it would allow the compiler to enforce that the set remains sorted.

As an aside thankyou very much for this package, dart deserves a quality immutable package and FIC seems to fill this role very nicely.

Json Serialization Support

Looks great, just glanced through it and am interested in using it in some projects!

Just a question / feature request. Is there json serialization support?

See for example: json_serializable_immutable_collections which adds support for serializing other immutable collections to json and back.

Since the collections are iterables I'm sure they probably serialize fine without any issue. The problem is to deserialize them back to an immutable form.

Remove `////...` comments

Hello!

First of all, thank you for this excellent package. It is a total lifesaver.

There is a small issue with the documentation that can be easily removed. 5 classes have section dividers in their visible documentation. Because the dartdoc treats everything that goes after three slashes as a doc comment, dividers consisting of slashes end up in the visible documentation

The affected classes are: IList, IMap, IMapImpl, IMapOfSets, IMapOfSetsConst.

I will be more than happy to submit a PR :)

operations on IList.empty() (and others) do not work when modified

Hello again, I feel very sorry for discovering this issue only after the change has been made but the current implementation seems to be broken in a nearly identical way to as it has been described in the comment Note: The _list can't be optional. This doesn't work: [this._list = const []] because when you do this _list will be List<Never> which is bad. I guess that empty lists with a generic type can not be ever constant.

The error message i've got in my production flutter app was:
type 'List<Foo>' is not a subtype of type 'Iterable<Never>' of 'other' when trying to expand on a empty ilist that has been modified using .addAll()

Therefore my proposed solution would be to not instantiate a list for empty ILists at all and instead handle them as a specific type. The simplest solution i came up with looks like this:

@immutable
class IListEmpty<T> extends IList<T> {
  @literal
  const IListEmpty([this.config = const ConfigList()])
      : super._gen();

  @override
  final ConfigList config;

  /// A empty list is always flushed, by definition.
  @override
  bool get isFlushed => true;

  /// Nothing happens when you flush a empty list, by definition.
  @override
  IListEmpty<T> get flush => this;

  @override
  int get _counter => 0;

  @override
  L<T> get _l => LFlat<T>.unsafe([]);

  /// Hash codes must be the same for objects that are equal to each other
  /// according to operator ==.
  @override
  int? get _hashCode {
    return isDeepEquals
        ? hash2(const ListEquality<dynamic>().hash([]), config.hashCode)
        : hash2(identityHashCode(_l), config.hashCode);
  }

  @override
  set _hashCode(int? value) {}

  @override
  bool same(IList<T>? other) =>
      (other != null) &&
      (other is IListConst) &&
      identical([], (other as IListConst)._list) &&
      (config == other.config);
}

As i do not understand the inner workings of ICollections in detail, i guess that there is room for improvements, and i would happily implement them if you were to tell me what to do.

PR: #76

Undocumented classes

Hello!

There are three classes which purposes are not very clear.

Why are the classes L, M and S are publically exposed and what do they do?

IList.update

I'd like the method IList.update because I find myself often writing things like

myList.put(index, myFunction(myList.get(index)))

but it would be great to be able to write

myList.update(index, myFunction)

Suggestion: Use `@useResult` instead of `@useCopy` (or use both)

Consider the following example.

@immutable
class MessageThread {
  const MessageThread(this._messages);
  final IList<String> _messages;
  IList<String> get messages => _messages;
}

void main() {
  String aStringWithDots = "a.b.c";
  final bla = MessageThread(["a", "b", aStringWithDots].lock);
  debugPrint("This is a message thread: ${bla.messages}");
  bla.messages.add("d");
  debugPrint("This is a message thread: ${bla.messages}");
}

This is of course incorrect usage and the string d won't ever be added to the immutable list (it would be if you replaced IList with List).

However, if you would add the @useResult annotation to the add function it would look like this:

  /// Return a new list with [item] added to the end of the current list,
  /// (thus extending the [length] by one).
  @useCopy
  @useResult
  IList<T> add(T item) {
    final result = IList<T>._unsafe(_l.add(item), config: config);

and in the IDE you get a type notification for this:
image

Resolve warnings pointed out by dart analyzer

Issue

Warnings are shown on pub.dev and points on this package are reduced because some easy-to-fix problems are yet to be fixed.

image

Resolving these problems would raise the score and fame of this package as deserved.

Predicate

Would you accept a PR with
typedef Predicate<T> = bool Function(T element);

Replacing any form
T? firstWhereOrNull(bool Function(T) test)

with
T? firstWhereOrNull(Predicate<T> test)

Just for readability purposes.
Need to check but there should be no performances penalties.

Thx for the feedback

using lock as getter is an antipattern

Hello, I love this package but the lock extension is a misuse of getters. lock should be an alias of toIList() since it transforms the original list rather than return data related to it. Please consider deprecating the lock getter and replace it with a lock() method.

Own iterable Class with FromIterableIListMixin not iterable in Web

Hi,

i created my own iterable class:

import 'package:fast_immutable_collections/fast_immutable_collections.dart';


class MyIter with FromIterableIListMixin<String> implements Iterable<String>{

  MyIter([Iterable<String> strings]) : _strings = IList(strings);

  final IList<String> _strings;

  @override
  IList<String> get iter => _strings;
}

if i use this class inside a for loop e.g.:

for (final String letter in _myIter){ string += letter; }

this iterable works well on android emulator but if i use chrome it throws:

"TypeError: this[_myIter] is not iterable"

only if i write:
for (final String letter in _myIter.iter){ string += letter; }

it works. Did i do something wrong or is this a bug?

Remove Flutter Dependency

Is there a reason why the root package has a flutter dependency? This should be a pure dart package but pub.dev lists it as flutter only.

Dart-FP integration

Dart-FP => dfp

Open discussion for planning

For the first step can we consider a breaking change in FIC and plan a for 6.0 release ?

Is there some entites than we can remove from fic and depends directly on dfp ?
Maybe evolve dfp entities for some new requirements too ?

@SandroMaglione

Add firstWhereOrNull and lastWhereOrNull

Hi, thanks for the amazing package. I love using it and push it to as many project as I can.

Something I always miss are the methods firstWhereOrNull and lastWhereOrNull.

It's currently quite cumbersome to write equivalent code.

If I submit a PR, would that be something you would be willing to add?

Shouldn't IList.removeLast() returns the removed item?

Hi, first I want to thank you for the amazing work it was done in this package. I've been using it since 2.0.2 and really helped with my projects. I'm currently in 7.0.3 and in the docs, it says removeLast "Pops and returns the last object in this list...", but instead it returns the new IList.

IListConst.empty()

Currently I use the form const IListConst([]) but I would like to have a more expressive const IListConst.empty() to init my fields. Thoughts on this?

Const constructors?

I have immutable class with const constructor and all fields final. I don't want to make them nullable or required. Instead, I want to set default value in const constructor. With regular list, I can do that this way (myList field must be final):

const MyClass({
this.myList = const [],
});

But I can't do the same with your immutable list, because there's no const constructor. Is there any workaround for that? From some reasons, I don't want to make myList field nullable and also I don't want it to be required, I want to assign default value instead.

const IList, ISet, IMap etc?

class Sample {
  final Ilist<String> list;
  Sample({ this.list = const <String>[].lock});
}

all default values of constructor should be const , how can i set default value for IList ?

above code fails with Context: Extension operations can't be used in constant expressions.

IList `replaceFirstWhere` unnecessary nullable

from IList:

  @useCopy
  IList<T> replaceFirstWhere(
    bool Function(T item) test,
    T Function(T? item) replacement, { // here
    bool addIfNotFound = false,
  }) {
    final int index = indexWhere(test);
    return (index != -1)
        ? put(index, replacement(this[index])) // and here
        : addIfNotFound
            ? add(replacement(null))
            : this;
  }

there's no reason for replacement to have item as T? as we already guarantee the item exists, don't we?

IMapOfSets does not support json_serializable

To support the type `IMapOfSets` you can:
* Use `JsonConverter`
  https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html
* Use `JsonKey` fields `fromJson` and `toJson`
  https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
  https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html

Incompatible with json_serializable toJson/fromJson: issue _safeKeyFromJson

Hi

Thank you for the great package.

Issue:
I tried to use IMap<DateTime,something> with json_serializable 6.7.0 and FIC 9.1.5. Unfortunately I get a string casting error, probably the same issue as #39. Therefore I made a example with IMap, Map with DateTime and Enum as key.
I also made a example and tested the example with a suggested solution.

Problem:
The json_serializable converts the string in the desired type, while _safeKeyToJson tries again to convert the already converted type. In my case: instead of DateTime.parse(string) it will be DateTime.parse(DateTime) at this cause the casting error. (See generated code)

Suggestion for Solution
Because the type convertion is already done by json_serializable, a possible solution could be: removing _safeKeyFromJson. This works fine and is compatible with serializable and freezed package. (Could _safeKeyFromJson be a option {bool safeKey = false/true} ?)

Temperal fix:

factory IMap.fromJson(
    Map<String, Object?> json,
    K Function(Object?) fromJsonK,
    V Function(Object?) fromJsonV,
  ) =>
      json.map<K, V>(
          // (key, value) => MapEntry(fromJsonK(_safeKeyFromJson<K>(key)), fromJsonV(value)))
          (key, value) => MapEntry(fromJsonK(key), fromJsonV(value))).lockUnsafe;


Test Example
Convertion to json and back:

void main() {
  final TestMaps testMaps = TestMaps(
      iMap: {DateTime(2023, 6, 25): 'IMap<DateTime,String>'}.lock,
      map: {DateTime(2023, 6, 25): 'Map<DateTime,String>'},
      iEnumMap: {TestEnum.testValue: 'IMap<Enum,String>'}.lock,
      enumMap: {TestEnum.testValue: 'Map<Enum,String>'});

  final Map<String, dynamic> json = testMaps.toJson();

  final fromJsonTestMap = TestMaps.fromJson(json);

  print('Output test Imap:\n ${fromJsonTestMap.toString()}');
}
```

_TestMaps:_
```
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'example.g.dart';

enum TestEnum {
  testValue,
}

@JsonSerializable()
class TestMaps {
  /// The generated code assumes these values exist in JSON.
  final IMap<DateTime, String> iMap;
  final IMap<TestEnum, String> iEnumMap;
  final Map<DateTime, String> map;
  final Map<TestEnum, String> enumMap;

  TestMaps(
      {required this.iMap,
      required this.map,
      required this.iEnumMap,
      required this.enumMap});

  /// Connect the generated [_$PersonFromJson] function to the `fromJson`
  /// factory.
  factory TestMaps.fromJson(Map<String, dynamic> json) =>
      _$TestMapsFromJson(json);

  /// Connect the generated [_$PersonToJson] function to the `toJson` method.
  Map<String, dynamic> toJson() => _$TestMapsToJson(this);

  @override
  String toString() {
    return 'TestMaps(iMap: $iMap, iEnumMap: $iEnumMap, map: $map, enumMap: $enumMap)';
  }
}
```

```
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'example.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

TestMaps _$TestMapsFromJson(Map<String, dynamic> json) => TestMaps(
      iMap: IMap<DateTime, String>.fromJson(
          json['iMap'] as Map<String, dynamic>,
          (value) => DateTime.parse(value as String),
          (value) => value as String),
      map: (json['map'] as Map<String, dynamic>).map(
        (k, e) => MapEntry(DateTime.parse(k), e as String),
      ),
      iEnumMap: IMap<TestEnum, String>.fromJson(
          json['iEnumMap'] as Map<String, dynamic>,
          (value) => $enumDecode(_$TestEnumEnumMap, value),
          (value) => value as String),
      enumMap: (json['enumMap'] as Map<String, dynamic>).map(
        (k, e) => MapEntry($enumDecode(_$TestEnumEnumMap, k), e as String),
      ),
    );

Map<String, dynamic> _$TestMapsToJson(TestMaps instance) => <String, dynamic>{
      'iMap': instance.iMap.toJson(
        (value) => value.toIso8601String(),
        (value) => value,
      ),
      'iEnumMap': instance.iEnumMap.toJson(
        (value) => _$TestEnumEnumMap[value]!,
        (value) => value,
      ),
      'map': instance.map.map((k, e) => MapEntry(k.toIso8601String(), e)),
      'enumMap':
          instance.enumMap.map((k, e) => MapEntry(_$TestEnumEnumMap[k]!, e)),
    };

const _$TestEnumEnumMap = {
  TestEnum.testValue: 'testValue',
};
```

Use of Fast Immutable Collections with Freezed results in dynamic types

I'm using the fast_immutable_collections package with the freezed package in my Dart project. However, I noticed that when using IList or ISet with freezed, the generated code results in dynamic types.

For example, here's a simplified version of the code I'm using:

import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'my_class.freezed.dart';

@freezed
abstract class MyClass with _$MyClass {
  const factory MyClass({
    @Default(IListConst([])) IList<int> numbers,
  }) = _MyClass;
}

When running freezed to generate the code, the generated class for _MyClass has dynamic types instead of IList<int>.

abstract class _MyClass implements MyClass {
  const factory _MyClass({
    dynamic numbers, // Should be IList<int>
  }) = _$_MyClass;
}

This results in issues when trying to use the numbers property in my code, as I need it to be of type IList<int>.

However, I noticed that freezed works well with other generic types such as List or Test.

I'm wondering if this is expected behavior or if there's something I'm missing. Is there a way to use IList or ISet with freezed and still have the generated code use the correct types?

Thanks for your help!

Add useResult

As of meta: ^1.4.0 there is a new annotation called useResult that can be used to signal that a return value should not be discarded.

This will help users that are transitioning to immutable collections / learning how to use immutable collections.

For example a new user might think that:

final l = IList<int>();
l.add(0);
l.add(1);
print(l);

will print [0,1]
when actually it will print []

Adding this annotation will help newcomers on a project who aren't used to immutable collections or haven't read the documentation yet. You can even provide a reason statement:

@UseResult('You should always use the modified copy of the old list with the new item added')
IList<T> add(T item){
...
}

ListMap: forEach does not respect key order

Hello.

test('Key Order', () {
  var map = ListMap.of({
    'b': 1,
    'a': 2,
  });

  var str1 = "";
  map.forEach((key, value) => str1 += key);

  var str2 = "";
  for (var e in map.entries) {
    str2 += e.key;
  }
  expect(str1, str2);
});

forEach gives ab (incorrect)
for gives ba (correct)

Best Practices for Mutating Collections Multiple Times

I am working with the fast_immutable_collections package in Dart and have a question regarding the optimal way to handle multiple mutations on a collection. My goal is to understand the best practices for performance, especially in relation to the copy-on-write optimization that this package offers.

Here's the core of my query: When needing to mutate a collection multiple times, is it more efficient to unlock the collection, perform all mutations, and then lock it again, or should I simply use the immutable collection methods for each addition?

To give a concrete example, I am comparing these two approaches:

Approach 1: Unlocking and Locking

var nums = IList();
final newNums = nums.unlock;
for (var i = 0; i < 10; i++) {
  newNums.add(i);
}
nums = newNums.lock;

Approach 2: Using Immutable Collections

var nums = IList();
for (var i = 0; i < 10; i++) {
  nums = nums.add(i);
}

My concern is about the performance implications of these two methods, particularly regarding the copy-on-write feature. Does the first approach of unlocking and locking impact the optimization adversely? Or is it more efficient compared to adding items individually using immutable collection methods?

Any insights or recommendations on this would be greatly appreciated.

Thank you for your time and for maintaining this valuable package.

IHashMap Implementation

I am looking for an immutable version of Dart's HashMap (not the LinkedHashMap). Is there a reason why this package doesn't provide that? Can I reasonably assume that a HashMap variant would be more memory efficient than the current IMap based on a LinkedHashMap or is that not really the case?

IListConst when empty has not type

I wrote this code:

class Holder<T> {
  const Holder({this.items = const IListConst([])});

  final IList<T> items;
}

void main() {
  const holder = Holder<int>();
  holder.items.addAll([1, 2, 3]);
}

And I got the error: type 'List<int>' is not a subtype of type 'Iterable<Never>' of 'items'

Help me please! What am I doing wrong?

Fix CI/CD

CI/CD was being done with flutter test --coverage, and, since the removal of Flutter as a dependency to enable this package for everything Dart-related (#4), it's gonna be necessary to recreate it with only Dart. This is much more complicated, kt.dart has gone through a lot of hoops in order to achieve it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.