Git Product home page Git Product logo

genq's Issues

JSON deserialization bug: double and int should be deserialized as num

Some languages will output json for doubles in a format that will break the current way genq is handling doubles and ints.

Ex:

{
     "someDoubleValue": 30.4,
     "anotherDoubleValue": 30,
     "someIntValue": 30,
}

This will break the deserialization when trying to use a double with "anotherDoubleValue".

Instead of generating the following
bodyFontSize: json['anotherDoubleValue'] == null ? null : json['anotherDoubleValue'] as double?

Follow JsonSerializableGenerator's lead on this and do
(json['anotherDoubleValue'] as num?)?.toDouble()

Possible to add a watcher?

Similar to how build_runner has a watch to rebuild when files change, is there something similar for genq?

Editor integrations

It would be nice if genq could run in editors when saving a file.

Integrations would be good for:

  • Visual Studio Code
  • Android Studio

Since genq is sufficiently fast, it should be possible to run genq before a file is saved, thus making the experience with Hot Reload/Hot Restart seamless.

Is there anyway to support a partial migration from freezed to genq

I work in a very big project and would like to eventually switch most of our data models with a few exceptions from freezed to genq.

However I am running into an issue with json serialization where all properties of genq data models must also be genq models. In a very big project this makes migrating difficult because it will be a big lift to migrate every single data model and even then there are models that need to stay in freezed.

Example:

@Genq(json: true)
class SomeGenqClass with _$SomeGenqClass {
  factory SomeGenqClass({
    required String value,
    required SomeFreezedClass someClass,
  }) = _SomeGenqClass;
}

@freezed
class SomeFreezedClass with _$SomeFreezedClass {
  const factory SomeFreezedClass({
    required String value,
  }) = _SomeFreezedClass;

  factory SomeFreezedClass.fromJson(Map<String, dynamic> json) =>
      _$SomeFreezedClassFromJson(json);
}

Gives an error that The function '$SomeFreezedClassFromJson' isn't defined.

Is there a way around this to make the migration easier?

Thanks

Hash code gen bug: Too many positional arguments

The hashcode function that gets generated cannot handle more than 20 arguments. Therefore once a class reaches over 20 properties this error occurs:

Error: Too many positional arguments: 20 allowed, but 21 found.
Try removing the extra positional arguments.
    return Object.hash(
                      ^
org-dartlang-sdk:///third_party/dart/sdk/lib/core/object.dart:183:14: Context: Found this candidate, but the arguments don't match.
  static int hash(Object? object1, Object? object2,

The way to fix this is to use

@override
int get hashCode => Object.hashAll([ <List of properties> ]);

instead of

@override
int get hashCode => Object.hash(<List of properties>);

[Question] Any best practices for parsing types like DateTime?

I read through the readme and I'm guessing using the @JsonKey() annotation with fromJson and toJson is the way to parse it.

I did something like this:

//Sample model
@Genq(json: true)
class MyModel with _$MyModel {
  factory MyModel({
    @JsonKey(
      fromJson: GenqDateTime.fromJson,
      toJson: GenqDateTime.toJson,
    )
    required GenqDateTime someDate,
  }) = _MyModel ;
}

//toJson fromJson
class GenqDateTime {
  final DateTime value;

  GenqDateTime(this.value);

  static GenqDateTime fromJson(String value) {
    final dateTime = DateTime.parse(value);
    return GenqDateTime(dateTime);
  }

  static String toJson(GenqDateTime enclosedDt) {
    return enclosedDt.value.toIso8601String();
  }
}

I'm just wondering if this is the right way to go about it? I use freezed normally so I got used to how it auto parses Strings into DateTime objects and just wondering if there's a way to do it without having to have a class enclosing a DateTime

I wanted to make the question more broad for other types but the only type I can think of is DateTime.

Edit: updated sample code

Regenerate the part classes when the files are saved

It's basically a file watcher detecting when a file contains the @genq annotations is saved.

I think it would improve the UX developer avoiding us to constantly switch between the Flutter bash and the genq bash

Add `JsonSerializable`-like annotation

A lot of existing dart code bases use vanilla json_serializable & json_annotation (https://pub.dev/packages/json_serializable), without any freezed. For classes marked with the annotation, the fields within the class will be considered for generating the serialization/deserialization code.

We could offer such an annotation, which is almost identical to the annotation from json_serializable (maybe @GenqJsonSerializable()). This should make migrations relatively trivial.

A limitation might be that genq has no ability to resolve inherited fields.

Support for const factory

Awesome package! Could you adjust it to support const factory constructors?

Ex:

@Genq(json: true)
class User with _$User {
  const factory User({
    @JsonKey(
      fromJson: UserName.fromJson,
      toJson: UserName.toJson,
    )
    required UserName name,
    required int age,
  }) = _User;
}

Thanks!

Add a model generator

Hi!

I just tried your tool and it's very great! I was wondering if it was possible to add a generator command line like in Ruby on Rails.

It would be something like genq generate User to generate the user.dart file with the basic template like in your README.

It would be useful to have this feature because there's no VSCode extension or snippets for that.

Not Dart compatible

Error when parsing: lib\features\auth\entities\app_theme.dart:13

final class AppTheme with _$AppTheme implements ISerializable, ICopyWith {
^
Unexpected token: FINAL (final). Expected CLASS.
โœ… Generated 0 data classes

Dart is not JavaScript, we have final, abstract interface, abstract base and sealed classes.

Support sealed classes

One change that would make genq an excellent freezed replacement would be to support unions with sealed classes.
Example

@genq
sealed class HomeState with _$HomeState {
  const factory HomeState.loading() = LoadingState;
  const factory HomeState.loaded(String data) = LoadedState;
  const factory HomeState.error(String message) = ErrorState;
}

It would be great if this was able to generate a sealed classes that could be used with dart's pattern matching. Here is more details on how this would be useful:
https://medium.com/@aliammariraq/sealed-classes-in-dart-unlocking-powerful-features-d8dba185925f

Is it possible to generate class methods?

Today we use freezed to generate some class methods like this:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'something_state.freezed.dart';

@freezed
class SomethingState with _$SomethingState {
  const factory SomethingState.initial() = _Initial;
  const factory SomethingState.loading() = _Loading;
  const factory SomethingState.invalid(String errorMessage) = _Invalid;
}
and freezed outputs:
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark

part of 'something_state.dart';

// **************************************************************************
// FreezedGenerator
// **************************************************************************

T _$identity<T>(T value) => value;

final _privateConstructorUsedError = UnsupportedError(
    'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');

/// @nodoc
mixin _$SomethingState {
  @optionalTypeArgs
  TResult when<TResult extends Object?>({
    required TResult Function() initial,
    required TResult Function() loading,
    required TResult Function(String errorMessage) invalid,
  }) =>
      throw _privateConstructorUsedError;
  @optionalTypeArgs
  TResult? whenOrNull<TResult extends Object?>({
    TResult? Function()? initial,
    TResult? Function()? loading,
    TResult? Function(String errorMessage)? invalid,
  }) =>
      throw _privateConstructorUsedError;
  @optionalTypeArgs
  TResult maybeWhen<TResult extends Object?>({
    TResult Function()? initial,
    TResult Function()? loading,
    TResult Function(String errorMessage)? invalid,
    required TResult orElse(),
  }) =>
      throw _privateConstructorUsedError;
  @optionalTypeArgs
  TResult map<TResult extends Object?>({
    required TResult Function(_Initial value) initial,
    required TResult Function(_Loading value) loading,
    required TResult Function(_Invalid value) invalid,
  }) =>
      throw _privateConstructorUsedError;
  @optionalTypeArgs
  TResult? mapOrNull<TResult extends Object?>({
    TResult? Function(_Initial value)? initial,
    TResult? Function(_Loading value)? loading,
    TResult? Function(_Invalid value)? invalid,
  }) =>
      throw _privateConstructorUsedError;
  @optionalTypeArgs
  TResult maybeMap<TResult extends Object?>({
    TResult Function(_Initial value)? initial,
    TResult Function(_Loading value)? loading,
    TResult Function(_Invalid value)? invalid,
    required TResult orElse(),
  }) =>
      throw _privateConstructorUsedError;
}

/// @nodoc
abstract class $SomethingStateCopyWith<$Res> {
  factory $SomethingStateCopyWith(
          SomethingState value, $Res Function(SomethingState) then) =
      _$SomethingStateCopyWithImpl<$Res, SomethingState>;
}

/// @nodoc
class _$SomethingStateCopyWithImpl<$Res, $Val extends SomethingState>
    implements $SomethingStateCopyWith<$Res> {
  _$SomethingStateCopyWithImpl(this._value, this._then);

  // ignore: unused_field
  final $Val _value;
  // ignore: unused_field
  final $Res Function($Val) _then;
}

/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
  factory _$$InitialImplCopyWith(
          _$InitialImpl value, $Res Function(_$InitialImpl) then) =
      __$$InitialImplCopyWithImpl<$Res>;
}

/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
    extends _$SomethingStateCopyWithImpl<$Res, _$InitialImpl>
    implements _$$InitialImplCopyWith<$Res> {
  __$$InitialImplCopyWithImpl(
      _$InitialImpl _value, $Res Function(_$InitialImpl) _then)
      : super(_value, _then);
}

/// @nodoc

class _$InitialImpl implements _Initial {
  const _$InitialImpl();

  @override
  String toString() {
    return 'SomethingState.initial()';
  }

  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        (other.runtimeType == runtimeType && other is _$InitialImpl);
  }

  @override
  int get hashCode => runtimeType.hashCode;

  @override
  @optionalTypeArgs
  TResult when<TResult extends Object?>({
    required TResult Function() initial,
    required TResult Function() loading,
    required TResult Function(String errorMessage) invalid,
  }) {
    return initial();
  }

  @override
  @optionalTypeArgs
  TResult? whenOrNull<TResult extends Object?>({
    TResult? Function()? initial,
    TResult? Function()? loading,
    TResult? Function(String errorMessage)? invalid,
  }) {
    return initial?.call();
  }

  @override
  @optionalTypeArgs
  TResult maybeWhen<TResult extends Object?>({
    TResult Function()? initial,
    TResult Function()? loading,
    TResult Function(String errorMessage)? invalid,
    required TResult orElse(),
  }) {
    if (initial != null) {
      return initial();
    }
    return orElse();
  }

  @override
  @optionalTypeArgs
  TResult map<TResult extends Object?>({
    required TResult Function(_Initial value) initial,
    required TResult Function(_Loading value) loading,
    required TResult Function(_Invalid value) invalid,
  }) {
    return initial(this);
  }

  @override
  @optionalTypeArgs
  TResult? mapOrNull<TResult extends Object?>({
    TResult? Function(_Initial value)? initial,
    TResult? Function(_Loading value)? loading,
    TResult? Function(_Invalid value)? invalid,
  }) {
    return initial?.call(this);
  }

  @override
  @optionalTypeArgs
  TResult maybeMap<TResult extends Object?>({
    TResult Function(_Initial value)? initial,
    TResult Function(_Loading value)? loading,
    TResult Function(_Invalid value)? invalid,
    required TResult orElse(),
  }) {
    if (initial != null) {
      return initial(this);
    }
    return orElse();
  }
}

abstract class _Initial implements SomethingState {
  const factory _Initial() = _$InitialImpl;
}

/// @nodoc
abstract class _$$LoadingImplCopyWith<$Res> {
  factory _$$LoadingImplCopyWith(
          _$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
      __$$LoadingImplCopyWithImpl<$Res>;
}

/// @nodoc
class __$$LoadingImplCopyWithImpl<$Res>
    extends _$SomethingStateCopyWithImpl<$Res, _$LoadingImpl>
    implements _$$LoadingImplCopyWith<$Res> {
  __$$LoadingImplCopyWithImpl(
      _$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
      : super(_value, _then);
}

/// @nodoc

class _$LoadingImpl implements _Loading {
  const _$LoadingImpl();

  @override
  String toString() {
    return 'SomethingState.loading()';
  }

  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        (other.runtimeType == runtimeType && other is _$LoadingImpl);
  }

  @override
  int get hashCode => runtimeType.hashCode;

  @override
  @optionalTypeArgs
  TResult when<TResult extends Object?>({
    required TResult Function() initial,
    required TResult Function() loading,
    required TResult Function(String errorMessage) invalid,
  }) {
    return loading();
  }

  @override
  @optionalTypeArgs
  TResult? whenOrNull<TResult extends Object?>({
    TResult? Function()? initial,
    TResult? Function()? loading,
    TResult? Function(String errorMessage)? invalid,
  }) {
    return loading?.call();
  }

  @override
  @optionalTypeArgs
  TResult maybeWhen<TResult extends Object?>({
    TResult Function()? initial,
    TResult Function()? loading,
    TResult Function(String errorMessage)? invalid,
    required TResult orElse(),
  }) {
    if (loading != null) {
      return loading();
    }
    return orElse();
  }

  @override
  @optionalTypeArgs
  TResult map<TResult extends Object?>({
    required TResult Function(_Initial value) initial,
    required TResult Function(_Loading value) loading,
    required TResult Function(_Invalid value) invalid,
  }) {
    return loading(this);
  }

  @override
  @optionalTypeArgs
  TResult? mapOrNull<TResult extends Object?>({
    TResult? Function(_Initial value)? initial,
    TResult? Function(_Loading value)? loading,
    TResult? Function(_Invalid value)? invalid,
  }) {
    return loading?.call(this);
  }

  @override
  @optionalTypeArgs
  TResult maybeMap<TResult extends Object?>({
    TResult Function(_Initial value)? initial,
    TResult Function(_Loading value)? loading,
    TResult Function(_Invalid value)? invalid,
    required TResult orElse(),
  }) {
    if (loading != null) {
      return loading(this);
    }
    return orElse();
  }
}

abstract class _Loading implements SomethingState {
  const factory _Loading() = _$LoadingImpl;
}

/// @nodoc
abstract class _$$InvalidImplCopyWith<$Res> {
  factory _$$InvalidImplCopyWith(
          _$InvalidImpl value, $Res Function(_$InvalidImpl) then) =
      __$$InvalidImplCopyWithImpl<$Res>;
  @useResult
  $Res call({String errorMessage});
}

/// @nodoc
class __$$InvalidImplCopyWithImpl<$Res>
    extends _$SomethingStateCopyWithImpl<$Res, _$InvalidImpl>
    implements _$$InvalidImplCopyWith<$Res> {
  __$$InvalidImplCopyWithImpl(
      _$InvalidImpl _value, $Res Function(_$InvalidImpl) _then)
      : super(_value, _then);

  @pragma('vm:prefer-inline')
  @override
  $Res call({
    Object? errorMessage = null,
  }) {
    return _then(_$InvalidImpl(
      null == errorMessage
          ? _value.errorMessage
          : errorMessage // ignore: cast_nullable_to_non_nullable
              as String,
    ));
  }
}

/// @nodoc

class _$InvalidImpl implements _Invalid {
  const _$InvalidImpl(this.errorMessage);

  @override
  final String errorMessage;

  @override
  String toString() {
    return 'SomethingState.invalid(errorMessage: $errorMessage)';
  }

  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        (other.runtimeType == runtimeType &&
            other is _$InvalidImpl &&
            (identical(other.errorMessage, errorMessage) ||
                other.errorMessage == errorMessage));
  }

  @override
  int get hashCode => Object.hash(runtimeType, errorMessage);

  @JsonKey(ignore: true)
  @override
  @pragma('vm:prefer-inline')
  _$$InvalidImplCopyWith<_$InvalidImpl> get copyWith =>
      __$$InvalidImplCopyWithImpl<_$InvalidImpl>(this, _$identity);

  @override
  @optionalTypeArgs
  TResult when<TResult extends Object?>({
    required TResult Function() initial,
    required TResult Function() loading,
    required TResult Function(String errorMessage) invalid,
  }) {
    return invalid(errorMessage);
  }

  @override
  @optionalTypeArgs
  TResult? whenOrNull<TResult extends Object?>({
    TResult? Function()? initial,
    TResult? Function()? loading,
    TResult? Function(String errorMessage)? invalid,
  }) {
    return invalid?.call(errorMessage);
  }

  @override
  @optionalTypeArgs
  TResult maybeWhen<TResult extends Object?>({
    TResult Function()? initial,
    TResult Function()? loading,
    TResult Function(String errorMessage)? invalid,
    required TResult orElse(),
  }) {
    if (invalid != null) {
      return invalid(errorMessage);
    }
    return orElse();
  }

  @override
  @optionalTypeArgs
  TResult map<TResult extends Object?>({
    required TResult Function(_Initial value) initial,
    required TResult Function(_Loading value) loading,
    required TResult Function(_Invalid value) invalid,
  }) {
    return invalid(this);
  }

  @override
  @optionalTypeArgs
  TResult? mapOrNull<TResult extends Object?>({
    TResult? Function(_Initial value)? initial,
    TResult? Function(_Loading value)? loading,
    TResult? Function(_Invalid value)? invalid,
  }) {
    return invalid?.call(this);
  }

  @override
  @optionalTypeArgs
  TResult maybeMap<TResult extends Object?>({
    TResult Function(_Initial value)? initial,
    TResult Function(_Loading value)? loading,
    TResult Function(_Invalid value)? invalid,
    required TResult orElse(),
  }) {
    if (invalid != null) {
      return invalid(this);
    }
    return orElse();
  }
}

abstract class _Invalid implements SomethingState {
  const factory _Invalid(final String errorMessage) = _$InvalidImpl;

  String get errorMessage;
  @JsonKey(ignore: true)
  _$$InvalidImplCopyWith<_$InvalidImpl> get copyWith =>
      throw _privateConstructorUsedError;
}

Is it possible to use genq to do the same?

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.