d_bincode 1.0.0
d_bincode: ^1.0.0 copied to clipboard
A bincode like serialization library for Dart. Provides fast, deterministic encoding for binary data structures, mirroring the bincode specification (Rust) minimalistically.
example/d_bincode_example.dart
import 'dart:typed_data';
import 'package:d_bincode/d_bincode.dart';
/// === ENUM: RoleType ===
enum RoleType { guest, user, moderator, admin }
/// === CLASS: Address (Nested Struct) ===
class Address extends BincodeEncodable {
final String city;
final String zipCode;
Address(this.city, this.zipCode);
@override
void writeBincode(BincodeWriter writer) {
writer.writeString(city);
writer.writeString(zipCode);
}
factory Address.fromReader(BincodeReader reader) {
return Address(reader.readString(), reader.readString());
}
@override
String toString() => 'Address(city: "$city", zipCode: "$zipCode")';
}
/// === CLASS: UserProfile (Complex Struct) ===
class UserProfile extends BincodeEncodable {
final int id;
final String name;
final bool isActive;
final RoleType role;
final double balance;
final Float32List? bonusVector;
final Address? address;
final List<int> loginTimestamps;
final String? nickname;
final double? rating;
UserProfile({
required this.id,
required this.name,
required this.isActive,
required this.role,
required this.balance,
this.bonusVector,
this.address,
required this.loginTimestamps,
this.nickname,
this.rating,
});
@override
void writeBincode(BincodeWriter writer) {
writer.writeU32(id);
writer.writeString(name);
writer.writeBool(isActive);
writer.writeU32(role.index);
writer.writeF32(balance);
writer.writeOptionF32Triple(bonusVector);
writer.writeU8(address != null ? 1 : 0);
if (address != null) address!.writeBincode(writer);
writer.writeU32List(loginTimestamps);
writer.writeOptionString(nickname);
writer.writeOptionF32(rating);
}
factory UserProfile.fromBincode(Uint8List bytes) {
final reader = BincodeReader(bytes);
final id = reader.readU32();
final name = reader.readString();
final isActive = reader.readBool();
final roleIndex = reader.readU32();
final balance = reader.readF32();
final bonusVec = reader.readOptionF32Triple();
Address? address;
if (reader.readU8() == 1) {
address = Address.fromReader(reader);
}
final timestamps = reader.readU32List();
final nickname = reader.readOptionString();
final rating = reader.readOptionF32();
return UserProfile(
id: id,
name: name,
isActive: isActive,
role: RoleType.values[roleIndex],
balance: balance,
bonusVector: bonusVec,
address: address,
loginTimestamps: timestamps,
nickname: nickname,
rating: rating,
);
}
@override
String toString() => '''
UserProfile(
id: $id,
name: "$name",
active: $isActive,
role: $role,
balance: $balance,
bonusVector: $bonusVector,
address: $address,
loginTimestamps: $loginTimestamps,
nickname: "$nickname",
rating: $rating
)''';
}
/// === CLASS: UserData (Simple Struct) ===
class UserData extends BincodeEncodable {
final int userId;
final String username;
final double balance;
final List<int> loginTimestamps;
UserData(this.userId, this.username, this.balance, this.loginTimestamps);
@override
void writeBincode(BincodeWriter writer) {
writer.writeU32(userId);
writer.writeString(username);
writer.writeF32(balance);
writer.writeU32List(loginTimestamps);
}
factory UserData.fromBincode(Uint8List bytes) {
final reader = BincodeReader(bytes);
return UserData(
reader.readU32(),
reader.readString(),
reader.readF32(),
reader.readU32List(),
);
}
@override
String toString() =>
'UserData(userId: $userId, username: "$username", balance: $balance, loginTimestamps: $loginTimestamps)';
}
void main() {
/// === 1. Complex UserProfile Encoding/Decoding ===
final profile = UserProfile(
id: 101,
name: "DartVenger",
isActive: true,
role: RoleType.admin,
balance: 420.69,
bonusVector: Float32List.fromList([1.1, 2.2, 3.3]), // float precision
address: Address("Flutterville", "90210"),
loginTimestamps: [1678880000, 1681234567],
nickname: "DV",
rating: 4.8,
);
final profileBytes = profile.toBincode();
final decodedProfile = UserProfile.fromBincode(profileBytes);
print("=== Complex UserProfile ===");
print("Encoded: $profileBytes");
print("Decoded:\n$decodedProfile");
/// === 2. Simple UserData Example ===
final user = UserData(42, 'Eve_the_Hacker', 1337.50, [1678900000, 1680001234, 1680999999]);
final encoded = user.toBincode();
final decoded = UserData.fromBincode(encoded);
print("\n=== Simple UserData ===");
print("Encoded: $encoded");
print("Decoded: $decoded");
/// === 3. Fluent API Example ===
final fluent = BincodeFluentBuilder()
.u32(7)
.strFix("FluentGuy", 12)
.f32(88.88)
.optF32(12.34)
.optF32(null)
.optU32(2024)
.optU32(null)
.optBool(true)
.optBool(null)
..writeU32List([10, 20, 30]);
final fluentBytes = fluent.toBytes();
print("\n=== Fluent Encoded ===");
print("Encoded: $fluentBytes");
BincodeFluentReader(fluentBytes)
.u32((id) => print("→ ID: $id"))
.fixedStr(12, (name) => print("→ Name: $name"))
.f32((bal) => print("→ Balance: $bal"))
.optF32((bonus) => print("→ Optional Bonus: $bonus"))
.optF32((none) => print("→ Optional Bonus (null): $none"))
.optU32((year) => print("→ Optional Year: $year"))
.optU32((none) => print("→ Optional Year (null): $none"))
.optBool((flag) => print("→ Optional Active: $flag"))
.optBool((none) => print("→ Optional Active (null): $none"))
.u32List((list) => print("→ Login timestamps: $list"));
/// === 4. Debuggable Writer & Reader ===
final debugWriter = DebuggableBincodeWriter()
..writeU32(9001)
..writeFixedString("DebugHero", 16)
..writeBool(false)
..writeOptionF64(3.14159265)
..writeOptionString("optional string")
..writeOptionBool(null);
final debugBytes = debugWriter.toBytes();
final debugReader = DebuggableBincodeReader(debugBytes);
print("\n=== Debuggable Output ===");
print("→ ID: ${debugReader.readU32()}");
print("→ Name: ${debugReader.readFixedString(16)}");
print("→ Admin Flag: ${debugReader.readBool()}");
print("→ Pi Value: ${debugReader.readOptionF64()}");
print("→ Optional String: ${debugReader.readOptionString()}");
print("→ Optional Flag: ${debugReader.readOptionBool()}");
}