freezed
This commit is contained in:
parent
6a47363d8c
commit
5e0e389915
@ -2,6 +2,7 @@ import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:change_case/change_case.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'veilid_encoding.dart';
|
||||
@ -12,57 +13,51 @@ part 'routing_context.g.dart';
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
extension ValidateDFLT on DHTSchemaDFLT {
|
||||
bool validate() {
|
||||
if (oCnt > 65535) {
|
||||
return false;
|
||||
}
|
||||
if (oCnt <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
extension ValidateSMPL on DHTSchemaSMPL {
|
||||
bool validate() {
|
||||
final totalsv = members.fold(0, (acc, v) => (acc + v.mCnt)) + oCnt;
|
||||
if (totalsv > 65535) {
|
||||
return false;
|
||||
}
|
||||
if (totalsv <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// DHT Schema
|
||||
|
||||
abstract class DHTSchema {
|
||||
factory DHTSchema.fromJson(dynamic json) {
|
||||
switch (json["kind"]) {
|
||||
case "DFLT":
|
||||
{
|
||||
return DHTSchemaDFLT(oCnt: json["o_cnt"]);
|
||||
}
|
||||
case "SMPL":
|
||||
{
|
||||
return DHTSchemaSMPL(
|
||||
oCnt: json["o_cnt"],
|
||||
members: List<DHTSchemaMember>.from(
|
||||
json['members'].map((j) => DHTSchemaMember.fromJson(j))));
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw VeilidAPIExceptionInternal(
|
||||
"Invalid DHTSchema type: ${json['kind']}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, dynamic> toJson();
|
||||
}
|
||||
@Freezed(unionKey: 'kind', unionValueCase: FreezedUnionCase.pascal)
|
||||
sealed class DHTSchema with _$DHTSchema {
|
||||
@FreezedUnionValue('DFLT')
|
||||
const factory DHTSchema.dflt({required int oCnt}) = DHTSchemaDFLT;
|
||||
|
||||
class DHTSchemaDFLT implements DHTSchema {
|
||||
final int oCnt;
|
||||
//
|
||||
DHTSchemaDFLT({
|
||||
required this.oCnt,
|
||||
}) {
|
||||
if (oCnt < 0 || oCnt > 65535) {
|
||||
throw VeilidAPIExceptionInvalidArgument(
|
||||
"value out of range", "oCnt", oCnt.toString());
|
||||
}
|
||||
}
|
||||
@FreezedUnionValue('SMPL')
|
||||
const factory DHTSchema.smpl(
|
||||
{required int oCnt,
|
||||
required List<DHTSchemaMember> members}) = DHTSchemaSMPL;
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'kind': "DFLT",
|
||||
'o_cnt': oCnt,
|
||||
};
|
||||
}
|
||||
factory DHTSchema.fromJson(Map<String, dynamic> json) =>
|
||||
_$DHTSchemaFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class DHTSchemaMember with _$DHTSchemaMember {
|
||||
@Assert('mCnt >= 0 && mCnt <= 65535', 'value out of range')
|
||||
@Assert('mCnt > 0 && mCnt <= 65535', 'value out of range')
|
||||
const factory DHTSchemaMember({
|
||||
required PublicKey mKey,
|
||||
required int mCnt,
|
||||
@ -72,118 +67,51 @@ class DHTSchemaMember with _$DHTSchemaMember {
|
||||
_$DHTSchemaMemberFromJson(json);
|
||||
}
|
||||
|
||||
class DHTSchemaSMPL implements DHTSchema {
|
||||
final int oCnt;
|
||||
final List<DHTSchemaMember> members;
|
||||
//
|
||||
DHTSchemaSMPL({
|
||||
required this.oCnt,
|
||||
required this.members,
|
||||
}) {
|
||||
if (oCnt < 0 || oCnt > 65535) {
|
||||
throw VeilidAPIExceptionInvalidArgument(
|
||||
"value out of range", "oCnt", oCnt.toString());
|
||||
}
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'kind': "SMPL",
|
||||
'o_cnt': oCnt,
|
||||
'members': members.map((p) => p.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// DHTRecordDescriptor
|
||||
|
||||
class DHTRecordDescriptor {
|
||||
TypedKey key;
|
||||
PublicKey owner;
|
||||
PublicKey? ownerSecret;
|
||||
DHTSchema schema;
|
||||
|
||||
DHTRecordDescriptor({
|
||||
required this.key,
|
||||
required this.owner,
|
||||
this.ownerSecret,
|
||||
required this.schema,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'key': key.toString(),
|
||||
'owner': owner,
|
||||
'owner_secret': ownerSecret,
|
||||
'schema': schema.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
DHTRecordDescriptor.fromJson(dynamic json)
|
||||
: key = TypedKey.fromString(json['key']),
|
||||
owner = json['owner'],
|
||||
ownerSecret = json['owner_secret'],
|
||||
schema = DHTSchema.fromJson(json['schema']);
|
||||
@freezed
|
||||
class DHTRecordDescriptor with _$DHTRecordDescriptor {
|
||||
const factory DHTRecordDescriptor({
|
||||
required TypedKey key,
|
||||
required PublicKey owner,
|
||||
PublicKey? ownerSecret,
|
||||
required DHTSchema schema,
|
||||
}) = _DHTRecordDescriptor;
|
||||
factory DHTRecordDescriptor.fromJson(Map<String, dynamic> json) =>
|
||||
_$DHTRecordDescriptorFromJson(json);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// ValueSubkeyRange
|
||||
|
||||
class ValueSubkeyRange {
|
||||
final int low;
|
||||
final int high;
|
||||
@freezed
|
||||
class ValueSubkeyRange with _$ValueSubkeyRange {
|
||||
@Assert('low < 0 || low > high', 'low out of range')
|
||||
@Assert('high < 0', 'high out of range')
|
||||
const factory ValueSubkeyRange({
|
||||
required int low,
|
||||
required int high,
|
||||
}) = _ValueSubkeyRange;
|
||||
|
||||
ValueSubkeyRange({
|
||||
required this.low,
|
||||
required this.high,
|
||||
}) {
|
||||
if (low < 0 || low > high) {
|
||||
throw VeilidAPIExceptionInvalidArgument(
|
||||
"invalid range", "low", low.toString());
|
||||
}
|
||||
if (high < 0) {
|
||||
throw VeilidAPIExceptionInvalidArgument(
|
||||
"invalid range", "high", high.toString());
|
||||
}
|
||||
}
|
||||
|
||||
ValueSubkeyRange.fromJson(dynamic json)
|
||||
: low = json[0],
|
||||
high = json[1] {
|
||||
if ((json as List<int>).length != 2) {
|
||||
throw VeilidAPIExceptionInvalidArgument(
|
||||
"not a pair of integers", "json", json.toString());
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic> toJson() {
|
||||
return [low, high];
|
||||
}
|
||||
factory ValueSubkeyRange.fromJson(Map<String, dynamic> json) =>
|
||||
_$ValueSubkeyRangeFromJson(json);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// ValueData
|
||||
|
||||
class ValueData {
|
||||
final int seq;
|
||||
final Uint8List data;
|
||||
final PublicKey writer;
|
||||
@freezed
|
||||
class ValueData with _$ValueData {
|
||||
@Assert('seq >= 0', 'seq out of range')
|
||||
const factory ValueData({
|
||||
required int seq,
|
||||
@Uint8ListJsonConverter() required Uint8List data,
|
||||
required PublicKey writer,
|
||||
}) = _ValueData;
|
||||
|
||||
ValueData({
|
||||
required this.seq,
|
||||
required this.data,
|
||||
required this.writer,
|
||||
});
|
||||
|
||||
ValueData.fromJson(dynamic json)
|
||||
: seq = json['seq'],
|
||||
data = base64UrlNoPadDecode(json['data']),
|
||||
writer = json['writer'];
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'seq': seq, 'data': base64UrlNoPadEncode(data), 'writer': writer};
|
||||
}
|
||||
factory ValueData.fromJson(Map<String, dynamic> json) =>
|
||||
_$ValueDataFromJson(json);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -193,13 +121,9 @@ enum Stability {
|
||||
lowLatency,
|
||||
reliable;
|
||||
|
||||
String toJson() {
|
||||
return name.toPascalCase();
|
||||
}
|
||||
|
||||
factory Stability.fromJson(String j) {
|
||||
return Stability.values.byName(j.toCamelCase());
|
||||
}
|
||||
String toJson() => name.toPascalCase();
|
||||
factory Stability.fromJson(String j) =>
|
||||
Stability.values.byName(j.toCamelCase());
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@ -210,37 +134,39 @@ enum Sequencing {
|
||||
preferOrdered,
|
||||
ensureOrdered;
|
||||
|
||||
String toJson() {
|
||||
return name.toPascalCase();
|
||||
}
|
||||
|
||||
factory Sequencing.fromJson(String j) {
|
||||
return Sequencing.values.byName(j.toCamelCase());
|
||||
}
|
||||
String toJson() => name.toPascalCase();
|
||||
factory Sequencing.fromJson(String j) =>
|
||||
Sequencing.values.byName(j.toCamelCase());
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// SafetySelection
|
||||
|
||||
abstract class SafetySelection {
|
||||
factory SafetySelection.fromJson(dynamic json) {
|
||||
var m = json as Map<String, dynamic>;
|
||||
if (m.containsKey("Unsafe")) {
|
||||
@immutable
|
||||
abstract class SafetySelection extends Equatable {
|
||||
factory SafetySelection.fromJson(Map<String, dynamic> json) {
|
||||
if (json.containsKey("Unsafe")) {
|
||||
return SafetySelectionUnsafe(
|
||||
sequencing: Sequencing.fromJson(m["Unsafe"]));
|
||||
} else if (m.containsKey("Safe")) {
|
||||
return SafetySelectionSafe(safetySpec: SafetySpec.fromJson(m["Safe"]));
|
||||
sequencing: Sequencing.fromJson(json["Unsafe"]));
|
||||
} else if (json.containsKey("Safe")) {
|
||||
return SafetySelectionSafe(safetySpec: SafetySpec.fromJson(json["Safe"]));
|
||||
} else {
|
||||
throw VeilidAPIExceptionInternal("Invalid SafetySelection");
|
||||
throw const VeilidAPIExceptionInternal("Invalid SafetySelection");
|
||||
}
|
||||
}
|
||||
Map<String, dynamic> toJson();
|
||||
}
|
||||
|
||||
@immutable
|
||||
class SafetySelectionUnsafe implements SafetySelection {
|
||||
final Sequencing sequencing;
|
||||
@override
|
||||
List<Object> get props => [sequencing];
|
||||
@override
|
||||
bool? get stringify => null;
|
||||
|
||||
//
|
||||
SafetySelectionUnsafe({
|
||||
const SafetySelectionUnsafe({
|
||||
required this.sequencing,
|
||||
});
|
||||
|
||||
@ -250,10 +176,16 @@ class SafetySelectionUnsafe implements SafetySelection {
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class SafetySelectionSafe implements SafetySelection {
|
||||
final SafetySpec safetySpec;
|
||||
@override
|
||||
List<Object> get props => [safetySpec];
|
||||
@override
|
||||
bool? get stringify => null;
|
||||
|
||||
//
|
||||
SafetySelectionSafe({
|
||||
const SafetySelectionSafe({
|
||||
required this.safetySpec,
|
||||
});
|
||||
|
||||
@ -264,50 +196,28 @@ class SafetySelectionSafe implements SafetySelection {
|
||||
}
|
||||
|
||||
/// Options for safety routes (sender privacy)
|
||||
class SafetySpec {
|
||||
final String? preferredRoute;
|
||||
final int hopCount;
|
||||
final Stability stability;
|
||||
final Sequencing sequencing;
|
||||
//
|
||||
SafetySpec({
|
||||
this.preferredRoute,
|
||||
required this.hopCount,
|
||||
required this.stability,
|
||||
required this.sequencing,
|
||||
});
|
||||
@freezed
|
||||
class SafetySpec with _$SafetySpec {
|
||||
const factory SafetySpec({
|
||||
String? preferredRoute,
|
||||
required int hopCount,
|
||||
required Stability stability,
|
||||
required Sequencing sequencing,
|
||||
}) = _SafetySpec;
|
||||
|
||||
SafetySpec.fromJson(dynamic json)
|
||||
: preferredRoute = json['preferred_route'],
|
||||
hopCount = json['hop_count'],
|
||||
stability = Stability.fromJson(json['stability']),
|
||||
sequencing = Sequencing.fromJson(json['sequencing']);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'preferred_route': preferredRoute,
|
||||
'hop_count': hopCount,
|
||||
'stability': stability.toJson(),
|
||||
'sequencing': sequencing.toJson()
|
||||
};
|
||||
}
|
||||
factory SafetySpec.fromJson(Map<String, dynamic> json) =>
|
||||
_$SafetySpecFromJson(json);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
/// RouteBlob
|
||||
class RouteBlob {
|
||||
final String routeId;
|
||||
final Uint8List blob;
|
||||
|
||||
RouteBlob(this.routeId, this.blob);
|
||||
|
||||
RouteBlob.fromJson(dynamic json)
|
||||
: routeId = json['route_id'],
|
||||
blob = base64UrlNoPadDecode(json['blob']);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'route_id': routeId, 'blob': base64UrlNoPadEncode(blob)};
|
||||
}
|
||||
@freezed
|
||||
class RouteBlob with _$RouteBlob {
|
||||
const factory RouteBlob(
|
||||
{required String routeId,
|
||||
@Uint8ListJsonConverter() required Uint8List blob}) = _RouteBlob;
|
||||
factory RouteBlob.fromJson(Map<String, dynamic> json) =>
|
||||
_$RouteBlobFromJson(json);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,34 @@ part of 'routing_context.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$DHTSchemaDFLT _$$DHTSchemaDFLTFromJson(Map<String, dynamic> json) =>
|
||||
_$DHTSchemaDFLT(
|
||||
oCnt: json['o_cnt'] as int,
|
||||
$type: json['kind'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$DHTSchemaDFLTToJson(_$DHTSchemaDFLT instance) =>
|
||||
<String, dynamic>{
|
||||
'o_cnt': instance.oCnt,
|
||||
'kind': instance.$type,
|
||||
};
|
||||
|
||||
_$DHTSchemaSMPL _$$DHTSchemaSMPLFromJson(Map<String, dynamic> json) =>
|
||||
_$DHTSchemaSMPL(
|
||||
oCnt: json['o_cnt'] as int,
|
||||
members: (json['members'] as List<dynamic>)
|
||||
.map((e) => DHTSchemaMember.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
$type: json['kind'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$DHTSchemaSMPLToJson(_$DHTSchemaSMPL instance) =>
|
||||
<String, dynamic>{
|
||||
'o_cnt': instance.oCnt,
|
||||
'members': instance.members.map((e) => e.toJson()).toList(),
|
||||
'kind': instance.$type,
|
||||
};
|
||||
|
||||
_$_DHTSchemaMember _$$_DHTSchemaMemberFromJson(Map<String, dynamic> json) =>
|
||||
_$_DHTSchemaMember(
|
||||
mKey: FixedEncodedString43.fromJson(json['m_key']),
|
||||
@ -17,3 +45,75 @@ Map<String, dynamic> _$$_DHTSchemaMemberToJson(_$_DHTSchemaMember instance) =>
|
||||
'm_key': instance.mKey.toJson(),
|
||||
'm_cnt': instance.mCnt,
|
||||
};
|
||||
|
||||
_$_DHTRecordDescriptor _$$_DHTRecordDescriptorFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$_DHTRecordDescriptor(
|
||||
key: Typed<FixedEncodedString43>.fromJson(json['key']),
|
||||
owner: FixedEncodedString43.fromJson(json['owner']),
|
||||
ownerSecret: json['owner_secret'] == null
|
||||
? null
|
||||
: FixedEncodedString43.fromJson(json['owner_secret']),
|
||||
schema: DHTSchema.fromJson(json['schema'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$_DHTRecordDescriptorToJson(
|
||||
_$_DHTRecordDescriptor instance) =>
|
||||
<String, dynamic>{
|
||||
'key': instance.key.toJson(),
|
||||
'owner': instance.owner.toJson(),
|
||||
'owner_secret': instance.ownerSecret?.toJson(),
|
||||
'schema': instance.schema.toJson(),
|
||||
};
|
||||
|
||||
_$_ValueSubkeyRange _$$_ValueSubkeyRangeFromJson(Map<String, dynamic> json) =>
|
||||
_$_ValueSubkeyRange(
|
||||
low: json['low'] as int,
|
||||
high: json['high'] as int,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$_ValueSubkeyRangeToJson(_$_ValueSubkeyRange instance) =>
|
||||
<String, dynamic>{
|
||||
'low': instance.low,
|
||||
'high': instance.high,
|
||||
};
|
||||
|
||||
_$_ValueData _$$_ValueDataFromJson(Map<String, dynamic> json) => _$_ValueData(
|
||||
seq: json['seq'] as int,
|
||||
data: const Uint8ListJsonConverter().fromJson(json['data'] as String),
|
||||
writer: FixedEncodedString43.fromJson(json['writer']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$_ValueDataToJson(_$_ValueData instance) =>
|
||||
<String, dynamic>{
|
||||
'seq': instance.seq,
|
||||
'data': const Uint8ListJsonConverter().toJson(instance.data),
|
||||
'writer': instance.writer.toJson(),
|
||||
};
|
||||
|
||||
_$_SafetySpec _$$_SafetySpecFromJson(Map<String, dynamic> json) =>
|
||||
_$_SafetySpec(
|
||||
preferredRoute: json['preferred_route'] as String?,
|
||||
hopCount: json['hop_count'] as int,
|
||||
stability: Stability.fromJson(json['stability'] as String),
|
||||
sequencing: Sequencing.fromJson(json['sequencing'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$_SafetySpecToJson(_$_SafetySpec instance) =>
|
||||
<String, dynamic>{
|
||||
'preferred_route': instance.preferredRoute,
|
||||
'hop_count': instance.hopCount,
|
||||
'stability': instance.stability.toJson(),
|
||||
'sequencing': instance.sequencing.toJson(),
|
||||
};
|
||||
|
||||
_$_RouteBlob _$$_RouteBlobFromJson(Map<String, dynamic> json) => _$_RouteBlob(
|
||||
routeId: json['route_id'] as String,
|
||||
blob: const Uint8ListJsonConverter().fromJson(json['blob'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$_RouteBlobToJson(_$_RouteBlob instance) =>
|
||||
<String, dynamic>{
|
||||
'route_id': instance.routeId,
|
||||
'blob': const Uint8ListJsonConverter().toJson(instance.blob),
|
||||
};
|
||||
|
@ -39,7 +39,8 @@ Object? veilidApiToEncodable(Object? value) {
|
||||
throw UnsupportedError('Cannot convert to JSON: $value');
|
||||
}
|
||||
|
||||
T? Function(dynamic) optFromJson<T>(T Function(dynamic) jsonConstructor) {
|
||||
T? Function(dynamic) optFromJson<T>(
|
||||
T Function(Map<String, dynamic>) jsonConstructor) {
|
||||
return (dynamic j) {
|
||||
if (j == null) {
|
||||
return null;
|
||||
@ -50,9 +51,11 @@ T? Function(dynamic) optFromJson<T>(T Function(dynamic) jsonConstructor) {
|
||||
}
|
||||
|
||||
List<T> Function(dynamic) jsonListConstructor<T>(
|
||||
T Function(dynamic) jsonConstructor) {
|
||||
T Function(Map<String, dynamic>) jsonConstructor) {
|
||||
return (dynamic j) {
|
||||
return (j as List<dynamic>).map((e) => jsonConstructor(e)).toList();
|
||||
return (j as List<Map<String, dynamic>>)
|
||||
.map((e) => jsonConstructor(e))
|
||||
.toList();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3266,6 +3266,8 @@ abstract class _$$VeilidUpdateValueChangeCopyWith<$Res> {
|
||||
List<ValueSubkeyRange> subkeys,
|
||||
int count,
|
||||
ValueData valueData});
|
||||
|
||||
$ValueDataCopyWith<$Res> get valueData;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -3303,6 +3305,14 @@ class __$$VeilidUpdateValueChangeCopyWithImpl<$Res>
|
||||
as ValueData,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ValueDataCopyWith<$Res> get valueData {
|
||||
return $ValueDataCopyWith<$Res>(_value.valueData, (value) {
|
||||
return _then(_value.copyWith(valueData: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
@ -242,10 +242,10 @@ _$VeilidUpdateValueChange _$$VeilidUpdateValueChangeFromJson(
|
||||
_$VeilidUpdateValueChange(
|
||||
key: Typed<FixedEncodedString43>.fromJson(json['key']),
|
||||
subkeys: (json['subkeys'] as List<dynamic>)
|
||||
.map(ValueSubkeyRange.fromJson)
|
||||
.map((e) => ValueSubkeyRange.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
count: json['count'] as int,
|
||||
valueData: ValueData.fromJson(json['value_data']),
|
||||
valueData: ValueData.fromJson(json['value_data'] as Map<String, dynamic>),
|
||||
$type: json['kind'] as String?,
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user