freezed 0.0.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 91

Build Status pub package

Welcome to Freezed, yet another code generator for immutable classes / sealed classes / union types / copy.

Motivation #

While there are many code-generators available to help you deal with immutable objects, they usually come with a trade-off.
Either they have a simple syntax but lack in feature, or they have very advanced features but with a complex syntax.

A typical example would be a "clone" method.
Current generators have two approaches:

  • a copyWith, usually implemented using ??:

    MyClass copyWith({ int a, String b }) {
        return MyClass(a: a ?? this.a, b: b ?? this.b);
    }
    

    The syntax is very simple to use, but doesn't support some use-cases: nullable values.
    We cannot use such copyWith to assign null to a property like so:

    person.copyWith(location: null)
    
  • a builder method combined with a temporary mutable object, usually used this way:

    person.rebuild((person) {
      return person
        ..b = person;
    })
    

    The benefits of this approach is that it does support nullable values.
    On the other hand, the syntax is not very readable and fun to use.

Say hello to Freezed~, with a support for advanced use-cases without compromising on the syntax.

See the example or the index for a preview on what's available

Index #

How to use #

0.0.0 #

Initial release

example/lib/main.dart

import 'package:flutter/foundation.dart';

part 'main.g.dart';

@immutable
abstract class MyClass with _$MyClass {
  factory MyClass({String a, int b}) = _MyClass;
}

@immutable
abstract class Union with _$Union {
  const factory Union(int value) = Data;
  const factory Union.loading() = Loading;
  const factory Union.error([String message]) = ErrorDetails;
  const factory Union.complex(int a, String b) = Complex;
}

@immutable
abstract class SharedProperty with _$SharedProperty {
  factory SharedProperty.person({String name, int age}) = SharedProperty0;
  factory SharedProperty.city({String name, int population}) = SharedProperty1;
}

void main() {
  final myClassexample = MyClass(a: '42', b: 42);

  // clone
  print(myClassexample.copyWith(a: null)); // MyClass(a: null, b: 42)
  print(myClassexample.copyWith()); // MyClass(a: '42', b: 42)

  // ------------------

  // == override
  print(MyClass(a: '42', b: 42) == MyClass(a: '42', b: 42)); // true
  print(MyClass(a: '42', b: 42) == MyClass()); // false

  // ------------------

  // destructuring pattern-matching
  const unionExample = Union(42);
  print(
    // `when` requires all callbacks to be not null
    unionExample.when(
      (value) => '$value',
      loading: () => 'loading',
      error: (message) => 'Error: $message',
      complex: (a, b) => 'complex $a $b',
    ),
  ); // 42

  print(
    // maybeWhen allows some callbacks to be missing, but requires an `orElse` callback
    unionExample.maybeWhen(
      null,
      loading: () => 'loading',
      // voluntarily didn't pass error/complex callbacks
      orElse: () => 42,
    ),
  ); // 42

  // ------------------

  // non-destructuring pattern-matching
  // works the same as `when`, but the callback is slightly different
  print(
    // `map` requires all callbacks to be not null
    unionExample.map(
      (Data value) => '$value',
      loading: (Loading value) => 'loading',
      error: (ErrorDetails error) => 'Error: ${error.message}',
      complex: (Complex value) => 'complex ${value.a} ${value.b}',
    ),
  ); // 42

  print(
    // maybeWhen allows some callbacks to be missing, but requires an `orElse` callback
    unionExample.maybeMap(
      null,
      error: (ErrorDetails value) => value.message,
      // voluntarily didn't pass error/complex callbacks
      orElse: () => null,
    ),
  ); // fallthrough

  // ------------------

  // nice toString
  print(const Union(42)); // Union(value: 42)
  print(const Union.loading()); // Union.loading()
  print(const Union.error('Failed to fetch')); // Union.error(message: Failed to fetch)

  // ------------------

  // shared properties between union possibilities
  var example = SharedProperty.person(name: 'Remi', age: 24);
  // OK, `name` is shared between both .person and .city constructor
  print(example.name); // Remi
  example = SharedProperty.city(name: 'London', population: 8900000);
  print(example.name); // London

  // COMPILE ERROR
  // print(example.age);
  // print(example.population);
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  freezed: ^0.0.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:freezed/builder.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
88
Health:
Code health derived from static analysis. [more]
96
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
90
Overall:
Weighted score of the above. [more]
91
Learn more about scoring.

We analyzed this package on Mar 25, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6

Health suggestions

Fix lib/src/templates/concrete_template.dart. (-1.99 points)

Analysis of lib/src/templates/concrete_template.dart reported 4 hints:

line 129 col 9: DO use curly braces for all flow control structures.

line 131 col 9: DO use curly braces for all flow control structures.

line 163 col 7: DO use curly braces for all flow control structures.

line 165 col 7: DO use curly braces for all flow control structures.

Fix lib/src/generator.dart. (-1.49 points)

Analysis of lib/src/generator.dart reported 3 hints:

line 40 col 99: 'name' is deprecated and shouldn't be used. Check element, or use getDisplayString().

line 60 col 103: 'name' is deprecated and shouldn't be used. Check element, or use getDisplayString().

line 63 col 55: 'name' is deprecated and shouldn't be used. Check element, or use getDisplayString().

Fix lib/src/templates/parameter_template.dart. (-1 points)

Analysis of lib/src/templates/parameter_template.dart reported 2 hints:

line 17 col 25: 'displayName' is deprecated and shouldn't be used. Use getDisplayString instead.

line 25 col 23: 'displayName' is deprecated and shouldn't be used. Use getDisplayString instead.

Format lib/src/templates/prototypes.dart.

Run dartfmt to format lib/src/templates/prototypes.dart.

Maintenance suggestions

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.7.0 <3.0.0
analyzer ^0.39.0 0.39.4
build >=0.12.6 <2.0.0 1.2.2
build_config >=0.2.6 <0.5.0 0.4.2
meta ^1.1.0 1.1.8
source_gen ^0.9.0 0.9.5
Transitive dependencies
_fe_analyzer_shared 1.0.3
args 1.6.0
async 2.4.1
charcode 1.1.3
checked_yaml 1.0.2
collection 1.14.12
convert 2.1.1
crypto 2.1.4
csslib 0.16.1
dart_style 1.3.3
glob 1.2.0
html 0.14.0+3
js 0.6.1+1
json_annotation 3.0.1
logging 0.11.4
node_interop 1.0.3
node_io 1.0.1+2
package_config 1.9.2
path 1.6.4
pedantic 1.9.0
pub_semver 1.4.4
pubspec_parse 0.1.5
source_span 1.7.0
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
watcher 0.9.7+14
yaml 2.2.0
Dev dependencies
build_runner ^1.0.0
build_test ^0.10.11
matcher ^0.12.6
source_gen_test ^0.1.0
test ^1.6.0