immutable_proto 0.0.5 immutable_proto: ^0.0.5 copied to clipboard
Automatically generates an immutable class for a ProtoBuf
This library generates immutable data classes for Protocol Buffers. Here's how to get started:
- Add these packages to your dependencies:
dependencies:
immutable_proto: ^0.0.5
dev_dependencies:
build_runner: ^1.0.0
immutable_proto_generator: ^0.0.5
- Write your Protocol Buffers definition.
message User {
string first_name = 1;
string last_name = 2;
repeated string email_addresses = 3;
enum FavoriteDrink {
UNKNOWN = 0;
COFFEE = 1;
COKE = 2;
TEA = 3;
}
FavoriteDrink favorite_drink = 4;
}
-
Generate the default (mutable) dart code for your Protobuf message (see the official documentation for more information).
-
Import the generated class with prefix
proto
to avoid name conflicts.
import 'proto_generated/user.pb.dart' as proto;
- Write a blueprint class. Let the name be
Mutable<Protobuf name>
and annotate it with@ImmutableProto(<Protobuf class>)
(Protobuf class
is a reference to the generated (mutable) class):
import 'package:immutable_proto/immutable_proto.dart';
part 'main.g.dart';
@ImmutableProto(proto.User)
class MutableUser {
String firstName;
@required // This field must not be null
String lastName;
// Lists must not be null by default
KtList<String> emailAddresses;
// Will be replaced by the generated enum
proto.User_FavoriteDrink favoriteDrink;
}
- Run
pub run build_runner build
in the command line (orflutter pub run build_runner build
, if you're using Flutter). The implementation based on your blueprint class will automatically get generated.
The immutable class contains
- a constructor with named parameters and assertions for required values
- method/constructor for converting the immutable class to the mutable class (generated by Protocol Buffers) and the other way around
- custom implementations of
==
,hashCode
andtoString()
- a copy method
- enum mappers
For example, here's the generated code of our class above:
@immutable
class User {
final String firstName;
final String lastName;
@required
final KtList<String> emailAddresses;
final UserFavoriteDrink favoriteDrink;
User({
this.firstName,
this.lastName,
@required this.emailAddresses,
this.favoriteDrink,
}) : assert(emailAddresses != null);
User.fromProto(proto.User user)
: this(
firstName: user.firstName,
lastName: user.lastName,
emailAddresses: KtList.from(user.emailAddresses),
favoriteDrink: userFavoriteDrinkFromProto(user.favoriteDrink),
);
proto.User toProto() {
final user = proto.User();
if (firstName != null) user.firstName = firstName;
if (lastName != null) user.lastName = lastName;
user.emailAddresses.addAll(emailAddresses.iter);
if (favoriteDrink != null)
user.favoriteDrink = userFavoriteDrinkToProto(favoriteDrink);
return user;
}
bool operator ==(Object other) {
return other is User &&
firstName == other.firstName &&
lastName == other.lastName &&
emailAddresses == other.emailAddresses &&
favoriteDrink == other.favoriteDrink;
}
int get hashCode => hashList([
firstName,
lastName,
emailAddresses,
favoriteDrink,
]);
User copy({
String firstName,
String lastName,
KtList<String> emailAddresses,
UserFavoriteDrink favoriteDrink,
}) =>
User(
firstName: firstName ?? this.firstName,
lastName: lastName ?? this.lastName,
emailAddresses: emailAddresses ?? this.emailAddresses,
favoriteDrink: favoriteDrink ?? this.favoriteDrink,
);
String toString() {
return 'User(firstName: $firstName, lastName: $lastName, emailAddresses: $emailAddresses, favoriteDrink: $favoriteDrink)';
}
static UserFavoriteDrink userFavoriteDrinkFromProto(
proto.User_FavoriteDrink userFavoriteDrink) {
switch (userFavoriteDrink) {
case proto.User_FavoriteDrink.COFFEE:
return UserFavoriteDrink.coffee;
case proto.User_FavoriteDrink.COKE:
return UserFavoriteDrink.coke;
case proto.User_FavoriteDrink.TEA:
return UserFavoriteDrink.tea;
case proto.User_FavoriteDrink.UNKNOWN:
default:
return UserFavoriteDrink.unknown;
}
}
static proto.User_FavoriteDrink userFavoriteDrinkToProto(
UserFavoriteDrink userFavoriteDrink) {
switch (userFavoriteDrink) {
case UserFavoriteDrink.coffee:
return proto.User_FavoriteDrink.COFFEE;
case UserFavoriteDrink.coke:
return proto.User_FavoriteDrink.COKE;
case UserFavoriteDrink.tea:
return proto.User_FavoriteDrink.TEA;
case UserFavoriteDrink.unknown:
default:
return proto.User_FavoriteDrink.UNKNOWN;
}
}
}
enum UserFavoriteDrink {
unknown,
coffee,
coke,
tea,
}
Features #
- Generate basic immutable classes for a message
- Generate classes for nested messages automatically
- Generate enum + mappers for nested enums automatically
oneof
-support- Commented code
- Custom methods
License #
Copyright 2019 Jonas Wanke
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.