Coder Social home page Coder Social logo

davidmarne / dart_meta_types Goto Github PK

View Code? Open in Web Editor NEW
25.0 2.0 1.0 421 KB

a code gen solution for defining sealed classes, data classes, and enum classes for dart.

License: MIT License

Dart 100.00%
dart dartlang flutter algebraic-data-types data-class union-types value-types

dart_meta_types's Introduction

dart_meta_types

Pub

a code gen solution for defining sealed classes, data classes, and enum classes for dart. examples.

puropse

  • attempt to keep dart up to par with data types supported by kotlin.
  • provide means for defining algebreic data types in dart.
  • define patterns and apis for generating 3rd party mixins to provide additional functionality to generated models. e.g. meta_types_json.
  • support explicitly defining dataclasses as abstract, interface, extendable, and/or final. The generator can enforces strict practices for these concepts which dart-lang itself does not enforce.
  • provide means for representing non-nullable and nullable types in your data model.
  • provide means for meta-programming with your models without using dart:mirrors.

How to use meta_types

  • Define model definitions using annotations from the meta_types package.
  • Add meta_types_generator and build_runner to your dev_dependencies
  • generate code by running pub run build_runner run

See meta_types/example for examples on how to write model definitions.

One rule to follow

When writing class definitions ALWAYS use other class definitions when referencing other meta types. When writing code ALWAYS use the generated classes. Using the class definitons gives the generator the ability to resolve type information for classes that have not yet been generated.

For this reason, class definitions for public models should always be made public.

Note, this is different from other dart code gen solutions such as json_serializable and built_value, because the model definition is NOT used in your code. The generated classes are used directly in your code. This lets the generator generate constructors and additional fields and functions that are not present in the model definition, e.g. the clone method for data classes.

Types

  • All metatypes are hashable and comparable.
  • All meta_types extend from a base class that allow them to be used generically for metaprogramming.

For example, you can write a function that has in input of type DataClass which can be called with any data class. That function can use the accessors on DataClass to iterate over all the fields in the dataclass.

data classes

Data classes are immutable classes that only contain data. Dataclasses can be interfaces, abstract, extendable, or final. All generated models extend DataClass.

sealed classes

Sealed classes are immutable classes that have multiple fields, but only a single field can be set. Sealed classes cannot be extended or used as interfaces. All generated models extend SealedClass.

enum classes

Enum classes are classes that represent enumerations, using any type to represent the enumeration values. Enum classes cannot be extended or used as interfaces. All generated models extend EnumClass.

Example - Binary tree ADT using sealed and data classes

// model definitions

@SealedClass()
abstract class $BinaryTree<T> {
  T get leaf;
  $Branch<T> get branch;
}

@DataClass()
abstract class $Branch<T> {
  T get value;
  $BinaryTree<T> get left;
  $BinaryTree<T> get right;
}
// model usage

void preorderTraversal(BinaryTree<int> tree) => tree.when(
      leaf: (val) {
        print(val);
      },
      branch: (b) {
        print(b.value);
        preorderTraversal(b.left);
        preorderTraversal(b.right);
      },
    );

final tree = BinaryTree<int>.branchFactory(
  Branch(
    value: 1,
    left: BinaryTree.branchFactory(
      Branch(
        value: 2,
        left: BinaryTree.leafFactory(3),
        right: BinaryTree.leafFactory(4),
      ),
    ),
    right: BinaryTree.leafFactory(5),
  ),
);

// prints 1, 2, 3, 4, 5
preorderTraversal(tree);

Example: data class features

// model definition
@DataClass()
abstract class $ExampleDataClass {
  // fieldWithNoDefault is a field without a default value
  // the constructor will require a value be passed for this param
  int get fieldWithNoDefault;

  // fieldWithDefault uses a default value of 10 if
  // no other value is passed to the constructor
  int get fieldWithDefault => 10;

  // data class fields are not nullable, one must
  // use the Nullable class to represent nullable fields
  Nullable<int> get nullable;

  // computed fields memoize the result of the getter function
  @computed
  int get computedField => fieldWithDefault + 5;
}
// model usage

final d = ExampleDataClass(
  fieldWithNoDefault: 0,
  nullable: Nullable<int>.nil(),
);

print(d.fieldWithNoDefault); // 0
print(d.fieldWithDefault); // 10
print(d.nullable.value); // null
print(d.computedField); // 15

see more examples here

dart_meta_types's People

Contributors

davidmarne 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

Watchers

 avatar  avatar

Forkers

tvh

dart_meta_types's Issues

fromJson to Nullable<String>

Hi @davidmarne :) Thanks for this great lib!
I am playing with this lib and i am wondering how to map a Nullable property of a DataClass via .fromJson()

I always get "type 'String' is not a subtype of type 'Nullable' in type cast".
As far as i can tell, the generated code should create a Nullable instead of just cast to?

Memoize hash codes

Rather than recomputing hashcode every time it is called, cache the result and reuse it for future calls

what if i wanted just an array

@MetaJson()
@DataClass()
abstract class $CalendarResult {
  List<$CalendarItem> get items;
}

here is what happens

{
  "items: [{a: a},{b: b}]
}

but what if i wanted to do

[{a: a}, {b: b}]

how would I go about doing that? is it possible?

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.