Closed astralstriker closed 4 years ago
isn't DataField('todos', List<String>),
working?
isn't
DataField('todos', List<String>),
working?
Currently, the dart compiler takes <> as two separate parts. It complains that The operator '<' isn't defined for the class 'Type'
. So we thought of creating two new field type for List and Map each.
Reworked the syntax for providing datafield type. Instead of doing, or rather trying to do in some cases,
DataField('foo1', int),
DataField('foo2', List<int>),
DataField('foo3', BuiltList<int>),
DataField('fooMap', Map<int, String>)
We shall now follow the much better and more comprehensive way -
DataField<int>('foo1'),
DataField<List<int>>('foo2'),
DataField<BuiltList<int>>('foo3'),
DataField<Map<int, String>>('fooMap')
PS: I am yet to push the changes to this PR.
The above mentioned syntax allows us to specify the generic types and saves us the effort for creating parsers for specific generic types viz lists, maps etc.
The absolute generics (T) still works the old way -
DataField<Generic>('genericTodo')
As there is no way to make the enum Generic.
Example:
@superEnum
enum _TodoResponse {
@Data(fields: [
DataField<int>('count'),
DataField<List<String>>('todos'),
DataField<Map<String, Object>>('objectMap'),
])
TodoSuccess,
@Data(fields: [
DataField<Generic>('todo'),
DataField<List<Generic>>('todoList'),
DataField<Map<int, Generic>>('todoMap'),
])
@generic
GenericTodo,
@object
TodoError
}
Generated file:
@immutable
abstract class TodoResponse<T> extends Equatable {
const TodoResponse(this._type);
factory TodoResponse.todoSuccess(
{@required int count,
@required List<String> todos,
@required Map<String, Object> objectMap}) = TodoSuccess<T>;
factory TodoResponse.genericTodo(
{@required T todo,
@required List<T> todoList,
@required Map<int, T> todoMap}) = GenericTodo<T>;
factory TodoResponse.todoError() = TodoError<T>;
final _TodoResponse _type;
//ignore: missing_return
FutureOr<R> when<R>(
{@required FutureOr<R> Function(TodoSuccess) todoSuccess,
@required FutureOr<R> Function(GenericTodo) genericTodo,
@required FutureOr<R> Function(TodoError) todoError}) {
assert(() {
if (todoSuccess == null || genericTodo == null || todoError == null) {
throw 'check for all possible cases';
}
return true;
}());
switch (this._type) {
case _TodoResponse.TodoSuccess:
return todoSuccess(this as TodoSuccess);
case _TodoResponse.GenericTodo:
return genericTodo(this as GenericTodo);
case _TodoResponse.TodoError:
return todoError(this as TodoError);
}
}
FutureOr<R> whenOrElse<R>(
{FutureOr<R> Function(TodoSuccess) todoSuccess,
FutureOr<R> Function(GenericTodo) genericTodo,
FutureOr<R> Function(TodoError) todoError,
@required FutureOr<R> Function(TodoResponse) orElse}) {
assert(() {
if (orElse == null) {
throw 'Missing orElse case';
}
return true;
}());
switch (this._type) {
case _TodoResponse.TodoSuccess:
if (todoSuccess == null) break;
return todoSuccess(this as TodoSuccess);
case _TodoResponse.GenericTodo:
if (genericTodo == null) break;
return genericTodo(this as GenericTodo);
case _TodoResponse.TodoError:
if (todoError == null) break;
return todoError(this as TodoError);
}
return orElse(this);
}
FutureOr<void> whenPartial(
{FutureOr<void> Function(TodoSuccess) todoSuccess,
FutureOr<void> Function(GenericTodo) genericTodo,
FutureOr<void> Function(TodoError) todoError}) {
assert(() {
if (todoSuccess == null && genericTodo == null && todoError == null) {
throw 'provide at least one branch';
}
return true;
}());
switch (this._type) {
case _TodoResponse.TodoSuccess:
if (todoSuccess == null) break;
return todoSuccess(this as TodoSuccess);
case _TodoResponse.GenericTodo:
if (genericTodo == null) break;
return genericTodo(this as GenericTodo);
case _TodoResponse.TodoError:
if (todoError == null) break;
return todoError(this as TodoError);
}
}
@override
List get props => const [];
}
@immutable
class TodoSuccess<T> extends TodoResponse<T> {
const TodoSuccess(
{@required this.count, @required this.todos, @required this.objectMap})
: super(_TodoResponse.TodoSuccess);
final int count;
final List<String> todos;
final Map<String, Object> objectMap;
@override
String toString() =>
'TodoSuccess(count:${this.count},todos:${this.todos},objectMap:${this.objectMap})';
@override
List get props => [count, todos, objectMap];
}
@immutable
class GenericTodo<T> extends TodoResponse<T> {
const GenericTodo(
{@required this.todo, @required this.todoList, @required this.todoMap})
: super(_TodoResponse.GenericTodo);
final T todo;
final List<T> todoList;
final Map<int, T> todoMap;
@override
String toString() =>
'GenericTodo(todo:${this.todo},todoList:${this.todoList},todoMap:${this.todoMap})';
@override
List get props => [todo, todoList, todoMap];
}
@immutable
class TodoError<T> extends TodoResponse<T> {
const TodoError._() : super(_TodoResponse.TodoError);
factory TodoError() {
_instance ??= TodoError._();
return _instance;
}
static TodoError _instance;
}
Commit pushed!
Reworked the syntax for providing datafield type. Instead of doing, or rather trying to do in some cases,
DataField('foo1', int), DataField('foo2', List<int>), DataField('foo3', BuiltList<int>), DataField('fooMap', Map<int, String>)
We shall now follow the much better and more comprehensive way -
DataField<int>('foo1'), DataField<List<int>>('foo2'), DataField<BuiltList<int>>('foo3'), DataField<Map<int, String>>('fooMap')
PS: I am yet to push the changes to this PR.
Loved the syntax :100:
@astralstriker resolve conflicts and push again :+1:
Got it
@astralstriker fix the CI checks please
@passsy please review
Solves #30
Usage :
Generated File :