Jaguar-dart / jaguar_serializer

Format (JSON, XML, protobuf, mongodb, etc) and platform (server, client) agnostic serialization framework
172 stars 34 forks source link

Protobuf support ? #161

Closed jaumard closed 5 years ago

jaumard commented 5 years ago

On the description it's written that it support protobuf, any example on this ? or maybe it's not implemented yet. Let me know

tejainece commented 5 years ago

it is not implemented yet.

jaumard commented 5 years ago

Thanks @tejainece :) I might try to implement it then

tejainece commented 5 years ago

That will be awesome. Can we hide all the implementation details of Protobuf and make it super simple to use?

jaumard commented 5 years ago

I don't know yet :) but the plan is to make a ProtoRepo like the JsonRepo so it's will be as simple as now, just use proto repo instead of json one. And it will allow you to switch from one to another easily. Hope it will be possible like this... we'll see

jaumard commented 5 years ago

So I was able to give it a try but I'm struggling :(

Here is what Protobuf generates:

///
//  Generated code. Do not modify.
//  source: test.proto
///
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import

// ignore: UNUSED_SHOWN_NAME
import 'dart:core' show int, bool, double, String, List, override;

import 'package:protobuf/protobuf.dart' as $pb;

class Person extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Person')
    ..aOS(1, 'name')
    ..a<int>(2, 'id', $pb.PbFieldType.O3)
    ..aOS(3, 'email')
    ..hasRequiredFields = false
  ;

  Person() : super();
  Person.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
  Person.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
  Person clone() => new Person()..mergeFromMessage(this);
  // ignore: return_of_invalid_type
  Person copyWith(void Function(Person) updates) => super.copyWith((message) => updates(message as Person));
  $pb.BuilderInfo get info_ => _i;
  static Person create() => new Person();
  static $pb.PbList<Person> createRepeated() => new $pb.PbList<Person>();
  static Person getDefault() => _defaultInstance ??= create()..freeze();
  static Person _defaultInstance;
  static void $checkItem(Person v) {
    if (v is! Person) $pb.checkItemFailed(v, _i.qualifiedMessageName);
  }

  String get name => $_getS(0, '');
  set name(String v) { $_setString(0, v); }
  bool hasName() => $_has(0);
  void clearName() => clearField(1);

  int get id => $_get(1, 0);
  set id(int v) { $_setSignedInt32(1, v); }
  bool hasId() => $_has(1);
  void clearId() => clearField(2);

  String get email => $_getS(2, '');
  set email(String v) { $_setString(2, v); }
  bool hasEmail() => $_has(2);
  void clearEmail() => clearField(3);
}

So to serialize we just need to call writeToBuffer and to deserialize we need the static method fromBuffer.

The problem is when I tried to implement the protoRepo I can't really implement the decodeOne method :/

import 'dart:convert';

import '../serializer/serializer.dart';
import 'package:jaguar_serializer/src/repo/repo.dart';
import "codec.dart";
import 'package:protobuf/protobuf.dart' as $pb;

/// Repository that serialize/deserialize JSON.
///
/// Same usage as [SerializerRepo]
class ProtoRepo extends SerializerRepoImpl implements CodecRepo<List<int>> {
  ProtoRepo({List<Serializer> serializers}) : super(serializers: serializers);

  ///@nodoc
  /// use [serialize]
  List<int> encode(dynamic object) {
    return object.writeToBuffer() as List<int>;
  }

  ///@nodoc
  /// use [deserialize]
  dynamic decode<T>(List<int> object) {
    throw 'no needed';
  }

  ///@nodoc
  /// use [deserialize]
  T decodeOne<T>(List<int> object) {
    return T.fromBuffer(object);
  }

  ///@nodoc
  /// use [deserialize]
  List<T> decodeList<T>(List<int> object) {
    throw 'no needed';
  }
}

Any idea how to do such things ? I know dart doesn't allow this, but maybe we can think of a workaround to be able to do this somehow.... @tejainece any ideas ?

jaumard commented 5 years ago

Done by #164 :) 🎆 @tejainece let me know when it's published please