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

Introduce libviolet #399

Merged
merged 11 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
- uses: subosito/flutter-action@v1
with:
channel: 'stable'

- uses: dtolnay/rust-toolchain@stable

- name: Formatting
run: dart format --output=none --set-exit-if-changed .
Expand Down Expand Up @@ -50,6 +52,8 @@ jobs:
with:
python-version: '3.8'

- uses: dtolnay/rust-toolchain@stable

- name: Preprocess
run: |
cd lib/server
Expand Down Expand Up @@ -102,6 +106,8 @@ jobs:
with:
python-version: '3.8'

- uses: dtolnay/rust-toolchain@stable

- name: Preprocess
run: |
cd lib/server
Expand Down
2 changes: 2 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ linter:
analyzer:
errors:
always_use_package_imports: error
exclude:
- "rust_builder/**"

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
2 changes: 2 additions & 0 deletions flutter_rust_bridge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rust_input: rust/src/api/**/*.rs
dart_output: lib/src/rust
13 changes: 13 additions & 0 deletions integration_test/simple_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:violet/main.dart';
import 'package:violet/src/rust/frb_generated.dart';
import 'package:integration_test/integration_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
setUpAll(() async => await RustLib.init());
testWidgets('Can call rust function', (WidgetTester tester) async {
await tester.pumpWidget(const MyApp());
expect(find.textContaining('Result: `Hello, Tom!`'), findsOneWidget);
});
}
28 changes: 28 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import 'package:violet/pages/database_download/database_download_page.dart';
import 'package:violet/pages/lock/lock_screen.dart';
import 'package:violet/pages/splash/splash_page.dart';
import 'package:violet/settings/settings.dart';
import 'package:violet/src/rust/frb_generated.dart';
import 'package:violet/style/palette.dart';

Future<void> main() async {
runZonedGuarded<Future<void>>(() async {
await RustLib.init();
WidgetsFlutterBinding.ensureInitialized();

await FlutterDownloader.initialize(); // @dependent: android
Expand Down Expand Up @@ -210,3 +212,29 @@ class MyApp extends StatelessWidget {
return supportedLocales.first;
}
}

// import 'package:flutter/material.dart';
// import 'package:violet/src/rust/api/simple.dart';
// import 'package:violet/src/rust/frb_generated.dart';

// Future<void> main() async {
// await RustLib.init();
// runApp(const MyApp());
// }

// class MyApp extends StatelessWidget {
// const MyApp({super.key});

// @override
// Widget build(BuildContext context) {
// return MaterialApp(
// home: Scaffold(
// appBar: AppBar(title: const Text('flutter_rust_bridge quickstart')),
// body: Center(
// child: Text(
// 'Action: Call Rust `greet("Tom")`\nResult: `${greet(name: "Tom")}`'),
// ),
// ),
// );
// }
// }
10 changes: 10 additions & 0 deletions lib/src/rust/api/simple.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// This file is automatically generated, so please do not edit it.
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.24.

// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import

import 'package:violet/src/rust/frb_generated.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';

String greet({required String name, dynamic hint}) =>
RustLib.instance.api.greet(name: name, hint: hint);
226 changes: 226 additions & 0 deletions lib/src/rust/frb_generated.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
// This file is automatically generated, so please do not edit it.
// Generated by `flutter_rust_bridge`@ 2.0.0-dev.24.

// 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

import 'package:violet/src/rust/api/simple.dart';
import 'dart:async';
import 'dart:convert';
import 'package:violet/src/rust/frb_generated.io.dart'
if (dart.library.html) 'frb_generated.web.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,
);
}

/// 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 {
await api.initApp();
}

@override
ExternalLibraryLoaderConfig get defaultExternalLibraryLoaderConfig =>
kDefaultExternalLibraryLoaderConfig;

@override
String get codegenVersion => '2.0.0-dev.24';

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

abstract class RustLibApi extends BaseApi {
String greet({required String name, dynamic hint});

Future<void> initApp({dynamic hint});
}

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

@override
String greet({required String name, dynamic hint}) {
return handler.executeSync(SyncTask(
callFfi: () {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_String(name, serializer);
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 1)!;
},
codec: SseCodec(
decodeSuccessData: sse_decode_String,
decodeErrorData: null,
),
constMeta: kGreetConstMeta,
argValues: [name],
apiImpl: this,
hint: hint,
));
}

TaskConstMeta get kGreetConstMeta => const TaskConstMeta(
debugName: 'greet',
argNames: ['name'],
);

@override
Future<void> initApp({dynamic hint}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
pdeCallFfi(generalizedFrbRustBinding, serializer,
funcId: 2, port: port_);
},
codec: SseCodec(
decodeSuccessData: sse_decode_unit,
decodeErrorData: null,
),
constMeta: kInitAppConstMeta,
argValues: [],
apiImpl: this,
hint: hint,
));
}

TaskConstMeta get kInitAppConstMeta => const TaskConstMeta(
debugName: 'init_app',
argNames: [],
);

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

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

@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_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_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_i_32(int self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
serializer.buffer.putInt32(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);
}
}
Loading
Loading