Coder Social home page Coder Social logo

cast's Introduction

This is a prototype of what a deep cast package might look like.

Usage

Simple schema

Simple schema can be defined and used like this:

  // Lists
  const schema = cast.List(cast.int);
  List<dynamic> someList = ....;
  // Inferred type is List<String>, runtime reified type is List<String>
  var typedList = schema.cast(someList);  
  // Maps
  const schema = cast.Map(cast.String, cast.int);
  Map<dynamic, dynamic> someMap = ....;
  // Inferred type is Map<String, int>, runtime reified type is Map<String, int>
  var typedMap = schema.cast(someMap);

Casts can be applied arbitrarily deep:

  // Maps
  const schema = cast.Map(cast.String, cast.List(cast.int));
  Map<dynamic, dynamic> someMap = ....;
  // Inferred type is Map<String, List<int>>, 
  // runtime reified type is Map<String, List<int>>
  var typedMap = schema.cast(someMap);
  // Inferred type is List<int>, 
  // runtime reified type is List<int>
  var typedList = typedMap["field"];

Structured schema

Complex schemas with different types for different fields can also be defined:

   const typed = cast.Keyed<String, dynamic>({
      "id": cast.int,
      "fields": cast.Keyed({"field1": cast.int, "field2": cast.int}),
      "extra1": cast.OneOf(cast.String, cast.List(cast.String)),
      "extra2": cast.OneOf(cast.String, cast.List(cast.String)),
    });

Given structured data matching that schema:

 var json = <String, dynamic>{
    "id": 0,
    "fields": <String, dynamic>{"field1": 1, "field2": 2},
    "extra1": "hello",
    "extra2": <dynamic>["hello"],
  };

Applying the cast gives back a deeply cast object of the right type:

Map<String, dynamic> result = typed.cast(json);
Map<String, int> fields = result["fields"]; // Implicit cast will not fail

cast's People

Contributors

leafpetersen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

cast's Issues

Add cast.any

There should be a cast.any which just silently accepts.

Meta issue for discussion of a debug API

Should there be a separate debug version of the classes? I deliberately avoided keeping a full trace of the path through the tree to the current parse point, since that requires allocation and/or putting handlers at every step. For performance, we should probably avoid that, at least in production. We could do nasty things with asserts, but it might be better to provide a separate version of the library cast_debug.dart that extends each class and intercepts the _cast calls to keep a stack. Is this necessary, or can we give good enough error messages without this?

Meta issue for discussion of a lazy API

Do we need to provide lazy casting/parsing? That is, instead of eagerly casting, instead return delegating (and probably memoizing) implementations of the returned type that only cast on reads.

It's not clear that laziness makes sense for the parsing case, but it's possible. For the cast conversion case, converting lazily would be beneficial when reads are sparse, but harmful when reads are dense.

Meta issue for discussion of this approach and API.

This is an attempt to flesh out an idea that I've kicked around with a number of people to address the difficulty of interacting with untyped structured data in Dart 2. The canonical example is interacting with json, where the result of parsing is a large untyped blob of data that the user wants to be able to interact with in a typed way. This also arises with RPC calls in flutter, and also has come up with yaml.

See README for some examples of how this API would be used, as well as the test files.

Currently all that this provides is casting, but if the API turns out to work well, I would like us to explore using the schema to drive json and yaml parsing directly. That is, instead of parsing into untyped data and then casting, consider using the schema in the parser/RPC call/whatever to generate code with the expected reified type directly.

This meta issue is for discussion of the general idea of the API, as well as specifics around naming, missing functionality, etc.

I'll file a few specific sub-issues for additional discussions around the following:

  • Should there be an incremental version of the API: #2
  • Should there be a lazy version of the API: #3
  • Should there be a debug version of the API: #4

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.