Skip to content

Commit

Permalink
Merge pull request #399 from project-violet/libviolet
Browse files Browse the repository at this point in the history
Introduce libviolet
  • Loading branch information
violet-dev authored Feb 10, 2024
2 parents f93d6af + 1483966 commit ff33949
Show file tree
Hide file tree
Showing 68 changed files with 5,256 additions and 3 deletions.
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

0 comments on commit ff33949

Please sign in to comment.