feat(core): A.6 — supervisor reconnect with watchdog and event stream

Adds an end-to-end auto-reconnect path so a brief network outage no
longer leaves the client wedged in a half-dead state. The flow has
three layers, each motivated by a real failure mode observed on the
Moto G live test:

* `chanora_protocol::DisconnectReason` (`UserRequested` /
  `StreamEnded` / `Error(String)`) is reported on a `oneshot` when
  the per-connection task exits, so the supervisor can tell user
  intent apart from a real loss.
* `chanora_core` spawns a supervisor task per `ChanoraSession`. It
  listens for the loss notifier AND runs a watchdog that issues
  `snapshot()` probes every 5s with a 4s timeout — three consecutive
  misses synthesise a `DisconnectReason::Error(...)` and trigger the
  reconnect path. The watchdog catches the "ghost connected" case
  where tsclientlib silently resets internal state but the event
  stream never errors. Backoff schedule: 1s, 2s, 5s, 15s, 30s, 60s
  (capped). On success the supervisor swaps the dead `ProtocolClient`
  for the new one in place and, if audio was running, restarts the
  audio engine bound to the new `voice_in`/`voice_out` channels.
* `SessionEvent` (Connected / Lost / Reconnecting / Disconnected /
  AudioStarted / AudioStopped) is broadcast on a 64-slot channel.
  `chanora_bridge` re-exports it as `BridgeEvent` and exposes
  `events_stream(StreamSink)`; the Flutter side subscribes from
  `initState` and renders a reconnect banner with attempt count and
  delay. New `SnapshotProbe` exposes a clone-friendly snapshot path
  so the watchdog can probe without holding `&self` across awaits.

Localization adds `statusReconnecting` and `statusConnectionLost`
keys to `app_en.arb` and `app_zh.arb`.

Verified on Moto G Stylus 5G (Android 14) against cn.teamspeak.app:
killed Wi-Fi + cellular for ~70 s; watchdog declared loss at three
misses, supervisor walked the backoff schedule, and the UI
reconnected automatically once the radios came back. Snapshot tree
re-rendered without user action.
This commit is contained in:
EdisonJwa
2026-05-15 01:06:07 +08:00
parent bc0da50cdb
commit 0bef61aea2
18 changed files with 1929 additions and 74 deletions
+12
View File
@@ -27,6 +27,18 @@
"placeholders": { "message": { "type": "String" } }
},
"statusReconnecting": "Reconnecting… attempt {attempt}, in {delay}s",
"@statusReconnecting": {
"placeholders": {
"attempt": { "type": "int" },
"delay": { "type": "int" }
}
},
"statusConnectionLost": "Connection lost: {reason}",
"@statusConnectionLost": {
"placeholders": { "reason": { "type": "String" } }
},
"audioStatsLine": "TX {sent} frames • RX {received} frames • PTT {ptt}",
"@audioStatsLine": {
"placeholders": {
+3
View File
@@ -20,6 +20,9 @@
"statusConnected": "已连接到 {server}",
"statusError": "错误:{message}",
"statusReconnecting": "正在重新连接……第 {attempt} 次尝试,{delay} 秒后",
"statusConnectionLost": "连接已断开:{reason}",
"audioStatsLine": "发送 {sent} 帧 • 接收 {received} 帧 • PTT {ptt}",
"channelsHeading": "频道",
@@ -181,6 +181,18 @@ abstract class AppL10n {
/// **'Error: {message}'**
String statusError(String message);
/// No description provided for @statusReconnecting.
///
/// In en, this message translates to:
/// **'Reconnecting… attempt {attempt}, in {delay}s'**
String statusReconnecting(int attempt, int delay);
/// No description provided for @statusConnectionLost.
///
/// In en, this message translates to:
/// **'Connection lost: {reason}'**
String statusConnectionLost(String reason);
/// No description provided for @audioStatsLine.
///
/// In en, this message translates to:
@@ -55,6 +55,16 @@ class AppL10nEn extends AppL10n {
return 'Error: $message';
}
@override
String statusReconnecting(int attempt, int delay) {
return 'Reconnecting… attempt $attempt, in ${delay}s';
}
@override
String statusConnectionLost(String reason) {
return 'Connection lost: $reason';
}
@override
String audioStatsLine(int sent, int received, String ptt) {
return 'TX $sent frames • RX $received frames • PTT $ptt';
@@ -54,6 +54,16 @@ class AppL10nZh extends AppL10n {
return '错误:$message';
}
@override
String statusReconnecting(int attempt, int delay) {
return '正在重新连接……第 $attempt 次尝试,$delay 秒后';
}
@override
String statusConnectionLost(String reason) {
return '连接已断开:$reason';
}
@override
String audioStatsLine(int sent, int received, String ptt) {
return '发送 $sent 帧 • 接收 $received 帧 • PTT $ptt';
+84
View File
@@ -60,9 +60,57 @@ class _BetaHomeState extends State<_BetaHome> {
bool _audioStarted = false;
rust.BridgeAudioStats? _audioStats;
Timer? _statsTimer;
StreamSubscription<rust.BridgeEvent>? _eventsSub;
// A.6 reconnect banner state.
String? _lostReason;
int? _reconnectAttempt;
int? _reconnectDelay;
@override
void initState() {
super.initState();
_eventsSub = rust.eventsStream().listen(_onEvent);
}
void _onEvent(rust.BridgeEvent evt) {
if (!mounted) return;
switch (evt) {
case rust.BridgeEvent_Connected():
setState(() {
_phase = _Phase.connected;
_lostReason = null;
_reconnectAttempt = null;
_reconnectDelay = null;
});
case rust.BridgeEvent_Lost(:final reason):
setState(() {
_lostReason = reason;
_reconnectAttempt = null;
_reconnectDelay = null;
});
case rust.BridgeEvent_Reconnecting(:final attempt, :final delaySecs):
setState(() {
_reconnectAttempt = attempt;
_reconnectDelay = delaySecs;
});
case rust.BridgeEvent_Disconnected():
setState(() {
_phase = _Phase.idle;
_lostReason = null;
_reconnectAttempt = null;
_reconnectDelay = null;
});
case rust.BridgeEvent_AudioStarted():
setState(() => _audioStarted = true);
case rust.BridgeEvent_AudioStopped():
setState(() => _audioStarted = false);
}
}
@override
void dispose() {
_eventsSub?.cancel();
_statsTimer?.cancel();
_hostCtl.dispose();
_nickCtl.dispose();
@@ -201,6 +249,42 @@ class _BetaHomeState extends State<_BetaHome> {
),
const SizedBox(height: 12),
Text(statusText(), style: theme.textTheme.titleMedium),
if (_lostReason != null || _reconnectAttempt != null) ...[
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: theme.colorScheme.errorContainer,
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
color: theme.colorScheme.onErrorContainer,
),
),
const SizedBox(width: 10),
Expanded(
child: Text(
_reconnectAttempt != null
? l10n.statusReconnecting(
_reconnectAttempt!,
_reconnectDelay ?? 0,
)
: l10n.statusConnectionLost(_lostReason ?? ''),
style: TextStyle(
color: theme.colorScheme.onErrorContainer,
),
),
),
],
),
),
],
const SizedBox(height: 12),
if (_phase == _Phase.idle) ...[
_ConnectForm(
+48 -1
View File
@@ -6,9 +6,11 @@
import 'frb_generated.dart';
import 'lib.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'package:freezed_annotation/freezed_annotation.dart' hide protected;
part 'api.freezed.dart';
// These functions are ignored because they are not marked as `pub`: `runtime`, `session`
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `clone`, `clone`, `fmt`, `fmt`, `fmt`, `fmt`, `from`
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `clone`, `clone`, `clone`, `fmt`, `fmt`, `fmt`, `fmt`, `fmt`, `from`, `from`
/// Connect to a TeamSpeak-compatible server and return the initial
/// state snapshot. Honours the DEC-006 single-connection invariant
@@ -35,6 +37,13 @@ Future<void> startAudio() => RustLib.instance.api.crateApiStartAudio();
Future<void> setPtt({required bool active}) =>
RustLib.instance.api.crateApiSetPtt(active: active);
/// Subscribe to lifecycle events. Each call yields a fresh
/// subscription; multiple subscribers are supported. On slow
/// consumers, events are dropped rather than blocking the supervisor
/// (consistent with `tokio::sync::broadcast::Receiver` semantics).
Stream<BridgeEvent> eventsStream() =>
RustLib.instance.api.crateApiEventsStream();
/// Read audio statistics. Errors if no connection or audio not started.
Future<BridgeAudioStats> audioStats() =>
RustLib.instance.api.crateApiAudioStats();
@@ -138,6 +147,44 @@ class BridgeClient {
name == other.name;
}
@freezed
sealed class BridgeEvent with _$BridgeEvent {
const BridgeEvent._();
/// Initial connect succeeded, or a reconnect attempt succeeded.
const factory BridgeEvent.connected({
/// Server name reported by the server snapshot.
required String serverName,
}) = BridgeEvent_Connected;
/// Connection lost; supervisor will retry.
const factory BridgeEvent.lost({
/// Reason classification from the protocol layer.
required String reason,
}) = BridgeEvent_Lost;
/// Supervisor is sleeping before its next reconnect attempt.
const factory BridgeEvent.reconnecting({
/// 1-based attempt counter for the current outage.
required int attempt,
/// Seconds the supervisor will sleep before this attempt.
required int delaySecs,
}) = BridgeEvent_Reconnecting;
/// Session ended (user-requested disconnect or unrecoverable).
const factory BridgeEvent.disconnected({
/// Reason classification.
required String reason,
}) = BridgeEvent_Disconnected;
/// Audio engine started.
const factory BridgeEvent.audioStarted() = BridgeEvent_AudioStarted;
/// Audio engine stopped.
const factory BridgeEvent.audioStopped() = BridgeEvent_AudioStopped;
}
/// Server snapshot as seen by Dart.
class BridgeSnapshot {
/// Server name.
@@ -0,0 +1,533 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'api.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$BridgeEvent {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeEvent);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString() {
return 'BridgeEvent()';
}
}
/// @nodoc
class $BridgeEventCopyWith<$Res> {
$BridgeEventCopyWith(BridgeEvent _, $Res Function(BridgeEvent) __);
}
/// Adds pattern-matching-related methods to [BridgeEvent].
extension BridgeEventPatterns on BridgeEvent {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( BridgeEvent_Connected value)? connected,TResult Function( BridgeEvent_Lost value)? lost,TResult Function( BridgeEvent_Reconnecting value)? reconnecting,TResult Function( BridgeEvent_Disconnected value)? disconnected,TResult Function( BridgeEvent_AudioStarted value)? audioStarted,TResult Function( BridgeEvent_AudioStopped value)? audioStopped,required TResult orElse(),}){
final _that = this;
switch (_that) {
case BridgeEvent_Connected() when connected != null:
return connected(_that);case BridgeEvent_Lost() when lost != null:
return lost(_that);case BridgeEvent_Reconnecting() when reconnecting != null:
return reconnecting(_that);case BridgeEvent_Disconnected() when disconnected != null:
return disconnected(_that);case BridgeEvent_AudioStarted() when audioStarted != null:
return audioStarted(_that);case BridgeEvent_AudioStopped() when audioStopped != null:
return audioStopped(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( BridgeEvent_Connected value) connected,required TResult Function( BridgeEvent_Lost value) lost,required TResult Function( BridgeEvent_Reconnecting value) reconnecting,required TResult Function( BridgeEvent_Disconnected value) disconnected,required TResult Function( BridgeEvent_AudioStarted value) audioStarted,required TResult Function( BridgeEvent_AudioStopped value) audioStopped,}){
final _that = this;
switch (_that) {
case BridgeEvent_Connected():
return connected(_that);case BridgeEvent_Lost():
return lost(_that);case BridgeEvent_Reconnecting():
return reconnecting(_that);case BridgeEvent_Disconnected():
return disconnected(_that);case BridgeEvent_AudioStarted():
return audioStarted(_that);case BridgeEvent_AudioStopped():
return audioStopped(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( BridgeEvent_Connected value)? connected,TResult? Function( BridgeEvent_Lost value)? lost,TResult? Function( BridgeEvent_Reconnecting value)? reconnecting,TResult? Function( BridgeEvent_Disconnected value)? disconnected,TResult? Function( BridgeEvent_AudioStarted value)? audioStarted,TResult? Function( BridgeEvent_AudioStopped value)? audioStopped,}){
final _that = this;
switch (_that) {
case BridgeEvent_Connected() when connected != null:
return connected(_that);case BridgeEvent_Lost() when lost != null:
return lost(_that);case BridgeEvent_Reconnecting() when reconnecting != null:
return reconnecting(_that);case BridgeEvent_Disconnected() when disconnected != null:
return disconnected(_that);case BridgeEvent_AudioStarted() when audioStarted != null:
return audioStarted(_that);case BridgeEvent_AudioStopped() when audioStopped != null:
return audioStopped(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String serverName)? connected,TResult Function( String reason)? lost,TResult Function( int attempt, int delaySecs)? reconnecting,TResult Function( String reason)? disconnected,TResult Function()? audioStarted,TResult Function()? audioStopped,required TResult orElse(),}) {final _that = this;
switch (_that) {
case BridgeEvent_Connected() when connected != null:
return connected(_that.serverName);case BridgeEvent_Lost() when lost != null:
return lost(_that.reason);case BridgeEvent_Reconnecting() when reconnecting != null:
return reconnecting(_that.attempt,_that.delaySecs);case BridgeEvent_Disconnected() when disconnected != null:
return disconnected(_that.reason);case BridgeEvent_AudioStarted() when audioStarted != null:
return audioStarted();case BridgeEvent_AudioStopped() when audioStopped != null:
return audioStopped();case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String serverName) connected,required TResult Function( String reason) lost,required TResult Function( int attempt, int delaySecs) reconnecting,required TResult Function( String reason) disconnected,required TResult Function() audioStarted,required TResult Function() audioStopped,}) {final _that = this;
switch (_that) {
case BridgeEvent_Connected():
return connected(_that.serverName);case BridgeEvent_Lost():
return lost(_that.reason);case BridgeEvent_Reconnecting():
return reconnecting(_that.attempt,_that.delaySecs);case BridgeEvent_Disconnected():
return disconnected(_that.reason);case BridgeEvent_AudioStarted():
return audioStarted();case BridgeEvent_AudioStopped():
return audioStopped();}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String serverName)? connected,TResult? Function( String reason)? lost,TResult? Function( int attempt, int delaySecs)? reconnecting,TResult? Function( String reason)? disconnected,TResult? Function()? audioStarted,TResult? Function()? audioStopped,}) {final _that = this;
switch (_that) {
case BridgeEvent_Connected() when connected != null:
return connected(_that.serverName);case BridgeEvent_Lost() when lost != null:
return lost(_that.reason);case BridgeEvent_Reconnecting() when reconnecting != null:
return reconnecting(_that.attempt,_that.delaySecs);case BridgeEvent_Disconnected() when disconnected != null:
return disconnected(_that.reason);case BridgeEvent_AudioStarted() when audioStarted != null:
return audioStarted();case BridgeEvent_AudioStopped() when audioStopped != null:
return audioStopped();case _:
return null;
}
}
}
/// @nodoc
class BridgeEvent_Connected extends BridgeEvent {
const BridgeEvent_Connected({required this.serverName}): super._();
/// Server name reported by the server snapshot.
final String serverName;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$BridgeEvent_ConnectedCopyWith<BridgeEvent_Connected> get copyWith => _$BridgeEvent_ConnectedCopyWithImpl<BridgeEvent_Connected>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeEvent_Connected&&(identical(other.serverName, serverName) || other.serverName == serverName));
}
@override
int get hashCode => Object.hash(runtimeType,serverName);
@override
String toString() {
return 'BridgeEvent.connected(serverName: $serverName)';
}
}
/// @nodoc
abstract mixin class $BridgeEvent_ConnectedCopyWith<$Res> implements $BridgeEventCopyWith<$Res> {
factory $BridgeEvent_ConnectedCopyWith(BridgeEvent_Connected value, $Res Function(BridgeEvent_Connected) _then) = _$BridgeEvent_ConnectedCopyWithImpl;
@useResult
$Res call({
String serverName
});
}
/// @nodoc
class _$BridgeEvent_ConnectedCopyWithImpl<$Res>
implements $BridgeEvent_ConnectedCopyWith<$Res> {
_$BridgeEvent_ConnectedCopyWithImpl(this._self, this._then);
final BridgeEvent_Connected _self;
final $Res Function(BridgeEvent_Connected) _then;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? serverName = null,}) {
return _then(BridgeEvent_Connected(
serverName: null == serverName ? _self.serverName : serverName // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class BridgeEvent_Lost extends BridgeEvent {
const BridgeEvent_Lost({required this.reason}): super._();
/// Reason classification from the protocol layer.
final String reason;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$BridgeEvent_LostCopyWith<BridgeEvent_Lost> get copyWith => _$BridgeEvent_LostCopyWithImpl<BridgeEvent_Lost>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeEvent_Lost&&(identical(other.reason, reason) || other.reason == reason));
}
@override
int get hashCode => Object.hash(runtimeType,reason);
@override
String toString() {
return 'BridgeEvent.lost(reason: $reason)';
}
}
/// @nodoc
abstract mixin class $BridgeEvent_LostCopyWith<$Res> implements $BridgeEventCopyWith<$Res> {
factory $BridgeEvent_LostCopyWith(BridgeEvent_Lost value, $Res Function(BridgeEvent_Lost) _then) = _$BridgeEvent_LostCopyWithImpl;
@useResult
$Res call({
String reason
});
}
/// @nodoc
class _$BridgeEvent_LostCopyWithImpl<$Res>
implements $BridgeEvent_LostCopyWith<$Res> {
_$BridgeEvent_LostCopyWithImpl(this._self, this._then);
final BridgeEvent_Lost _self;
final $Res Function(BridgeEvent_Lost) _then;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? reason = null,}) {
return _then(BridgeEvent_Lost(
reason: null == reason ? _self.reason : reason // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class BridgeEvent_Reconnecting extends BridgeEvent {
const BridgeEvent_Reconnecting({required this.attempt, required this.delaySecs}): super._();
/// 1-based attempt counter for the current outage.
final int attempt;
/// Seconds the supervisor will sleep before this attempt.
final int delaySecs;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$BridgeEvent_ReconnectingCopyWith<BridgeEvent_Reconnecting> get copyWith => _$BridgeEvent_ReconnectingCopyWithImpl<BridgeEvent_Reconnecting>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeEvent_Reconnecting&&(identical(other.attempt, attempt) || other.attempt == attempt)&&(identical(other.delaySecs, delaySecs) || other.delaySecs == delaySecs));
}
@override
int get hashCode => Object.hash(runtimeType,attempt,delaySecs);
@override
String toString() {
return 'BridgeEvent.reconnecting(attempt: $attempt, delaySecs: $delaySecs)';
}
}
/// @nodoc
abstract mixin class $BridgeEvent_ReconnectingCopyWith<$Res> implements $BridgeEventCopyWith<$Res> {
factory $BridgeEvent_ReconnectingCopyWith(BridgeEvent_Reconnecting value, $Res Function(BridgeEvent_Reconnecting) _then) = _$BridgeEvent_ReconnectingCopyWithImpl;
@useResult
$Res call({
int attempt, int delaySecs
});
}
/// @nodoc
class _$BridgeEvent_ReconnectingCopyWithImpl<$Res>
implements $BridgeEvent_ReconnectingCopyWith<$Res> {
_$BridgeEvent_ReconnectingCopyWithImpl(this._self, this._then);
final BridgeEvent_Reconnecting _self;
final $Res Function(BridgeEvent_Reconnecting) _then;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? attempt = null,Object? delaySecs = null,}) {
return _then(BridgeEvent_Reconnecting(
attempt: null == attempt ? _self.attempt : attempt // ignore: cast_nullable_to_non_nullable
as int,delaySecs: null == delaySecs ? _self.delaySecs : delaySecs // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// @nodoc
class BridgeEvent_Disconnected extends BridgeEvent {
const BridgeEvent_Disconnected({required this.reason}): super._();
/// Reason classification.
final String reason;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$BridgeEvent_DisconnectedCopyWith<BridgeEvent_Disconnected> get copyWith => _$BridgeEvent_DisconnectedCopyWithImpl<BridgeEvent_Disconnected>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeEvent_Disconnected&&(identical(other.reason, reason) || other.reason == reason));
}
@override
int get hashCode => Object.hash(runtimeType,reason);
@override
String toString() {
return 'BridgeEvent.disconnected(reason: $reason)';
}
}
/// @nodoc
abstract mixin class $BridgeEvent_DisconnectedCopyWith<$Res> implements $BridgeEventCopyWith<$Res> {
factory $BridgeEvent_DisconnectedCopyWith(BridgeEvent_Disconnected value, $Res Function(BridgeEvent_Disconnected) _then) = _$BridgeEvent_DisconnectedCopyWithImpl;
@useResult
$Res call({
String reason
});
}
/// @nodoc
class _$BridgeEvent_DisconnectedCopyWithImpl<$Res>
implements $BridgeEvent_DisconnectedCopyWith<$Res> {
_$BridgeEvent_DisconnectedCopyWithImpl(this._self, this._then);
final BridgeEvent_Disconnected _self;
final $Res Function(BridgeEvent_Disconnected) _then;
/// Create a copy of BridgeEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? reason = null,}) {
return _then(BridgeEvent_Disconnected(
reason: null == reason ? _self.reason : reason // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class BridgeEvent_AudioStarted extends BridgeEvent {
const BridgeEvent_AudioStarted(): super._();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeEvent_AudioStarted);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString() {
return 'BridgeEvent.audioStarted()';
}
}
/// @nodoc
class BridgeEvent_AudioStopped extends BridgeEvent {
const BridgeEvent_AudioStopped(): super._();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeEvent_AudioStopped);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString() {
return 'BridgeEvent.audioStopped()';
}
}
// dart format on
@@ -67,7 +67,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
String get codegenVersion => '2.12.0';
@override
int get rustContentHash => 1944264248;
int get rustContentHash => -1896742393;
static const kDefaultExternalLibraryLoaderConfig =
ExternalLibraryLoaderConfig(
@@ -90,6 +90,8 @@ abstract class RustLibApi extends BaseApi {
Future<void> crateApiDisconnect();
Stream<BridgeEvent> crateApiEventsStream();
Future<bool> crateApiIsConnected();
Future<void> crateApiSetPtt({required bool active});
@@ -220,6 +222,38 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
TaskConstMeta get kCrateApiDisconnectConstMeta =>
const TaskConstMeta(debugName: "disconnect", argNames: []);
@override
Stream<BridgeEvent> crateApiEventsStream() {
final sink = RustStreamSink<BridgeEvent>();
unawaited(
handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_StreamSink_bridge_event_Sse(sink, serializer);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 5,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_unit,
decodeErrorData: sse_decode_bridge_error,
),
constMeta: kCrateApiEventsStreamConstMeta,
argValues: [sink],
apiImpl: this,
),
),
);
return sink.stream;
}
TaskConstMeta get kCrateApiEventsStreamConstMeta =>
const TaskConstMeta(debugName: "events_stream", argNames: ["sink"]);
@override
Future<bool> crateApiIsConnected() {
return handler.executeNormal(
@@ -229,7 +263,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 5,
funcId: 6,
port: port_,
);
},
@@ -257,7 +291,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 6,
funcId: 7,
port: port_,
);
},
@@ -284,7 +318,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 7,
funcId: 8,
port: port_,
);
},
@@ -311,7 +345,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 8,
funcId: 9,
port: port_,
);
},
@@ -329,6 +363,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
TaskConstMeta get kCrateApiStartAudioConstMeta =>
const TaskConstMeta(debugName: "start_audio", argNames: []);
@protected
AnyhowException dco_decode_AnyhowException(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return AnyhowException(raw as String);
}
@protected
RustStreamSink<BridgeEvent> dco_decode_StreamSink_bridge_event_Sse(
dynamic raw,
) {
// Codec=Dco (DartCObject based), see doc to use other codecs
throw UnimplementedError();
}
@protected
String dco_decode_String(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -388,18 +436,47 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
case 0:
return BridgeError_InvalidCommand(dco_decode_String(raw[1]));
case 1:
return BridgeError_Connection(dco_decode_String(raw[1]));
return BridgeError_DnsFailed(
host: dco_decode_String(raw[1]),
reason: dco_decode_String(raw[2]),
);
case 2:
return BridgeError_NotConnected();
return BridgeError_Connection(dco_decode_String(raw[1]));
case 3:
return BridgeError_AlreadyConnected();
return BridgeError_NotConnected();
case 4:
return BridgeError_AlreadyConnected();
case 5:
return BridgeError_Unmapped(dco_decode_String(raw[1]));
default:
throw Exception("unreachable");
}
}
@protected
BridgeEvent dco_decode_bridge_event(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
switch (raw[0]) {
case 0:
return BridgeEvent_Connected(serverName: dco_decode_String(raw[1]));
case 1:
return BridgeEvent_Lost(reason: dco_decode_String(raw[1]));
case 2:
return BridgeEvent_Reconnecting(
attempt: dco_decode_u_32(raw[1]),
delaySecs: dco_decode_u_32(raw[2]),
);
case 3:
return BridgeEvent_Disconnected(reason: dco_decode_String(raw[1]));
case 4:
return BridgeEvent_AudioStarted();
case 5:
return BridgeEvent_AudioStopped();
default:
throw Exception("unreachable");
}
}
@protected
BridgeSnapshot dco_decode_bridge_snapshot(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -464,6 +541,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return;
}
@protected
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var inner = sse_decode_String(deserializer);
return AnyhowException(inner);
}
@protected
RustStreamSink<BridgeEvent> sse_decode_StreamSink_bridge_event_Sse(
SseDeserializer deserializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
throw UnimplementedError('Unreachable ()');
}
@protected
String sse_decode_String(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -524,13 +616,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var var_field0 = sse_decode_String(deserializer);
return BridgeError_InvalidCommand(var_field0);
case 1:
var var_host = sse_decode_String(deserializer);
var var_reason = sse_decode_String(deserializer);
return BridgeError_DnsFailed(host: var_host, reason: var_reason);
case 2:
var var_field0 = sse_decode_String(deserializer);
return BridgeError_Connection(var_field0);
case 2:
return BridgeError_NotConnected();
case 3:
return BridgeError_AlreadyConnected();
return BridgeError_NotConnected();
case 4:
return BridgeError_AlreadyConnected();
case 5:
var var_field0 = sse_decode_String(deserializer);
return BridgeError_Unmapped(var_field0);
default:
@@ -538,6 +634,37 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
BridgeEvent sse_decode_bridge_event(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var tag_ = sse_decode_i_32(deserializer);
switch (tag_) {
case 0:
var var_serverName = sse_decode_String(deserializer);
return BridgeEvent_Connected(serverName: var_serverName);
case 1:
var var_reason = sse_decode_String(deserializer);
return BridgeEvent_Lost(reason: var_reason);
case 2:
var var_attempt = sse_decode_u_32(deserializer);
var var_delaySecs = sse_decode_u_32(deserializer);
return BridgeEvent_Reconnecting(
attempt: var_attempt,
delaySecs: var_delaySecs,
);
case 3:
var var_reason = sse_decode_String(deserializer);
return BridgeEvent_Disconnected(reason: var_reason);
case 4:
return BridgeEvent_AudioStarted();
case 5:
return BridgeEvent_AudioStopped();
default:
throw UnimplementedError('');
}
}
@protected
BridgeSnapshot sse_decode_bridge_snapshot(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -627,6 +754,32 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return deserializer.buffer.getInt32();
}
@protected
void sse_encode_AnyhowException(
AnyhowException self,
SseSerializer serializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.message, serializer);
}
@protected
void sse_encode_StreamSink_bridge_event_Sse(
RustStreamSink<BridgeEvent> self,
SseSerializer serializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(
self.setupAndSerialize(
codec: SseCodec(
decodeSuccessData: sse_decode_bridge_event,
decodeErrorData: sse_decode_AnyhowException,
),
),
serializer,
);
}
@protected
void sse_encode_String(String self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -674,19 +827,50 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
case BridgeError_InvalidCommand(field0: final field0):
sse_encode_i_32(0, serializer);
sse_encode_String(field0, serializer);
case BridgeError_Connection(field0: final field0):
case BridgeError_DnsFailed(host: final host, reason: final reason):
sse_encode_i_32(1, serializer);
sse_encode_String(host, serializer);
sse_encode_String(reason, serializer);
case BridgeError_Connection(field0: final field0):
sse_encode_i_32(2, serializer);
sse_encode_String(field0, serializer);
case BridgeError_NotConnected():
sse_encode_i_32(2, serializer);
case BridgeError_AlreadyConnected():
sse_encode_i_32(3, serializer);
case BridgeError_Unmapped(field0: final field0):
case BridgeError_AlreadyConnected():
sse_encode_i_32(4, serializer);
case BridgeError_Unmapped(field0: final field0):
sse_encode_i_32(5, serializer);
sse_encode_String(field0, serializer);
}
}
@protected
void sse_encode_bridge_event(BridgeEvent self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
switch (self) {
case BridgeEvent_Connected(serverName: final serverName):
sse_encode_i_32(0, serializer);
sse_encode_String(serverName, serializer);
case BridgeEvent_Lost(reason: final reason):
sse_encode_i_32(1, serializer);
sse_encode_String(reason, serializer);
case BridgeEvent_Reconnecting(
attempt: final attempt,
delaySecs: final delaySecs,
):
sse_encode_i_32(2, serializer);
sse_encode_u_32(attempt, serializer);
sse_encode_u_32(delaySecs, serializer);
case BridgeEvent_Disconnected(reason: final reason):
sse_encode_i_32(3, serializer);
sse_encode_String(reason, serializer);
case BridgeEvent_AudioStarted():
sse_encode_i_32(4, serializer);
case BridgeEvent_AudioStopped():
sse_encode_i_32(5, serializer);
}
}
@protected
void sse_encode_bridge_snapshot(
BridgeSnapshot self,
@@ -19,6 +19,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
required super.portManager,
});
@protected
AnyhowException dco_decode_AnyhowException(dynamic raw);
@protected
RustStreamSink<BridgeEvent> dco_decode_StreamSink_bridge_event_Sse(
dynamic raw,
);
@protected
String dco_decode_String(dynamic raw);
@@ -37,6 +45,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
BridgeError dco_decode_bridge_error(dynamic raw);
@protected
BridgeEvent dco_decode_bridge_event(dynamic raw);
@protected
BridgeSnapshot dco_decode_bridge_snapshot(dynamic raw);
@@ -64,6 +75,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void dco_decode_unit(dynamic raw);
@protected
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
@protected
RustStreamSink<BridgeEvent> sse_decode_StreamSink_bridge_event_Sse(
SseDeserializer deserializer,
);
@protected
String sse_decode_String(SseDeserializer deserializer);
@@ -82,6 +101,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
BridgeError sse_decode_bridge_error(SseDeserializer deserializer);
@protected
BridgeEvent sse_decode_bridge_event(SseDeserializer deserializer);
@protected
BridgeSnapshot sse_decode_bridge_snapshot(SseDeserializer deserializer);
@@ -116,6 +138,18 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
int sse_decode_i_32(SseDeserializer deserializer);
@protected
void sse_encode_AnyhowException(
AnyhowException self,
SseSerializer serializer,
);
@protected
void sse_encode_StreamSink_bridge_event_Sse(
RustStreamSink<BridgeEvent> self,
SseSerializer serializer,
);
@protected
void sse_encode_String(String self, SseSerializer serializer);
@@ -137,6 +171,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_bridge_error(BridgeError self, SseSerializer serializer);
@protected
void sse_encode_bridge_event(BridgeEvent self, SseSerializer serializer);
@protected
void sse_encode_bridge_snapshot(
BridgeSnapshot self,
@@ -21,6 +21,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
required super.portManager,
});
@protected
AnyhowException dco_decode_AnyhowException(dynamic raw);
@protected
RustStreamSink<BridgeEvent> dco_decode_StreamSink_bridge_event_Sse(
dynamic raw,
);
@protected
String dco_decode_String(dynamic raw);
@@ -39,6 +47,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
BridgeError dco_decode_bridge_error(dynamic raw);
@protected
BridgeEvent dco_decode_bridge_event(dynamic raw);
@protected
BridgeSnapshot dco_decode_bridge_snapshot(dynamic raw);
@@ -66,6 +77,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void dco_decode_unit(dynamic raw);
@protected
AnyhowException sse_decode_AnyhowException(SseDeserializer deserializer);
@protected
RustStreamSink<BridgeEvent> sse_decode_StreamSink_bridge_event_Sse(
SseDeserializer deserializer,
);
@protected
String sse_decode_String(SseDeserializer deserializer);
@@ -84,6 +103,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
BridgeError sse_decode_bridge_error(SseDeserializer deserializer);
@protected
BridgeEvent sse_decode_bridge_event(SseDeserializer deserializer);
@protected
BridgeSnapshot sse_decode_bridge_snapshot(SseDeserializer deserializer);
@@ -118,6 +140,18 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
int sse_decode_i_32(SseDeserializer deserializer);
@protected
void sse_encode_AnyhowException(
AnyhowException self,
SseSerializer serializer,
);
@protected
void sse_encode_StreamSink_bridge_event_Sse(
RustStreamSink<BridgeEvent> self,
SseSerializer serializer,
);
@protected
void sse_encode_String(String self, SseSerializer serializer);
@@ -139,6 +173,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_bridge_error(BridgeError self, SseSerializer serializer);
@protected
void sse_encode_bridge_event(BridgeEvent self, SseSerializer serializer);
@protected
void sse_encode_bridge_snapshot(
BridgeSnapshot self,
@@ -16,6 +16,16 @@ sealed class BridgeError with _$BridgeError implements FrbException {
const factory BridgeError.invalidCommand(String field0) =
BridgeError_InvalidCommand;
/// Hostname resolution failed. Distinct from `Connection` so the
/// UI can show a meaningful "Server not found" message.
const factory BridgeError.dnsFailed({
/// The hostname (or `host:port`) the caller submitted.
required String host,
/// Reason from the platform resolver.
required String reason,
}) = BridgeError_DnsFailed;
/// Connection layer failure (typed-mapped from CoreError).
const factory BridgeError.connection(String field0) = BridgeError_Connection;
@@ -55,11 +55,12 @@ extension BridgeErrorPatterns on BridgeError {
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( BridgeError_InvalidCommand value)? invalidCommand,TResult Function( BridgeError_Connection value)? connection,TResult Function( BridgeError_NotConnected value)? notConnected,TResult Function( BridgeError_AlreadyConnected value)? alreadyConnected,TResult Function( BridgeError_Unmapped value)? unmapped,required TResult orElse(),}){
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( BridgeError_InvalidCommand value)? invalidCommand,TResult Function( BridgeError_DnsFailed value)? dnsFailed,TResult Function( BridgeError_Connection value)? connection,TResult Function( BridgeError_NotConnected value)? notConnected,TResult Function( BridgeError_AlreadyConnected value)? alreadyConnected,TResult Function( BridgeError_Unmapped value)? unmapped,required TResult orElse(),}){
final _that = this;
switch (_that) {
case BridgeError_InvalidCommand() when invalidCommand != null:
return invalidCommand(_that);case BridgeError_Connection() when connection != null:
return invalidCommand(_that);case BridgeError_DnsFailed() when dnsFailed != null:
return dnsFailed(_that);case BridgeError_Connection() when connection != null:
return connection(_that);case BridgeError_NotConnected() when notConnected != null:
return notConnected(_that);case BridgeError_AlreadyConnected() when alreadyConnected != null:
return alreadyConnected(_that);case BridgeError_Unmapped() when unmapped != null:
@@ -81,11 +82,12 @@ return unmapped(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( BridgeError_InvalidCommand value) invalidCommand,required TResult Function( BridgeError_Connection value) connection,required TResult Function( BridgeError_NotConnected value) notConnected,required TResult Function( BridgeError_AlreadyConnected value) alreadyConnected,required TResult Function( BridgeError_Unmapped value) unmapped,}){
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( BridgeError_InvalidCommand value) invalidCommand,required TResult Function( BridgeError_DnsFailed value) dnsFailed,required TResult Function( BridgeError_Connection value) connection,required TResult Function( BridgeError_NotConnected value) notConnected,required TResult Function( BridgeError_AlreadyConnected value) alreadyConnected,required TResult Function( BridgeError_Unmapped value) unmapped,}){
final _that = this;
switch (_that) {
case BridgeError_InvalidCommand():
return invalidCommand(_that);case BridgeError_Connection():
return invalidCommand(_that);case BridgeError_DnsFailed():
return dnsFailed(_that);case BridgeError_Connection():
return connection(_that);case BridgeError_NotConnected():
return notConnected(_that);case BridgeError_AlreadyConnected():
return alreadyConnected(_that);case BridgeError_Unmapped():
@@ -103,11 +105,12 @@ return unmapped(_that);}
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( BridgeError_InvalidCommand value)? invalidCommand,TResult? Function( BridgeError_Connection value)? connection,TResult? Function( BridgeError_NotConnected value)? notConnected,TResult? Function( BridgeError_AlreadyConnected value)? alreadyConnected,TResult? Function( BridgeError_Unmapped value)? unmapped,}){
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( BridgeError_InvalidCommand value)? invalidCommand,TResult? Function( BridgeError_DnsFailed value)? dnsFailed,TResult? Function( BridgeError_Connection value)? connection,TResult? Function( BridgeError_NotConnected value)? notConnected,TResult? Function( BridgeError_AlreadyConnected value)? alreadyConnected,TResult? Function( BridgeError_Unmapped value)? unmapped,}){
final _that = this;
switch (_that) {
case BridgeError_InvalidCommand() when invalidCommand != null:
return invalidCommand(_that);case BridgeError_Connection() when connection != null:
return invalidCommand(_that);case BridgeError_DnsFailed() when dnsFailed != null:
return dnsFailed(_that);case BridgeError_Connection() when connection != null:
return connection(_that);case BridgeError_NotConnected() when notConnected != null:
return notConnected(_that);case BridgeError_AlreadyConnected() when alreadyConnected != null:
return alreadyConnected(_that);case BridgeError_Unmapped() when unmapped != null:
@@ -128,10 +131,11 @@ return unmapped(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String field0)? invalidCommand,TResult Function( String field0)? connection,TResult Function()? notConnected,TResult Function()? alreadyConnected,TResult Function( String field0)? unmapped,required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String field0)? invalidCommand,TResult Function( String host, String reason)? dnsFailed,TResult Function( String field0)? connection,TResult Function()? notConnected,TResult Function()? alreadyConnected,TResult Function( String field0)? unmapped,required TResult orElse(),}) {final _that = this;
switch (_that) {
case BridgeError_InvalidCommand() when invalidCommand != null:
return invalidCommand(_that.field0);case BridgeError_Connection() when connection != null:
return invalidCommand(_that.field0);case BridgeError_DnsFailed() when dnsFailed != null:
return dnsFailed(_that.host,_that.reason);case BridgeError_Connection() when connection != null:
return connection(_that.field0);case BridgeError_NotConnected() when notConnected != null:
return notConnected();case BridgeError_AlreadyConnected() when alreadyConnected != null:
return alreadyConnected();case BridgeError_Unmapped() when unmapped != null:
@@ -153,10 +157,11 @@ return unmapped(_that.field0);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String field0) invalidCommand,required TResult Function( String field0) connection,required TResult Function() notConnected,required TResult Function() alreadyConnected,required TResult Function( String field0) unmapped,}) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String field0) invalidCommand,required TResult Function( String host, String reason) dnsFailed,required TResult Function( String field0) connection,required TResult Function() notConnected,required TResult Function() alreadyConnected,required TResult Function( String field0) unmapped,}) {final _that = this;
switch (_that) {
case BridgeError_InvalidCommand():
return invalidCommand(_that.field0);case BridgeError_Connection():
return invalidCommand(_that.field0);case BridgeError_DnsFailed():
return dnsFailed(_that.host,_that.reason);case BridgeError_Connection():
return connection(_that.field0);case BridgeError_NotConnected():
return notConnected();case BridgeError_AlreadyConnected():
return alreadyConnected();case BridgeError_Unmapped():
@@ -174,10 +179,11 @@ return unmapped(_that.field0);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String field0)? invalidCommand,TResult? Function( String field0)? connection,TResult? Function()? notConnected,TResult? Function()? alreadyConnected,TResult? Function( String field0)? unmapped,}) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String field0)? invalidCommand,TResult? Function( String host, String reason)? dnsFailed,TResult? Function( String field0)? connection,TResult? Function()? notConnected,TResult? Function()? alreadyConnected,TResult? Function( String field0)? unmapped,}) {final _that = this;
switch (_that) {
case BridgeError_InvalidCommand() when invalidCommand != null:
return invalidCommand(_that.field0);case BridgeError_Connection() when connection != null:
return invalidCommand(_that.field0);case BridgeError_DnsFailed() when dnsFailed != null:
return dnsFailed(_that.host,_that.reason);case BridgeError_Connection() when connection != null:
return connection(_that.field0);case BridgeError_NotConnected() when notConnected != null:
return notConnected();case BridgeError_AlreadyConnected() when alreadyConnected != null:
return alreadyConnected();case BridgeError_Unmapped() when unmapped != null:
@@ -258,6 +264,76 @@ as String,
/// @nodoc
class BridgeError_DnsFailed extends BridgeError {
const BridgeError_DnsFailed({required this.host, required this.reason}): super._();
/// The hostname (or `host:port`) the caller submitted.
final String host;
/// Reason from the platform resolver.
final String reason;
/// Create a copy of BridgeError
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$BridgeError_DnsFailedCopyWith<BridgeError_DnsFailed> get copyWith => _$BridgeError_DnsFailedCopyWithImpl<BridgeError_DnsFailed>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BridgeError_DnsFailed&&(identical(other.host, host) || other.host == host)&&(identical(other.reason, reason) || other.reason == reason));
}
@override
int get hashCode => Object.hash(runtimeType,host,reason);
@override
String toString() {
return 'BridgeError.dnsFailed(host: $host, reason: $reason)';
}
}
/// @nodoc
abstract mixin class $BridgeError_DnsFailedCopyWith<$Res> implements $BridgeErrorCopyWith<$Res> {
factory $BridgeError_DnsFailedCopyWith(BridgeError_DnsFailed value, $Res Function(BridgeError_DnsFailed) _then) = _$BridgeError_DnsFailedCopyWithImpl;
@useResult
$Res call({
String host, String reason
});
}
/// @nodoc
class _$BridgeError_DnsFailedCopyWithImpl<$Res>
implements $BridgeError_DnsFailedCopyWith<$Res> {
_$BridgeError_DnsFailedCopyWithImpl(this._self, this._then);
final BridgeError_DnsFailed _self;
final $Res Function(BridgeError_DnsFailed) _then;
/// Create a copy of BridgeError
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? host = null,Object? reason = null,}) {
return _then(BridgeError_DnsFailed(
host: null == host ? _self.host : host // ignore: cast_nullable_to_non_nullable
as String,reason: null == reason ? _self.reason : reason // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class BridgeError_Connection extends BridgeError {
const BridgeError_Connection(this.field0): super._();