class Embeddable { static const TYPE_KEY = '_type'; static const INLINE_KEY = '_inline'; final String type; final bool inline; final Map _data; Embeddable(this.type, this.inline, Map data) : assert(type != null), assert(inline != null), _data = Map.from(data); Map toJson() { Map m = Map.from(_data); m[TYPE_KEY] = type; m[INLINE_KEY] = inline; return m; } static Embeddable fromJson(Map json) { String type = json[TYPE_KEY] as String; bool inline = json[INLINE_KEY] as bool; Map data = Map.from(json); data.remove(TYPE_KEY); data.remove(INLINE_KEY); if (inline) { return Span(type, data: data); } return BlockEmbed(type, data: data); } } class Span extends Embeddable { Span( String type, { Map data = const {}, }) : super(type, true, data); } class BlockEmbed extends Embeddable { BlockEmbed( String type, { Map data = const {}, }) : super(type, false, data); }