ebisu_pod 0.0.10

  • README.md
  • Installing
  • Versions
  • 18

Ebisu Pod


Build Status

Dart modeling for Plain Old Data


A general purpose recursive design pattern for modeling plain old data components. Think IDL, or json schema but only covering the basic data modeling of scalars, arrays, and dictionaries (a.k.a. objects).

The goal is a simple modeling API that can then be used as inputs to code generators.

A Simple Modeling Library

If you have experience with any interface definition languages or IDLs (CORBA, Apache Thrift, Google Protocol Buffers, etd), this should feel familar. Since these ebisu projects are about code generation, rather than commit to an existing IDL, which usually entails its own code generation solution, the approach taken here is the typical extra level of indirection. We pull some of the common IDL features into the library and then support modeling with declarative instantiations of that meta-data. The process of creating a PodPackage is analagous to creating an instance of an IDL. The benefit of this approach include:

  • Competitive Selection: Decisions on serialization solutions can be informed by having multiple approaches tried against the same data set.

  • Additivie: Single source for multiple needs. For example, generate mongo bson serialization for mongo as well as msgpack serialization for network communication.

  • Programatic Control: Because the meta-language is implemented with a library programatic creation of large-scale models from structured data sets is simplified.

  • Model Interogation: Since the model is stored in Dart and accessible via dart, you can easily query/iterate on types, generate diagrams, etc.


All types support the [PodType] interface.

User Defined Data Types

User's may defined two types of data type:

| Type      | Description                      |
| PodEnum   | An enumerated type               |
| PodObject | An object type with named fields |

These types are created with an [Id] instance identifying the type.

| Built-In Type | Literal Name |
| StrType       | Str          |
| BooleanType   | Boolean      |
| DoubleType    | Double       |
| Int8Type      | Int8         |
| Int16Type     | Int16        |
| Int32Type     | Int32        |
| Int64Type     | Int64        |
| Uint8Type     | Uint8        |
| Uint16Type    | Uint16       |
| Uint32Type    | Uint32       |
| Uint64Type    | Uint64       |
| DateType      | Date         |
| DateTimeType  | DateTime     |
| TimestampType | Timestamp    |
| RegexType     | Regex        |

For these built-in types, there is an actual Dart type (e.g. Int32Type) and a single instance of that type (e.g. Int32) that may be used in declarations.

A Few Functions

Because the modeling language is a Dart library and not a DSL, the creation of new types and fields is acheived with functions.

  • object(id, [fields]): Create a named object with a list of fields
  • field(id, [podType]): Create a named field within an object
  • array(referredType): Create an array of referredType
  • package(packageName, imports, namedTypes): Create a package of types
object('point', [
  field('x', Int32),
  field('y', Int32)

This defines a POD object called point with two fields, x of type Int32 and y of type Int32.

Reference To Other Types

The [PodArrayType] requires a reference to the type of elements in the array. Since the [PodArrayType] models a reference to a single type it is necessarily a homogeneous collection. To enable the same type to be referenced in multiple other types without redefining it, it is convenient to be able to able to reference other types by name. Therefore, the podType argument to the field function may be either an actual PodType (e.g. Int32 or some user defined type) or it may be a literal string that references another type.

Scale With Packages

As projects grow it can be useful to not require all object types to be within the same file. The typical approach to supporting this requirement is to allow the grouping of types into packages and allow fields and arrays to refer to other types, both within their package and without.

Package Name Convention

Packages are named with the familar dotted-name notation.

Type references use the same notation.

  namedTypes: [
    object('player_stats', [
      field('unforced_errors', Int32),
      field('batting_average', Double),
    object('player_stat', [
      field('player'),                       // type unspecified defaults to [Str]
      field('player_stats', 'player_stats')
    object('player_stats_map', [
      field('pairs', 'player_stat')

Variable Size Types

These types may have a variable number of elements:

  • Str(N): characters for [StrType]
  • BinaryData(N): bytes for [BinaryDataType]
  • PodArray(N): instances of some referencedType, which is a [PodType]

For modeling purposes, these types support specification of maxLength which may enable optimizations on the serialization end.

Support For Recursive Models

object('person', [
  field('children', array('person'))  // Types may be referenced by name (ie literal string)


Balance Sheet

The following declarative ebisu_pod dart code models a few simple types from a balance sheet.

final balanceSheet = new PodPackage('bs.balance_sheet', namedTypes: [
  enum_('holding_type', ['other', 'stock', 'bond', 'cash', 'blend',])
    ..doc = '''
Is the holding stock (equity), bond, cash, some blend of those or other.''',
  enum_('account_type', [
  ])..doc = 'Type of account',
  object('date_value', [field('date', Date), field('value', Double)]),
  object('holding', [
    field('holding_type', 'holding_type')..doc = 'Type of the holding',
    field('quantity', 'date_value')..doc = 'Quantity as of the date',
    field('unit_value', 'date_value')..doc = 'Unit value as of the date',
    field('cost_basis', Double),
    ..doc = '''
The holding for a given symbol (or a sythetic aggregate as in an account other_holdings).

Both quantity and unitValue have dates associated with them. The marketValue of
the holding is based on the latest date of the two. This date can be different
(most likely older) than the date associated with the BalanceSheet owning the
    ..doc =
        'The map of holdings indexed by symbol (or similar name unique to the portfolio).'
    ..fields = [
      field('account_type', 'account_type')
        ..doc = 'Type of the portfolio account',
      field('descr')..doc = 'Description of the account',
      field('stout', Boolean)..doc = 'Is it a beefy account',

And here is the generated C++ for msgpack See ebisu_msgpack:


#include "ebisu/utils/block_indenter.hpp"
#include "msgpack.hpp"
#include <boost/date_time/gregorian/gregorian.hpp>
#include <iosfwd>
#include <string>

namespace bs {
namespace balance_sheet {
enum class Holding_type {

inline char const* to_c_str(Holding_type e) {
  switch(e) {
    case Holding_type::Other_e: return "Other_e";
    case Holding_type::Stock_e: return "Stock_e";
    case Holding_type::Bond_e: return "Bond_e";
    case Holding_type::Cash_e: return "Cash_e";
    case Holding_type::Blend_e: return "Blend_e";
    default: {
      return "Invalid Holding_type";

inline std::ostream& operator<<(std::ostream &out, Holding_type e) {
  return out << to_c_str(e);

enum class Account_type {

inline char const* to_c_str(Account_type e) {
  switch(e) {
    case Account_type::Other_e: return "Other_e";
    case Account_type::Roth_irs401k_e: return "Roth_irs401k_e";
    case Account_type::Traditional_irs401k_e: return "Traditional_irs401k_e";
    case Account_type::College_irs529_e: return "College_irs529_e";
    case Account_type::Traditional_ira_e: return "Traditional_ira_e";
    case Account_type::Investment_e: return "Investment_e";
    case Account_type::Brokerage_e: return "Brokerage_e";
    case Account_type::Checking_e: return "Checking_e";
    case Account_type::Health_savings_account_e: return "Health_savings_account_e";
    case Account_type::Savings_e: return "Savings_e";
    case Account_type::Money_market_e: return "Money_market_e";
    case Account_type::Mattress_e: return "Mattress_e";
    default: {
      return "Invalid Account_type";

inline std::ostream& operator<<(std::ostream &out, Account_type e) {
  return out << to_c_str(e);

struct Date_value

  Date_value() = default;

    boost::gregorian::date date,
    double value) :   date (date),
    value (value) {

  friend inline
  std::ostream& operator<<(std::ostream &out,
                           Date_value const& item) {
    out << "Date_value(" << &item << ") {";
    out << "\n  date:" << item.date;
    out << "\n  value:" << item.value;
    out << "\n}\n";
    return out;

  MSGPACK_DEFINE(date, value);

  boost::gregorian::date date {};
  double value {};


struct Holding

  Holding() = default;

    Holding_type holding_type,
    Date_value quantity,
    Date_value unit_value,
    double cost_basis) :   holding_type (holding_type),
    quantity (quantity),
    unit_value (unit_value),
    cost_basis (cost_basis) {

  friend inline
  std::ostream& operator<<(std::ostream &out,
                           Holding const& item) {
    out << "Holding(" << &item << ") {";
    out << "\n  holding_type:" << item.holding_type;
    out << "\n  quantity:" << item.quantity;
    out << "\n  unit_value:" << item.unit_value;
    out << "\n  cost_basis:" << item.cost_basis;
    out << "\n}\n";
    return out;

  MSGPACK_DEFINE(holding_type, quantity, unit_value, cost_basis);

  Holding_type holding_type {};
  Date_value quantity {};
  Date_value unit_value {};
  double cost_basis {};


struct Portfolio_account

  Portfolio_account() = default;

    Account_type account_type,
    std::string const & descr,
    bool stout) :   account_type (account_type),
    descr (descr),
    stout (stout) {

  friend inline
  std::ostream& operator<<(std::ostream &out,
                           Portfolio_account const& item) {
    out << "Portfolio_account(" << &item << ") {";
    out << "\n  account_type:" << item.account_type;
    out << "\n  descr:" << item.descr;
    out << "\n  stout:" << item.stout;
    out << "\n}\n";
    return out;

  MSGPACK_DEFINE(account_type, descr, stout);

  Account_type account_type {};
  std::string descr {};
  bool stout {};


} // namespace balance_sheet
} // namespace bs

template< typename T >
inline msgpack::sbuffer to_msgpack(T const& t) {
  msgpack::sbuffer sbuf;
  msgpack::pack(sbuf, t);
  return sbuf;

template < typename T >
inline void from_msgpack(msgpack::sbuffer &sbuf, T &t) {
  msgpack::unpacked msg;
  msgpack::unpack(msg, sbuf.data(), sbuf.size());
  msgpack::object obj = msg.get();
namespace msgpack {
namespace adaptor {

struct convert<boost::gregorian::date> {
    msgpack::object const& operator()(msgpack::object const& o, boost::gregorian::date& v) const {
        v = boost::gregorian::from_undelimited_string(o.as<std::string>());
        return o;

struct pack<boost::gregorian::date> {
    template <typename Stream>
    packer<Stream>& operator()(msgpack::packer<Stream>& o, boost::gregorian::date const& v) const {
        return o;

} // namespace adaptor
} // namespace msgpack


Use this package as a library

1. Depend on it

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

  ebisu_pod: "^0.0.10"

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:ebisu_pod/ebisu_pod.dart';
Version Uploaded Documentation Archive
0.0.10 May 27, 2017 Go to the documentation of ebisu_pod 0.0.10 Download ebisu_pod 0.0.10 archive
0.0.8 Feb 6, 2016 Go to the documentation of ebisu_pod 0.0.8 Download ebisu_pod 0.0.8 archive
0.0.7 Jan 29, 2016 Go to the documentation of ebisu_pod 0.0.7 Download ebisu_pod 0.0.7 archive
0.0.6 Jan 22, 2016 Go to the documentation of ebisu_pod 0.0.6 Download ebisu_pod 0.0.6 archive
0.0.5 Jan 22, 2016 Go to the documentation of ebisu_pod 0.0.5 Download ebisu_pod 0.0.5 archive
0.0.4 Jan 22, 2016 Go to the documentation of ebisu_pod 0.0.4 Download ebisu_pod 0.0.4 archive
0.0.2 Dec 16, 2015 Go to the documentation of ebisu_pod 0.0.2 Download ebisu_pod 0.0.2 archive


We analyzed this package on Jun 19, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.63.0
  • pana: 0.11.3


Describes how popular the package is relative to other packages. [more]
0 / 100
Code health derived from static analysis. [more]
28 / 100
Reflects how tidy and up-to-date the package is. [more]
48 / 100
Overall score:
Weighted score of the above. [more]
Learn more about scoring.


Detected platforms: unsure

Error(s) prevent platform classification:

Error(s) in lib/ebisu_pod.dart: super call must be last in an initializer list (see https://goo.gl/EY6hDP): 'super(id)'.


  • Fix platform conflicts.

    Error(s) prevent platform classification:

    Error(s) in lib/ebisu_pod.dart: super call must be last in an initializer list (see https://goo.gl/EY6hDP): 'super(id)'.

  • Maintain CHANGELOG.md.

    Changelog entries help clients to follow the progress in your code.

  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 25 errors 8 hints.

    Make sure that the imported libraries are not in conflict. Error(s) in lib/ebisu_pod.dart: super call must be last in an initializer list (see https://goo.gl/EY6hDP): 'super(id)'.

    Run dartfmt to format lib/example/balance_sheet.dart.

    Similar analysis of the following files failed:

    • lib/pod_cpp.dart (hint)
    • lib/pod_dart.dart (hint)
  • Package is getting outdated.

    The package was released 55 weeks ago.

  • Package is pre-v1 release.

    While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction API.

  • The description is too long.

    Search engines will display only the first part of the description. Try to keep it under 180 characters.

  • Maintain an example.

    Create a short demo in the example/ directory to show how to use this package. Common file name patterns include: main.dart, example.dart or you could also use ebisu_pod.dart.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.8.2 <2.0.0
collection >=1.1.0 <1.14.0 1.13.0 1.14.10
ebisu ^0.7.5 0.7.9
ebisu_cpp ^0.3.25 0.3.25
id ^1.0.16 1.0.16
logging >=0.9.3 <0.12.0 0.11.3+1
path ^1.4.1 1.6.1
quiver >=0.21.0 <0.25.0 0.24.0 0.29.0+1
Transitive dependencies
analyzer 0.32.1
args 0.13.7 1.4.3
async 2.0.7
charcode 1.1.1
convert 2.0.1
crypto 2.0.5
csslib 0.14.4
dart_style 1.1.0
drudge 0.0.1
front_end 0.1.1
glob 1.1.5
html 0.13.3+1
ini 1.1.0
kernel 0.3.1
matcher 0.12.3
meta 1.1.5
package_config 1.0.3
petitparser 1.7.6
plugin 0.2.0+2
source_span 1.4.0
stack_trace 1.7.4 1.9.2
string_scanner 1.0.2
typed_data 1.1.5
utf 0.9.0+4
watcher 0.9.7+8
yaml 2.1.14
Dev dependencies
test >=0.12.0 <0.14.0