Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI with Material App #2307

Open
NoelJacob opened this issue Sep 20, 2024 · 9 comments
Open

UI with Material App #2307

NoelJacob opened this issue Sep 20, 2024 · 9 comments
Labels
enhancement New feature or request wontfix This will not be worked on

Comments

@NoelJacob
Copy link

NoelJacob commented Sep 20, 2024

I've seen the frb(ui_state) and frm(ui_mutation) and i honestly cannot appreciate enough as it is the best multiplatform dev solution I've seen in a while. 👏🏻

Looked at the code and it seems MaterialApp is generated by default and only nested widgets under that are required. I think if MaterialApp onwards if we could supply into runRustApp() with state. Like a replacement for runApp() it would be great. The widget style function supply could be built upon it I think. Maybe with a replacement for StatelessWidget?

@NoelJacob NoelJacob added the enhancement New feature or request label Sep 20, 2024
@NoelJacob
Copy link
Author

NoelJacob commented Sep 20, 2024

Instead of the following lines:

Future<void> runRustApp({
required Widget Function(RustState state) body,
required RustState Function() state,
}) async {
await RustLib.init();
runApp(_MyApp(body: body, state: state()));
}
// improve typing later
class _MyApp extends StatefulWidget {
final Widget Function(RustState state) body;
final RustState state;
const _MyApp({
required this.body,
required this.state,
});
@override
State<_MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<_MyApp> {
late final BaseRustState baseState;
@override
void initState() {
super.initState();
baseState = BaseRustState(onMutate: () {
if (mounted) setState(() {});
});
widget.state.setBaseState(baseState: baseState);
}
@override
void dispose() {
baseState.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// We can allow users to customize MaterialApp/Scaffold by exposing another argument
// like `Widget Function() app`; but for simplicity let's customize the `body` by default.
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: Scaffold(body: widget.body(widget.state)),
);
}
}

If these lines were genereated:

abstract class RustWidget extends StatefulWidget {
  final RustState state;

  const RustWidget({super.key, required this.state});

  @override
  State<RustWidget> createState() => _RustWidgetState();

  Widget build(BuildContext context);
}

class _RustWidgetState extends State<RustWidget> {
  late final BaseRustState baseState;

  @override
  void initState() {
    super.initState();
    baseState = BaseRustState(onMutate: () {
      if (mounted) setState(() {});
    });
    widget.state.setBaseState(baseState: baseState);
  }

  @override
  void dispose() {
    baseState.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.build(context);
  }
}

We get an abstract class RustWidget that can replace StatefulWidgets.

Fork of ui_counter demo with replacements made in generated code manually: https://github.com/NoelJacob/flutter_rust_bridge/tree/ba12be4d6555295bd804a9d3c21277986ca01129/frb_example/rust_ui_counter/ui/lib

@fzyzcjy
Copy link
Owner

fzyzcjy commented Sep 21, 2024

That looks interesting!

Currently, a limitation of this super minimal solution is that, it hardcodes the BaseRustState class, so the proposed RustWidget may not have many subclasses.

Back to the runRustApp question, if we want to customize MaterialApp, we may

Future<void> runRustApp({ 
   Widget Function(RustState state)? builder, 
   Widget Function(RustState state)? body, 
   required RustState Function() state, 
 }) async { 
   await RustLib.init(); 
   runApp(_MyApp(builder: builder, body: body, state: state())); 
 } 
  
 // improve typing later 
 class _MyApp extends StatefulWidget { 
   final Widget Function(RustState state)? builder;
   final Widget Function(RustState state)? body;
   final RustState state; 
  
   const _MyApp({ 
     required this.builder, 
     required this.body, 
     required this.state, 
   }); 
  
   @override 
   State<_MyApp> createState() => _MyAppState(); 
 } 
  
 class _MyAppState extends State<_MyApp> { 
   late final BaseRustState baseState; 
  
   @override 
   void initState() { 
     super.initState(); 
     baseState = BaseRustState(onMutate: () { 
       if (mounted) setState(() {}); 
     }); 
     widget.state.setBaseState(baseState: baseState); 
   } 
  
   @override 
   void dispose() { 
     baseState.dispose(); 
     super.dispose(); 
   } 
  
   @override 
   Widget build(BuildContext context) { 
     return widget.builder(widget.state) ?? MaterialApp( 
       theme: ThemeData( 
         colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), 
         useMaterial3: true, 
       ), 
       home: Scaffold(body: widget.body(widget.state)), 
     ); 
   } 
 } 

Then if you want to customize the MaterialApp, just pass in builder arg

@NoelJacob
Copy link
Author

NoelJacob commented Sep 21, 2024

Could the BaseRustState be autogenerated?

Also the builder way looks waay more awesome. Seems like best of both worlds. But, wouldn't making this rebuild the full UI from MaterialApp onwards on state change?

@fzyzcjy
Copy link
Owner

fzyzcjy commented Sep 21, 2024

Seems I forgot what I have done months ago for this experimental feature... Yes you are right, looks like BaseRustState is an auto generated base class and thus can be used for all subclasses (or at least it should).

But, wouldn't making this rebuild the full UI from MaterialApp onwards on state change?

Yes and no. Firstly, yes it will trigger a rebuild from root. However, Flutter is smart, such that a rebuild is not a very heavy operation. But, if your app is complex and this causes jank, then yes you may want to do more complicated state management solution to avoid such rebuild from root. Then, the proposed RustWidget looks good. (So maybe we can have both the runRustApp-with-builder and the RustWidget available).

Btw, IMHO Flutter favors composition and callback than subclasses, thus a RustWidget may be something like:

abstract class RustWidget extends StatefulWidget {
  final RustState state;
  final Widget Function(RustState) builder;

  const RustWidget({super.key, required this.state, required this.builder});

  @override
  State<RustWidget> createState() => _RustWidgetState();
}

class _RustWidgetState extends State<RustWidget> {
  late final BaseRustState baseState;

  @override
  void initState() {
    super.initState();
    baseState = BaseRustState(onMutate: () {
      if (mounted) setState(() {});
    });
    widget.state.setBaseState(baseState: baseState);
  }

  @override
  void dispose() {
    baseState.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.build(context);
  }
}

@NoelJacob
Copy link
Author

NoelJacob commented Sep 21, 2024

Flutter favors composition and callback than subclasses

Oh okay.
Also another flaw in the RustWidget solution I think is that any change in state will trigger rebuild across every RustWidget. It would be cool if each RustWidget watches a particular value in RustState/state to see if rebuild is required. Is it possible in any way?

experimental feature

I think this the most complete multiplatform solution, NGL.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Sep 21, 2024

any change in state will trigger rebuild across every RustWidget.

any change in the specific state object will trigger rebuild across RustWidgets that listens to this state (i.e. RustWidget(state: THIS_OBJECT).

I think this the most complete multiplatform solution, NGL.

Happy to hear that!

@NoelJacob
Copy link
Author

NoelJacob commented Sep 21, 2024

Just wanted to inform that while doing this:

import 'package:flutter/material.dart';
import 'package:frb_example_rust_ui_counter/src/rust/app.dart';
import 'package:frb_example_rust_ui_counter/src/rust/frb_generated.dart';

void main() async {
  await RustLib.init();
  runApp(MyRustApp());
}

class MyRustApp extends StatelessWidget {
  final RustState x = RustState();
  MyRustApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: Scaffold(
        body: Column(
          children: <Widget>[
            RS1(state: x,),
            RS2(state: x,),
          ],
        ),
      ),
    );
  }
}


class RS1 extends RustWidget {
  const RS1({super.key, required super.state});

  @override
  Widget build(BuildContext context) {
    return  Column(
      children: <Widget>[
        Text('Count: ${state.count}'),
        TextButton(
          onPressed: state.increment,
          child: Text('+1'),
        ),
      ],
    );
  }
}

class RS2 extends RustWidget {
  const RS2({super.key, required super.state});

  @override
  Widget build(BuildContext context) {
    return  Column(
      children: <Widget>[
        Text('Count: ${state.count}'),
        TextButton(
          onPressed: state.increment,
          child: Text('+1'),
        ),
      ],
    );
  }
}

Only RS2 updates on clicking +1 button on RS1 or RS2. But if we comment out RS2 from the Scaffold, RS1 works properly.

The generated file is:

// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.4.0.

// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.4.0.

// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import

import 'app.dart';
import 'dart:async';
import 'dart:convert';
import 'frb_generated.dart';
import 'frb_generated.io.dart'
    if (dart.library.js_interop) 'frb_generated.web.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';

/// Main entrypoint of the Rust API
class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
  @internal
  static final instance = RustLib._();

  RustLib._();

  /// Initialize flutter_rust_bridge
  static Future<void> init({
    RustLibApi? api,
    BaseHandler? handler,
    ExternalLibrary? externalLibrary,
  }) async {
    await instance.initImpl(
      api: api,
      handler: handler,
      externalLibrary: externalLibrary,
    );
  }

  /// Initialize flutter_rust_bridge in mock mode.
  /// No libraries for FFI are loaded.
  static void initMock({
    required RustLibApi api,
  }) {
    instance.initMockImpl(
      api: api,
    );
  }

  /// Dispose flutter_rust_bridge
  ///
  /// The call to this function is optional, since flutter_rust_bridge (and everything else)
  /// is automatically disposed when the app stops.
  static void dispose() => instance.disposeImpl();

  @override
  ApiImplConstructor<RustLibApiImpl, RustLibWire> get apiImplConstructor =>
      RustLibApiImpl.new;

  @override
  WireConstructor<RustLibWire> get wireConstructor =>
      RustLibWire.fromExternalLibrary;

  @override
  Future<void> executeRustInitializers() async {}

  @override
  ExternalLibraryLoaderConfig get defaultExternalLibraryLoaderConfig =>
      kDefaultExternalLibraryLoaderConfig;

  @override
  String get codegenVersion => '2.4.0';

  @override
  int get rustContentHash => 686613453;

  static const kDefaultExternalLibraryLoaderConfig =
      ExternalLibraryLoaderConfig(
    stem: 'rust_lib_frb_example_rust_ui_counter',
    ioDirectory: '../target/release/',
    webPrefix: 'pkg/',
  );
}

abstract class RustLibApi extends BaseApi {
  int crateAppRustState2AutoAccessorGetCount({required RustState2 that});

  void crateAppRustState2AutoAccessorSetCount(
      {required RustState2 that, required int count});

  void crateAppRustState2Increment({required RustState2 that});

  RustState2 crateAppRustState2New();

  void crateAppRustState2SetBaseState(
      {required RustState2 that, required BaseRustState baseState});

  int crateAppRustStateAutoAccessorGetCount({required RustState that});

  void crateAppRustStateAutoAccessorSetCount(
      {required RustState that, required int count});

  void crateAppRustStateIncrement({required RustState that});

  RustState crateAppRustStateNew();

  void crateAppRustStateSetBaseState(
      {required RustState that, required BaseRustState baseState});

  Stream<void> crateFrbGeneratedBaseRustStateCreateNotifyUiStream(
      {required BaseRustState that});

  BaseRustState crateFrbGeneratedBaseRustStateEmpty();

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_BaseRustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_BaseRustState;

  CrossPlatformFinalizerArg
      get rust_arc_decrement_strong_count_BaseRustStatePtr;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState;

  CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_RustStatePtr;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState2;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState2;

  CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_RustState2Ptr;
}

class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
  RustLibApiImpl({
    required super.handler,
    required super.wire,
    required super.generalizedFrbRustBinding,
    required super.portManager,
  });

  @override
  int crateAppRustState2AutoAccessorGetCount({required RustState2 that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 1)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_i_32,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2AutoAccessorGetCountConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2AutoAccessorGetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_auto_accessor_get_count",
        argNames: ["that"],
      );

  @override
  void crateAppRustState2AutoAccessorSetCount(
      {required RustState2 that, required int count}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        sse_encode_i_32(count, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 2)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2AutoAccessorSetCountConstMeta,
      argValues: [that, count],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2AutoAccessorSetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_auto_accessor_set_count",
        argNames: ["that", "count"],
      );

  @override
  void crateAppRustState2Increment({required RustState2 that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 3)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2IncrementConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2IncrementConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_increment",
        argNames: ["that"],
      );

  @override
  RustState2 crateAppRustState2New() {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 4)!;
      },
      codec: SseCodec(
        decodeSuccessData:
            sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2NewConstMeta,
      argValues: [],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2NewConstMeta => const TaskConstMeta(
        debugName: "RustState2_new",
        argNames: [],
      );

  @override
  void crateAppRustState2SetBaseState(
      {required RustState2 that, required BaseRustState baseState}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
            baseState, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 5)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2SetBaseStateConstMeta,
      argValues: [that, baseState],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2SetBaseStateConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_set_base_state",
        argNames: ["that", "baseState"],
      );

  @override
  int crateAppRustStateAutoAccessorGetCount({required RustState that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 6)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_i_32,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateAutoAccessorGetCountConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateAutoAccessorGetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState_auto_accessor_get_count",
        argNames: ["that"],
      );

  @override
  void crateAppRustStateAutoAccessorSetCount(
      {required RustState that, required int count}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        sse_encode_i_32(count, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 7)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateAutoAccessorSetCountConstMeta,
      argValues: [that, count],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateAutoAccessorSetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState_auto_accessor_set_count",
        argNames: ["that", "count"],
      );

  @override
  void crateAppRustStateIncrement({required RustState that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 8)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateIncrementConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateIncrementConstMeta => const TaskConstMeta(
        debugName: "RustState_increment",
        argNames: ["that"],
      );

  @override
  RustState crateAppRustStateNew() {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 9)!;
      },
      codec: SseCodec(
        decodeSuccessData:
            sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateNewConstMeta,
      argValues: [],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateNewConstMeta => const TaskConstMeta(
        debugName: "RustState_new",
        argNames: [],
      );

  @override
  void crateAppRustStateSetBaseState(
      {required RustState that, required BaseRustState baseState}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
            baseState, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 10)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateSetBaseStateConstMeta,
      argValues: [that, baseState],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateSetBaseStateConstMeta =>
      const TaskConstMeta(
        debugName: "RustState_set_base_state",
        argNames: ["that", "baseState"],
      );

  @override
  Stream<void> crateFrbGeneratedBaseRustStateCreateNotifyUiStream(
      {required BaseRustState that}) {
    final sink = RustStreamSink<void>();
    handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
            that, serializer);
        sse_encode_StreamSink_unit_Sse(sink, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 11)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateFrbGeneratedBaseRustStateCreateNotifyUiStreamConstMeta,
      argValues: [that, sink],
      apiImpl: this,
    ));
    return sink.stream;
  }

  TaskConstMeta
      get kCrateFrbGeneratedBaseRustStateCreateNotifyUiStreamConstMeta =>
          const TaskConstMeta(
            debugName: "BaseRustState_create_notify_ui_stream",
            argNames: ["that", "sink"],
          );

  @override
  BaseRustState crateFrbGeneratedBaseRustStateEmpty() {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 12)!;
      },
      codec: SseCodec(
        decodeSuccessData:
            sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState,
        decodeErrorData: null,
      ),
      constMeta: kCrateFrbGeneratedBaseRustStateEmptyConstMeta,
      argValues: [],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateFrbGeneratedBaseRustStateEmptyConstMeta =>
      const TaskConstMeta(
        debugName: "BaseRustState_empty",
        argNames: [],
      );

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_BaseRustState => wire
          .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_BaseRustState => wire
          .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState => wire
          .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState => wire
          .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState2 => wire
          .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState2 => wire
          .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2;

  @protected
  AnyhowException dco_decode_AnyhowException(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return AnyhowException(raw as String);
  }

  @protected
  BaseRustState
      dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  BaseRustState
      dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  BaseRustState
      dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustStreamSink<void> dco_decode_StreamSink_unit_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
    return raw as String;
  }

  @protected
  int dco_decode_i_32(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return raw as int;
  }

  @protected
  Uint8List dco_decode_list_prim_u_8_strict(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return raw as Uint8List;
  }

  @protected
  int dco_decode_u_8(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return raw as int;
  }

  @protected
  void dco_decode_unit(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return;
  }

  @protected
  BigInt dco_decode_usize(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return dcoDecodeU64(raw);
  }

  @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
  BaseRustState
      sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  BaseRustState
      sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  BaseRustState
      sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustStreamSink<void> sse_decode_StreamSink_unit_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
    var inner = sse_decode_list_prim_u_8_strict(deserializer);
    return utf8.decoder.convert(inner);
  }

  @protected
  int sse_decode_i_32(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getInt32();
  }

  @protected
  Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    var len_ = sse_decode_i_32(deserializer);
    return deserializer.buffer.getUint8List(len_);
  }

  @protected
  int sse_decode_u_8(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getUint8();
  }

  @protected
  void sse_decode_unit(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
  }

  @protected
  BigInt sse_decode_usize(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getBigUint64();
  }

  @protected
  bool sse_decode_bool(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getUint8() != 0;
  }

  @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_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          BaseRustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as BaseRustStateImpl).frbInternalSseEncode(move: true),
        serializer);
  }

  @protected
  void
      sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: true), serializer);
  }

  @protected
  void
      sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: true), serializer);
  }

  @protected
  void
      sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          BaseRustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as BaseRustStateImpl).frbInternalSseEncode(move: false),
        serializer);
  }

  @protected
  void
      sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          BaseRustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as BaseRustStateImpl).frbInternalSseEncode(move: null),
        serializer);
  }

  @protected
  void
      sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: null), serializer);
  }

  @protected
  void
      sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: null), serializer);
  }

  @protected
  void sse_encode_StreamSink_unit_Sse(
      RustStreamSink<void> self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_String(
        self.setupAndSerialize(
            codec: SseCodec(
          decodeSuccessData: sse_decode_unit,
          decodeErrorData: sse_decode_AnyhowException,
        )),
        serializer);
  }

  @protected
  void sse_encode_String(String self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
  }

  @protected
  void sse_encode_i_32(int self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putInt32(self);
  }

  @protected
  void sse_encode_list_prim_u_8_strict(
      Uint8List self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_i_32(self.length, serializer);
    serializer.buffer.putUint8List(self);
  }

  @protected
  void sse_encode_u_8(int self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putUint8(self);
  }

  @protected
  void sse_encode_unit(void self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
  }

  @protected
  void sse_encode_usize(BigInt self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putBigUint64(self);
  }

  @protected
  void sse_encode_bool(bool self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putUint8(self ? 1 : 0);
  }
}

// Section: extra_from_parser

abstract class RustWidget extends StatefulWidget {
  final RustState state;

  const RustWidget({super.key, required this.state});

  @override
  State<RustWidget> createState() => _RustWidgetState();

  Widget build(BuildContext context);
}

class _RustWidgetState extends State<RustWidget> {
  late final BaseRustState baseState;

  @override
  void initState() {
    super.initState();
    baseState = BaseRustState(onMutate: () {
      if (mounted) setState(() {});
    });
    widget.state.setBaseState(baseState: baseState);
  }

  @override
  void dispose() {
    baseState.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.build(context);
  }
}

// These functions are ignored because they are not marked as `pub`: `on_mutation`

// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BaseRustState>>
abstract class BaseRustState implements RustOpaqueInterface {
  Stream<void> createNotifyUiStream();

  static BaseRustState empty() =>
      RustLib.instance.api.crateFrbGeneratedBaseRustStateEmpty();

  factory BaseRustState({required void Function() onMutate}) {
    final object = BaseRustState.empty();
    object.createNotifyUiStream().listen((_) => onMutate());
    return object;
  }
}

@sealed
class BaseRustStateImpl extends RustOpaque implements BaseRustState {
  // Not to be used by end users
  BaseRustStateImpl.frbInternalDcoDecode(List<dynamic> wire)
      : super.frbInternalDcoDecode(wire, _kStaticData);

  // Not to be used by end users
  BaseRustStateImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
      : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);

  static final _kStaticData = RustArcStaticData(
    rustArcIncrementStrongCount:
        RustLib.instance.api.rust_arc_increment_strong_count_BaseRustState,
    rustArcDecrementStrongCount:
        RustLib.instance.api.rust_arc_decrement_strong_count_BaseRustState,
    rustArcDecrementStrongCountPtr:
        RustLib.instance.api.rust_arc_decrement_strong_count_BaseRustStatePtr,
  );

  Stream<void> createNotifyUiStream() =>
      RustLib.instance.api.crateFrbGeneratedBaseRustStateCreateNotifyUiStream(
        that: this,
      );
}

@sealed
class RustState2Impl extends RustOpaque implements RustState2 {
  // Not to be used by end users
  RustState2Impl.frbInternalDcoDecode(List<dynamic> wire)
      : super.frbInternalDcoDecode(wire, _kStaticData);

  // Not to be used by end users
  RustState2Impl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
      : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);

  static final _kStaticData = RustArcStaticData(
    rustArcIncrementStrongCount:
        RustLib.instance.api.rust_arc_increment_strong_count_RustState2,
    rustArcDecrementStrongCount:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustState2,
    rustArcDecrementStrongCountPtr:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustState2Ptr,
  );

  int get count => RustLib.instance.api.crateAppRustState2AutoAccessorGetCount(
        that: this,
      );

  set count(int count) => RustLib.instance.api
      .crateAppRustState2AutoAccessorSetCount(that: this, count: count);

  void increment() => RustLib.instance.api.crateAppRustState2Increment(
        that: this,
      );

  void setBaseState({required BaseRustState baseState}) => RustLib.instance.api
      .crateAppRustState2SetBaseState(that: this, baseState: baseState);
}

@sealed
class RustStateImpl extends RustOpaque implements RustState {
  // Not to be used by end users
  RustStateImpl.frbInternalDcoDecode(List<dynamic> wire)
      : super.frbInternalDcoDecode(wire, _kStaticData);

  // Not to be used by end users
  RustStateImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
      : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);

  static final _kStaticData = RustArcStaticData(
    rustArcIncrementStrongCount:
        RustLib.instance.api.rust_arc_increment_strong_count_RustState,
    rustArcDecrementStrongCount:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustState,
    rustArcDecrementStrongCountPtr:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustStatePtr,
  );

  int get count => RustLib.instance.api.crateAppRustStateAutoAccessorGetCount(
        that: this,
      );

  set count(int count) => RustLib.instance.api
      .crateAppRustStateAutoAccessorSetCount(that: this, count: count);

  void increment() => RustLib.instance.api.crateAppRustStateIncrement(
        that: this,
      );

  void setBaseState({required BaseRustState baseState}) => RustLib.instance.api
      .crateAppRustStateSetBaseState(that: this, baseState: baseState);
}

Composable version

Same results but just putting it here:
lib/main.dart:

import 'package:flutter/material.dart';
import 'package:frb_example_rust_ui_counter/src/rust/app.dart';
import 'package:frb_example_rust_ui_counter/src/rust/frb_generated.dart';

void main() async {
  await RustLib.init();
  runApp(MyRustApp());
}

class MyRustApp extends StatelessWidget {
  final RustState x = RustState();
  MyRustApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: Scaffold(
        body: Column(
          children: <Widget>[
            RustWidget(state: x, builder: (context, state) => Column(
                children: <Widget>[
                  Text('Count: ${state.count}'),
                  TextButton(
                    onPressed: state.increment,
                    child: Text('+1'),
                  ),
                ],
              )
            ),
            RustWidget(state: x, builder: (context, state) => Column(
                children: <Widget>[
                  Text('Count: ${state.count}'),
                  TextButton(
                    onPressed: state.increment,
                    child: Text('+1'),
                  ),
                ],
              )
            ),
          ],
        ),
      ),
    );
  }
}

lib/frb_generated.dart:

// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.4.0.

// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.4.0.

// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import

import 'app.dart';
import 'dart:async';
import 'dart:convert';
import 'frb_generated.dart';
import 'frb_generated.io.dart'
    if (dart.library.js_interop) 'frb_generated.web.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';

/// Main entrypoint of the Rust API
class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
  @internal
  static final instance = RustLib._();

  RustLib._();

  /// Initialize flutter_rust_bridge
  static Future<void> init({
    RustLibApi? api,
    BaseHandler? handler,
    ExternalLibrary? externalLibrary,
  }) async {
    await instance.initImpl(
      api: api,
      handler: handler,
      externalLibrary: externalLibrary,
    );
  }

  /// Initialize flutter_rust_bridge in mock mode.
  /// No libraries for FFI are loaded.
  static void initMock({
    required RustLibApi api,
  }) {
    instance.initMockImpl(
      api: api,
    );
  }

  /// Dispose flutter_rust_bridge
  ///
  /// The call to this function is optional, since flutter_rust_bridge (and everything else)
  /// is automatically disposed when the app stops.
  static void dispose() => instance.disposeImpl();

  @override
  ApiImplConstructor<RustLibApiImpl, RustLibWire> get apiImplConstructor =>
      RustLibApiImpl.new;

  @override
  WireConstructor<RustLibWire> get wireConstructor =>
      RustLibWire.fromExternalLibrary;

  @override
  Future<void> executeRustInitializers() async {}

  @override
  ExternalLibraryLoaderConfig get defaultExternalLibraryLoaderConfig =>
      kDefaultExternalLibraryLoaderConfig;

  @override
  String get codegenVersion => '2.4.0';

  @override
  int get rustContentHash => 686613453;

  static const kDefaultExternalLibraryLoaderConfig =
      ExternalLibraryLoaderConfig(
    stem: 'rust_lib_frb_example_rust_ui_counter',
    ioDirectory: '../target/release/',
    webPrefix: 'pkg/',
  );
}

abstract class RustLibApi extends BaseApi {
  int crateAppRustState2AutoAccessorGetCount({required RustState2 that});

  void crateAppRustState2AutoAccessorSetCount(
      {required RustState2 that, required int count});

  void crateAppRustState2Increment({required RustState2 that});

  RustState2 crateAppRustState2New();

  void crateAppRustState2SetBaseState(
      {required RustState2 that, required BaseRustState baseState});

  int crateAppRustStateAutoAccessorGetCount({required RustState that});

  void crateAppRustStateAutoAccessorSetCount(
      {required RustState that, required int count});

  void crateAppRustStateIncrement({required RustState that});

  RustState crateAppRustStateNew();

  void crateAppRustStateSetBaseState(
      {required RustState that, required BaseRustState baseState});

  Stream<void> crateFrbGeneratedBaseRustStateCreateNotifyUiStream(
      {required BaseRustState that});

  BaseRustState crateFrbGeneratedBaseRustStateEmpty();

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_BaseRustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_BaseRustState;

  CrossPlatformFinalizerArg
      get rust_arc_decrement_strong_count_BaseRustStatePtr;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState;

  CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_RustStatePtr;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState2;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState2;

  CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_RustState2Ptr;
}

class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
  RustLibApiImpl({
    required super.handler,
    required super.wire,
    required super.generalizedFrbRustBinding,
    required super.portManager,
  });

  @override
  int crateAppRustState2AutoAccessorGetCount({required RustState2 that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 1)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_i_32,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2AutoAccessorGetCountConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2AutoAccessorGetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_auto_accessor_get_count",
        argNames: ["that"],
      );

  @override
  void crateAppRustState2AutoAccessorSetCount(
      {required RustState2 that, required int count}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        sse_encode_i_32(count, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 2)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2AutoAccessorSetCountConstMeta,
      argValues: [that, count],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2AutoAccessorSetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_auto_accessor_set_count",
        argNames: ["that", "count"],
      );

  @override
  void crateAppRustState2Increment({required RustState2 that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 3)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2IncrementConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2IncrementConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_increment",
        argNames: ["that"],
      );

  @override
  RustState2 crateAppRustState2New() {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 4)!;
      },
      codec: SseCodec(
        decodeSuccessData:
            sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2NewConstMeta,
      argValues: [],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2NewConstMeta => const TaskConstMeta(
        debugName: "RustState2_new",
        argNames: [],
      );

  @override
  void crateAppRustState2SetBaseState(
      {required RustState2 that, required BaseRustState baseState}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
            that, serializer);
        sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
            baseState, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 5)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustState2SetBaseStateConstMeta,
      argValues: [that, baseState],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustState2SetBaseStateConstMeta =>
      const TaskConstMeta(
        debugName: "RustState2_set_base_state",
        argNames: ["that", "baseState"],
      );

  @override
  int crateAppRustStateAutoAccessorGetCount({required RustState that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 6)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_i_32,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateAutoAccessorGetCountConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateAutoAccessorGetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState_auto_accessor_get_count",
        argNames: ["that"],
      );

  @override
  void crateAppRustStateAutoAccessorSetCount(
      {required RustState that, required int count}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        sse_encode_i_32(count, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 7)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateAutoAccessorSetCountConstMeta,
      argValues: [that, count],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateAutoAccessorSetCountConstMeta =>
      const TaskConstMeta(
        debugName: "RustState_auto_accessor_set_count",
        argNames: ["that", "count"],
      );

  @override
  void crateAppRustStateIncrement({required RustState that}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 8)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateIncrementConstMeta,
      argValues: [that],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateIncrementConstMeta => const TaskConstMeta(
        debugName: "RustState_increment",
        argNames: ["that"],
      );

  @override
  RustState crateAppRustStateNew() {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 9)!;
      },
      codec: SseCodec(
        decodeSuccessData:
            sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateNewConstMeta,
      argValues: [],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateNewConstMeta => const TaskConstMeta(
        debugName: "RustState_new",
        argNames: [],
      );

  @override
  void crateAppRustStateSetBaseState(
      {required RustState that, required BaseRustState baseState}) {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
            that, serializer);
        sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
            baseState, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 10)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateAppRustStateSetBaseStateConstMeta,
      argValues: [that, baseState],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateAppRustStateSetBaseStateConstMeta =>
      const TaskConstMeta(
        debugName: "RustState_set_base_state",
        argNames: ["that", "baseState"],
      );

  @override
  Stream<void> crateFrbGeneratedBaseRustStateCreateNotifyUiStream(
      {required BaseRustState that}) {
    final sink = RustStreamSink<void>();
    handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
            that, serializer);
        sse_encode_StreamSink_unit_Sse(sink, serializer);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 11)!;
      },
      codec: SseCodec(
        decodeSuccessData: sse_decode_unit,
        decodeErrorData: null,
      ),
      constMeta: kCrateFrbGeneratedBaseRustStateCreateNotifyUiStreamConstMeta,
      argValues: [that, sink],
      apiImpl: this,
    ));
    return sink.stream;
  }

  TaskConstMeta
      get kCrateFrbGeneratedBaseRustStateCreateNotifyUiStreamConstMeta =>
          const TaskConstMeta(
            debugName: "BaseRustState_create_notify_ui_stream",
            argNames: ["that", "sink"],
          );

  @override
  BaseRustState crateFrbGeneratedBaseRustStateEmpty() {
    return handler.executeSync(SyncTask(
      callFfi: () {
        final serializer = SseSerializer(generalizedFrbRustBinding);
        return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 12)!;
      },
      codec: SseCodec(
        decodeSuccessData:
            sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState,
        decodeErrorData: null,
      ),
      constMeta: kCrateFrbGeneratedBaseRustStateEmptyConstMeta,
      argValues: [],
      apiImpl: this,
    ));
  }

  TaskConstMeta get kCrateFrbGeneratedBaseRustStateEmptyConstMeta =>
      const TaskConstMeta(
        debugName: "BaseRustState_empty",
        argNames: [],
      );

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_BaseRustState => wire
          .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_BaseRustState => wire
          .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState => wire
          .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState => wire
          .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState;

  RustArcIncrementStrongCountFnType
      get rust_arc_increment_strong_count_RustState2 => wire
          .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2;

  RustArcDecrementStrongCountFnType
      get rust_arc_decrement_strong_count_RustState2 => wire
          .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2;

  @protected
  AnyhowException dco_decode_AnyhowException(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return AnyhowException(raw as String);
  }

  @protected
  BaseRustState
      dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  BaseRustState
      dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  BaseRustState
      dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState
      dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustStateImpl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustState2
      dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return RustState2Impl.frbInternalDcoDecode(raw as List<dynamic>);
  }

  @protected
  RustStreamSink<void> dco_decode_StreamSink_unit_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
    return raw as String;
  }

  @protected
  int dco_decode_i_32(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return raw as int;
  }

  @protected
  Uint8List dco_decode_list_prim_u_8_strict(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return raw as Uint8List;
  }

  @protected
  int dco_decode_u_8(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return raw as int;
  }

  @protected
  void dco_decode_unit(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return;
  }

  @protected
  BigInt dco_decode_usize(dynamic raw) {
    // Codec=Dco (DartCObject based), see doc to use other codecs
    return dcoDecodeU64(raw);
  }

  @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
  BaseRustState
      sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  BaseRustState
      sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  BaseRustState
      sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return BaseRustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState
      sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustStateImpl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustState2
      sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return RustState2Impl.frbInternalSseDecode(
        sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
  }

  @protected
  RustStreamSink<void> sse_decode_StreamSink_unit_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
    var inner = sse_decode_list_prim_u_8_strict(deserializer);
    return utf8.decoder.convert(inner);
  }

  @protected
  int sse_decode_i_32(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getInt32();
  }

  @protected
  Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    var len_ = sse_decode_i_32(deserializer);
    return deserializer.buffer.getUint8List(len_);
  }

  @protected
  int sse_decode_u_8(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getUint8();
  }

  @protected
  void sse_decode_unit(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
  }

  @protected
  BigInt sse_decode_usize(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getBigUint64();
  }

  @protected
  bool sse_decode_bool(SseDeserializer deserializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    return deserializer.buffer.getUint8() != 0;
  }

  @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_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          BaseRustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as BaseRustStateImpl).frbInternalSseEncode(move: true),
        serializer);
  }

  @protected
  void
      sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: true), serializer);
  }

  @protected
  void
      sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: true), serializer);
  }

  @protected
  void
      sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          BaseRustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as BaseRustStateImpl).frbInternalSseEncode(move: false),
        serializer);
  }

  @protected
  void
      sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: false), serializer);
  }

  @protected
  void
      sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBaseRustState(
          BaseRustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as BaseRustStateImpl).frbInternalSseEncode(move: null),
        serializer);
  }

  @protected
  void
      sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState(
          RustState self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustStateImpl).frbInternalSseEncode(move: null), serializer);
  }

  @protected
  void
      sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerRustState2(
          RustState2 self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_usize(
        (self as RustState2Impl).frbInternalSseEncode(move: null), serializer);
  }

  @protected
  void sse_encode_StreamSink_unit_Sse(
      RustStreamSink<void> self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_String(
        self.setupAndSerialize(
            codec: SseCodec(
          decodeSuccessData: sse_decode_unit,
          decodeErrorData: sse_decode_AnyhowException,
        )),
        serializer);
  }

  @protected
  void sse_encode_String(String self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
  }

  @protected
  void sse_encode_i_32(int self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putInt32(self);
  }

  @protected
  void sse_encode_list_prim_u_8_strict(
      Uint8List self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    sse_encode_i_32(self.length, serializer);
    serializer.buffer.putUint8List(self);
  }

  @protected
  void sse_encode_u_8(int self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putUint8(self);
  }

  @protected
  void sse_encode_unit(void self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
  }

  @protected
  void sse_encode_usize(BigInt self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putBigUint64(self);
  }

  @protected
  void sse_encode_bool(bool self, SseSerializer serializer) {
    // Codec=Sse (Serialization based), see doc to use other codecs
    serializer.buffer.putUint8(self ? 1 : 0);
  }
}

// Section: extra_from_parser

class RustWidget extends StatefulWidget {
  final RustState state;
  final Widget Function(BuildContext, RustState) builder;

  const RustWidget({super.key, required this.state, required this.builder});

  @override
  State<RustWidget> createState() => _RustWidgetState();
}

class _RustWidgetState extends State<RustWidget> {
  late final BaseRustState baseState;

  @override
  void initState() {
    super.initState();
    baseState = BaseRustState(onMutate: () {
      if (mounted) setState(() {});
    });
    widget.state.setBaseState(baseState: baseState);
  }

  @override
  void dispose() {
    baseState.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.builder(context, widget.state);
  }
}
// These functions are ignored because they are not marked as `pub`: `on_mutation`

// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BaseRustState>>
abstract class BaseRustState implements RustOpaqueInterface {
  Stream<void> createNotifyUiStream();

  static BaseRustState empty() =>
      RustLib.instance.api.crateFrbGeneratedBaseRustStateEmpty();

  factory BaseRustState({required void Function() onMutate}) {
    final object = BaseRustState.empty();
    object.createNotifyUiStream().listen((_) => onMutate());
    return object;
  }
}

@sealed
class BaseRustStateImpl extends RustOpaque implements BaseRustState {
  // Not to be used by end users
  BaseRustStateImpl.frbInternalDcoDecode(List<dynamic> wire)
      : super.frbInternalDcoDecode(wire, _kStaticData);

  // Not to be used by end users
  BaseRustStateImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
      : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);

  static final _kStaticData = RustArcStaticData(
    rustArcIncrementStrongCount:
        RustLib.instance.api.rust_arc_increment_strong_count_BaseRustState,
    rustArcDecrementStrongCount:
        RustLib.instance.api.rust_arc_decrement_strong_count_BaseRustState,
    rustArcDecrementStrongCountPtr:
        RustLib.instance.api.rust_arc_decrement_strong_count_BaseRustStatePtr,
  );

  Stream<void> createNotifyUiStream() =>
      RustLib.instance.api.crateFrbGeneratedBaseRustStateCreateNotifyUiStream(
        that: this,
      );
}

@sealed
class RustState2Impl extends RustOpaque implements RustState2 {
  // Not to be used by end users
  RustState2Impl.frbInternalDcoDecode(List<dynamic> wire)
      : super.frbInternalDcoDecode(wire, _kStaticData);

  // Not to be used by end users
  RustState2Impl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
      : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);

  static final _kStaticData = RustArcStaticData(
    rustArcIncrementStrongCount:
        RustLib.instance.api.rust_arc_increment_strong_count_RustState2,
    rustArcDecrementStrongCount:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustState2,
    rustArcDecrementStrongCountPtr:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustState2Ptr,
  );

  int get count => RustLib.instance.api.crateAppRustState2AutoAccessorGetCount(
        that: this,
      );

  set count(int count) => RustLib.instance.api
      .crateAppRustState2AutoAccessorSetCount(that: this, count: count);

  void increment() => RustLib.instance.api.crateAppRustState2Increment(
        that: this,
      );

  void setBaseState({required BaseRustState baseState}) => RustLib.instance.api
      .crateAppRustState2SetBaseState(that: this, baseState: baseState);
}

@sealed
class RustStateImpl extends RustOpaque implements RustState {
  // Not to be used by end users
  RustStateImpl.frbInternalDcoDecode(List<dynamic> wire)
      : super.frbInternalDcoDecode(wire, _kStaticData);

  // Not to be used by end users
  RustStateImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
      : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);

  static final _kStaticData = RustArcStaticData(
    rustArcIncrementStrongCount:
        RustLib.instance.api.rust_arc_increment_strong_count_RustState,
    rustArcDecrementStrongCount:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustState,
    rustArcDecrementStrongCountPtr:
        RustLib.instance.api.rust_arc_decrement_strong_count_RustStatePtr,
  );

  int get count => RustLib.instance.api.crateAppRustStateAutoAccessorGetCount(
        that: this,
      );

  set count(int count) => RustLib.instance.api
      .crateAppRustStateAutoAccessorSetCount(that: this, count: count);

  void increment() => RustLib.instance.api.crateAppRustStateIncrement(
        that: this,
      );

  void setBaseState({required BaseRustState baseState}) => RustLib.instance.api
      .crateAppRustStateSetBaseState(that: this, baseState: baseState);
}

@fzyzcjy
Copy link
Owner

fzyzcjy commented Sep 21, 2024

Only RS2 updates on clicking +1 button on RS1 or RS2. But if we comment out RS2 from the Scaffold, RS1 works properly.

Looks like because

widget.state.setBaseState(...)

which does not handle "single Rust state be watched by multi Dart widgets". It seems not hard to extend to allow multi.

Copy link

stale bot commented Nov 23, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Nov 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants