jolleekin / jsonx

An extended JSON library that supports the encoding and decoding of arbitrary objects.
BSD 2-Clause "Simplified" License
11 stars 6 forks source link

Encoding / Decoding Enum #2

Closed Xerosigma closed 10 years ago

Xerosigma commented 10 years ago

How would one encode and decode the below?

class SkillType {
  final _value;
  const SkillType._internal(this._value);
  toString() => 'SkillType.$_value';

  static const ULTIMATE = const SkillType._internal('ULTIMATE');
  static const ACTIVE = const SkillType._internal('ACTIVE');
  static const PASSIVE = const SkillType._internal('PASSIVE');
}

Given this example class:

class Test() {
  String name;
  SkillType type;

  Test(String name, SkillType type) {
    this.name = name;
    this.type = type;
  }
}
print(encode(new Test("lol",SkillType.PASSIVE)));

My desired result is as follows:

{
    "name":"lol",
    "type":"PASSIVE"
}
jolleekin commented 10 years ago

Dart doesn't have enums yet. SkillType in your example is just a way to mimic enum but it's not an enum. So, there is no way for this library to detect it and encode/decode properly.

jolleekin commented 10 years ago

Hi there,

The process of encoding/decoding an arbitrary Dart object is as follows.

            toEncodable
Dart Object -----------> Json Object -----------> Json String

            toObject
Dart Object <----------- Json Object <----------- Json String

In the current version, users cannot control the behavior of toEncodable or toObject. That prevents the library from working with DateTime or simulated enums. So, I'm working on a new version that allows users to customize toObject and toEncodable methods.

Now, you can make the library work with your enums as below.

class Enum {
  final int _id;

  const Enum._(this._id);

  static const ONE = const Enum._(1);
  static const TWO = const Enum._(2);
}

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

customToObjects[Enum] = (int input) {
  if (input == 1) return Enum.ONE;
  if (input == 2) return Enum.TWO;
  throw new ArgumentError('Unknown enum value [$input]');
};

customToEncodables[Enum] = (Enum input) => input._id;

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

assert(encode(Enum.ONE) == '1');
assert(decode('1', type: Enum) == Enum.ONE);
Xerosigma commented 10 years ago

Awesome, thanks for the update! :thumbsup:

jolleekin commented 10 years ago

The latest version has been published. Please try it out!