feat(flutter): add Rust bridge backend and generated bindings
This commit is contained in:
parent
8bfbbd0444
commit
85e616c256
|
|
@ -5,6 +5,7 @@ members = [
|
||||||
]
|
]
|
||||||
exclude = [
|
exclude = [
|
||||||
"apps/tauri/src-tauri",
|
"apps/tauri/src-tauri",
|
||||||
|
"apps/flutter/rust",
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|
|
||||||
195
apps/flutter/lib/src/rust/api.dart
Normal file
195
apps/flutter/lib/src/rust/api.dart
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||||
|
|
||||||
|
import 'frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||||
|
|
||||||
|
// These functions are ignored because they are not marked as `pub`: `config_to_dto`, `ensure_repo`, `task_to_dto`
|
||||||
|
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `AppState`
|
||||||
|
|
||||||
|
Future<AppConfigDto> getConfig() => RustLib.instance.api.crateApiGetConfig();
|
||||||
|
|
||||||
|
Future<void> initWorkspace({required String path}) =>
|
||||||
|
RustLib.instance.api.crateApiInitWorkspace(path: path);
|
||||||
|
|
||||||
|
Future<void> addWorkspace({required String name, required String path}) =>
|
||||||
|
RustLib.instance.api.crateApiAddWorkspace(name: name, path: path);
|
||||||
|
|
||||||
|
Future<void> setCurrentWorkspace({required String name}) =>
|
||||||
|
RustLib.instance.api.crateApiSetCurrentWorkspace(name: name);
|
||||||
|
|
||||||
|
Future<void> removeWorkspace({required String name}) =>
|
||||||
|
RustLib.instance.api.crateApiRemoveWorkspace(name: name);
|
||||||
|
|
||||||
|
Future<List<TaskListDto>> getLists() => RustLib.instance.api.crateApiGetLists();
|
||||||
|
|
||||||
|
Future<TaskListDto> createList({required String name}) =>
|
||||||
|
RustLib.instance.api.crateApiCreateList(name: name);
|
||||||
|
|
||||||
|
Future<void> deleteList({required String listId}) =>
|
||||||
|
RustLib.instance.api.crateApiDeleteList(listId: listId);
|
||||||
|
|
||||||
|
Future<List<TaskDto>> listTasks({required String listId}) =>
|
||||||
|
RustLib.instance.api.crateApiListTasks(listId: listId);
|
||||||
|
|
||||||
|
Future<TaskDto> createTask({
|
||||||
|
required String listId,
|
||||||
|
required String title,
|
||||||
|
required String description,
|
||||||
|
}) => RustLib.instance.api.crateApiCreateTask(
|
||||||
|
listId: listId,
|
||||||
|
title: title,
|
||||||
|
description: description,
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<void> updateTask({required String listId, required TaskDto task}) =>
|
||||||
|
RustLib.instance.api.crateApiUpdateTask(listId: listId, task: task);
|
||||||
|
|
||||||
|
Future<void> deleteTask({required String listId, required String taskId}) =>
|
||||||
|
RustLib.instance.api.crateApiDeleteTask(listId: listId, taskId: taskId);
|
||||||
|
|
||||||
|
Future<TaskDto> toggleTask({required String listId, required String taskId}) =>
|
||||||
|
RustLib.instance.api.crateApiToggleTask(listId: listId, taskId: taskId);
|
||||||
|
|
||||||
|
Future<void> reorderTask({
|
||||||
|
required String listId,
|
||||||
|
required String taskId,
|
||||||
|
required int newPosition,
|
||||||
|
}) => RustLib.instance.api.crateApiReorderTask(
|
||||||
|
listId: listId,
|
||||||
|
taskId: taskId,
|
||||||
|
newPosition: newPosition,
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<String> greet({required String name}) =>
|
||||||
|
RustLib.instance.api.crateApiGreet(name: name);
|
||||||
|
|
||||||
|
class AppConfigDto {
|
||||||
|
final List<WorkspaceEntry> workspaces;
|
||||||
|
final String? currentWorkspace;
|
||||||
|
|
||||||
|
const AppConfigDto({required this.workspaces, this.currentWorkspace});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => workspaces.hashCode ^ currentWorkspace.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is AppConfigDto &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
workspaces == other.workspaces &&
|
||||||
|
currentWorkspace == other.currentWorkspace;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TaskDto {
|
||||||
|
final String id;
|
||||||
|
final String title;
|
||||||
|
final String description;
|
||||||
|
final String status;
|
||||||
|
final String? dueDate;
|
||||||
|
final String createdAt;
|
||||||
|
final String updatedAt;
|
||||||
|
final String? parentId;
|
||||||
|
|
||||||
|
const TaskDto({
|
||||||
|
required this.id,
|
||||||
|
required this.title,
|
||||||
|
required this.description,
|
||||||
|
required this.status,
|
||||||
|
this.dueDate,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
this.parentId,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
id.hashCode ^
|
||||||
|
title.hashCode ^
|
||||||
|
description.hashCode ^
|
||||||
|
status.hashCode ^
|
||||||
|
dueDate.hashCode ^
|
||||||
|
createdAt.hashCode ^
|
||||||
|
updatedAt.hashCode ^
|
||||||
|
parentId.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is TaskDto &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
id == other.id &&
|
||||||
|
title == other.title &&
|
||||||
|
description == other.description &&
|
||||||
|
status == other.status &&
|
||||||
|
dueDate == other.dueDate &&
|
||||||
|
createdAt == other.createdAt &&
|
||||||
|
updatedAt == other.updatedAt &&
|
||||||
|
parentId == other.parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TaskListDto {
|
||||||
|
final String id;
|
||||||
|
final String title;
|
||||||
|
final String createdAt;
|
||||||
|
final String updatedAt;
|
||||||
|
final bool groupByDueDate;
|
||||||
|
|
||||||
|
const TaskListDto({
|
||||||
|
required this.id,
|
||||||
|
required this.title,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.groupByDueDate,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
id.hashCode ^
|
||||||
|
title.hashCode ^
|
||||||
|
createdAt.hashCode ^
|
||||||
|
updatedAt.hashCode ^
|
||||||
|
groupByDueDate.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is TaskListDto &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
id == other.id &&
|
||||||
|
title == other.title &&
|
||||||
|
createdAt == other.createdAt &&
|
||||||
|
updatedAt == other.updatedAt &&
|
||||||
|
groupByDueDate == other.groupByDueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkspaceEntry {
|
||||||
|
final String name;
|
||||||
|
final String path;
|
||||||
|
final String? webdavUrl;
|
||||||
|
final String? lastSync;
|
||||||
|
|
||||||
|
const WorkspaceEntry({
|
||||||
|
required this.name,
|
||||||
|
required this.path,
|
||||||
|
this.webdavUrl,
|
||||||
|
this.lastSync,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
name.hashCode ^ path.hashCode ^ webdavUrl.hashCode ^ lastSync.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is WorkspaceEntry &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
name == other.name &&
|
||||||
|
path == other.path &&
|
||||||
|
webdavUrl == other.webdavUrl &&
|
||||||
|
lastSync == other.lastSync;
|
||||||
|
}
|
||||||
1024
apps/flutter/lib/src/rust/frb_generated.dart
Normal file
1024
apps/flutter/lib/src/rust/frb_generated.dart
Normal file
File diff suppressed because it is too large
Load diff
190
apps/flutter/lib/src/rust/frb_generated.io.dart
Normal file
190
apps/flutter/lib/src/rust/frb_generated.io.dart
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// 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 'api.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:ffi' as ffi;
|
||||||
|
import 'frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_io.dart';
|
||||||
|
|
||||||
|
abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
|
RustLibApiImplPlatform({
|
||||||
|
required super.handler,
|
||||||
|
required super.wire,
|
||||||
|
required super.generalizedFrbRustBinding,
|
||||||
|
required super.portManager,
|
||||||
|
});
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String dco_decode_String(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AppConfigDto dco_decode_app_config_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
bool dco_decode_bool(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto dco_decode_box_autoadd_task_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskDto> dco_decode_list_task_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskListDto> dco_decode_list_task_list_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<WorkspaceEntry> dco_decode_list_workspace_entry(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String? dco_decode_opt_String(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto dco_decode_task_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskListDto dco_decode_task_list_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int dco_decode_u_32(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int dco_decode_u_8(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void dco_decode_unit(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
WorkspaceEntry dco_decode_workspace_entry(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String sse_decode_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AppConfigDto sse_decode_app_config_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
bool sse_decode_bool(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto sse_decode_box_autoadd_task_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskDto> sse_decode_list_task_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskListDto> sse_decode_list_task_list_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<WorkspaceEntry> sse_decode_list_workspace_entry(
|
||||||
|
SseDeserializer deserializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String? sse_decode_opt_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto sse_decode_task_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskListDto sse_decode_task_list_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int sse_decode_u_32(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int sse_decode_u_8(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_decode_unit(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
WorkspaceEntry sse_decode_workspace_entry(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int sse_decode_i_32(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_String(String self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_app_config_dto(AppConfigDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_bool(bool self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_box_autoadd_task_dto(TaskDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_prim_u_8_strict(
|
||||||
|
Uint8List self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_task_dto(List<TaskDto> self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_task_list_dto(
|
||||||
|
List<TaskListDto> self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_workspace_entry(
|
||||||
|
List<WorkspaceEntry> self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_task_dto(TaskDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_task_list_dto(TaskListDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_u_32(int self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_unit(void self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_workspace_entry(
|
||||||
|
WorkspaceEntry self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_i_32(int self, SseSerializer serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section: wire_class
|
||||||
|
|
||||||
|
class RustLibWire implements BaseWire {
|
||||||
|
factory RustLibWire.fromExternalLibrary(ExternalLibrary lib) =>
|
||||||
|
RustLibWire(lib.ffiDynamicLibrary);
|
||||||
|
|
||||||
|
/// Holds the symbol lookup function.
|
||||||
|
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||||
|
_lookup;
|
||||||
|
|
||||||
|
/// The symbols are looked up in [dynamicLibrary].
|
||||||
|
RustLibWire(ffi.DynamicLibrary dynamicLibrary)
|
||||||
|
: _lookup = dynamicLibrary.lookup;
|
||||||
|
}
|
||||||
190
apps/flutter/lib/src/rust/frb_generated.web.dart
Normal file
190
apps/flutter/lib/src/rust/frb_generated.web.dart
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
// This file is automatically generated, so please do not edit it.
|
||||||
|
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Static analysis wrongly picks the IO variant, thus ignore this
|
||||||
|
// ignore_for_file: argument_type_not_assignable
|
||||||
|
|
||||||
|
import 'api.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'frb_generated.dart';
|
||||||
|
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_web.dart';
|
||||||
|
|
||||||
|
abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||||
|
RustLibApiImplPlatform({
|
||||||
|
required super.handler,
|
||||||
|
required super.wire,
|
||||||
|
required super.generalizedFrbRustBinding,
|
||||||
|
required super.portManager,
|
||||||
|
});
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String dco_decode_String(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AppConfigDto dco_decode_app_config_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
bool dco_decode_bool(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto dco_decode_box_autoadd_task_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskDto> dco_decode_list_task_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskListDto> dco_decode_list_task_list_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<WorkspaceEntry> dco_decode_list_workspace_entry(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String? dco_decode_opt_String(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto dco_decode_task_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskListDto dco_decode_task_list_dto(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int dco_decode_u_32(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int dco_decode_u_8(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void dco_decode_unit(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
WorkspaceEntry dco_decode_workspace_entry(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String sse_decode_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
AppConfigDto sse_decode_app_config_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
bool sse_decode_bool(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto sse_decode_box_autoadd_task_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskDto> sse_decode_list_task_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<TaskListDto> sse_decode_list_task_list_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
List<WorkspaceEntry> sse_decode_list_workspace_entry(
|
||||||
|
SseDeserializer deserializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
String? sse_decode_opt_String(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskDto sse_decode_task_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
TaskListDto sse_decode_task_list_dto(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int sse_decode_u_32(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int sse_decode_u_8(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_decode_unit(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
WorkspaceEntry sse_decode_workspace_entry(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
int sse_decode_i_32(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_String(String self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_app_config_dto(AppConfigDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_bool(bool self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_box_autoadd_task_dto(TaskDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_prim_u_8_strict(
|
||||||
|
Uint8List self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_task_dto(List<TaskDto> self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_task_list_dto(
|
||||||
|
List<TaskListDto> self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_list_workspace_entry(
|
||||||
|
List<WorkspaceEntry> self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_task_dto(TaskDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_task_list_dto(TaskListDto self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_u_32(int self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_unit(void self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_workspace_entry(
|
||||||
|
WorkspaceEntry self,
|
||||||
|
SseSerializer serializer,
|
||||||
|
);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_i_32(int self, SseSerializer serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section: wire_class
|
||||||
|
|
||||||
|
class RustLibWire implements BaseWire {
|
||||||
|
RustLibWire.fromExternalLibrary(ExternalLibrary lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JS('wasm_bindgen')
|
||||||
|
external RustLibWasmModule get wasmModule;
|
||||||
|
|
||||||
|
@JS()
|
||||||
|
@anonymous
|
||||||
|
extension type RustLibWasmModule._(JSObject _) implements JSObject {}
|
||||||
6
apps/flutter/rust/Cargo.lock
generated
6
apps/flutter/rust/Cargo.lock
generated
|
|
@ -126,15 +126,13 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy-tasks-flutter-bridge"
|
name = "bevy-tasks-flutter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy-tasks-core",
|
"bevy-tasks-core",
|
||||||
"chrono",
|
"chrono",
|
||||||
"flutter_rust_bridge",
|
"flutter_rust_bridge",
|
||||||
"serde",
|
"once_cell",
|
||||||
"serde_json",
|
|
||||||
"tokio",
|
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
14
apps/flutter/rust/Cargo.toml
Normal file
14
apps/flutter/rust/Cargo.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "bevy-tasks-flutter"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "staticlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
flutter_rust_bridge = "=2.11.1"
|
||||||
|
bevy-tasks-core = { path = "../../../crates/bevy-tasks-core" }
|
||||||
|
uuid = { version = "1", features = ["serde", "v4"] }
|
||||||
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
once_cell = "1"
|
||||||
257
apps/flutter/rust/src/api.rs
Normal file
257
apps/flutter/rust/src/api.rs
Normal file
|
|
@ -0,0 +1,257 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use bevy_tasks_core::{
|
||||||
|
config::{AppConfig, WorkspaceConfig},
|
||||||
|
models::{Task, TaskList, TaskStatus},
|
||||||
|
repository::TaskRepository,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── State ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
struct AppState {
|
||||||
|
config: AppConfig,
|
||||||
|
repo: Option<TaskRepository>,
|
||||||
|
}
|
||||||
|
|
||||||
|
static STATE: Lazy<Mutex<AppState>> = Lazy::new(|| {
|
||||||
|
let config_path = AppConfig::get_config_path();
|
||||||
|
let config = AppConfig::load_from_file(&config_path).unwrap_or_default();
|
||||||
|
Mutex::new(AppState { config, repo: None })
|
||||||
|
});
|
||||||
|
|
||||||
|
fn ensure_repo(state: &mut AppState) -> Result<(), String> {
|
||||||
|
if state.repo.is_some() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let (_name, ws) = state.config.get_current_workspace().map_err(|e| e.to_string())?;
|
||||||
|
let repo = TaskRepository::new(ws.path.clone()).map_err(|e| e.to_string())?;
|
||||||
|
state.repo = Some(repo);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── DTOs ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
pub struct TaskDto {
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
pub description: String,
|
||||||
|
pub status: String,
|
||||||
|
pub due_date: Option<String>,
|
||||||
|
pub created_at: String,
|
||||||
|
pub updated_at: String,
|
||||||
|
pub parent_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TaskListDto {
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
pub created_at: String,
|
||||||
|
pub updated_at: String,
|
||||||
|
pub group_by_due_date: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WorkspaceEntry {
|
||||||
|
pub name: String,
|
||||||
|
pub path: String,
|
||||||
|
pub webdav_url: Option<String>,
|
||||||
|
pub last_sync: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AppConfigDto {
|
||||||
|
pub workspaces: Vec<WorkspaceEntry>,
|
||||||
|
pub current_workspace: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn task_to_dto(t: &Task) -> TaskDto {
|
||||||
|
TaskDto {
|
||||||
|
id: t.id.to_string(),
|
||||||
|
title: t.title.clone(),
|
||||||
|
description: t.description.clone(),
|
||||||
|
status: match t.status {
|
||||||
|
TaskStatus::Backlog => "backlog".into(),
|
||||||
|
TaskStatus::Completed => "completed".into(),
|
||||||
|
},
|
||||||
|
due_date: t.due_date.map(|d| d.to_rfc3339()),
|
||||||
|
created_at: t.created_at.to_rfc3339(),
|
||||||
|
updated_at: t.updated_at.to_rfc3339(),
|
||||||
|
parent_id: t.parent_id.map(|id| id.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_to_dto(c: &AppConfig) -> AppConfigDto {
|
||||||
|
AppConfigDto {
|
||||||
|
workspaces: c
|
||||||
|
.workspaces
|
||||||
|
.iter()
|
||||||
|
.map(|(name, ws)| WorkspaceEntry {
|
||||||
|
name: name.clone(),
|
||||||
|
path: ws.path.to_string_lossy().into_owned(),
|
||||||
|
webdav_url: ws.webdav_url.clone(),
|
||||||
|
last_sync: ws.last_sync.map(|d| d.to_rfc3339()),
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
current_workspace: c.current_workspace.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Config commands ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
pub fn get_config() -> Result<AppConfigDto, String> {
|
||||||
|
let s = STATE.lock().unwrap();
|
||||||
|
Ok(config_to_dto(&s.config))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_workspace(path: String) -> Result<(), String> {
|
||||||
|
TaskRepository::init(PathBuf::from(path))
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_workspace(name: String, path: String) -> Result<(), String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
let ws = WorkspaceConfig::new(PathBuf::from(&path));
|
||||||
|
s.config.add_workspace(name.clone(), ws);
|
||||||
|
s.config.set_current_workspace(name).map_err(|e| e.to_string())?;
|
||||||
|
s.repo = None;
|
||||||
|
let config_path = AppConfig::get_config_path();
|
||||||
|
s.config.save_to_file(&config_path).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_current_workspace(name: String) -> Result<(), String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
s.config.set_current_workspace(name).map_err(|e| e.to_string())?;
|
||||||
|
s.repo = None;
|
||||||
|
let config_path = AppConfig::get_config_path();
|
||||||
|
s.config.save_to_file(&config_path).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_workspace(name: String) -> Result<(), String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
s.config.remove_workspace(&name);
|
||||||
|
s.repo = None;
|
||||||
|
let config_path = AppConfig::get_config_path();
|
||||||
|
s.config.save_to_file(&config_path).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── List commands ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
pub fn get_lists() -> Result<Vec<TaskListDto>, String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let lists = s.repo.as_ref().unwrap().get_lists().map_err(|e| e.to_string())?;
|
||||||
|
Ok(lists
|
||||||
|
.iter()
|
||||||
|
.map(|l| TaskListDto {
|
||||||
|
id: l.id.to_string(),
|
||||||
|
title: l.title.clone(),
|
||||||
|
created_at: l.created_at.to_rfc3339(),
|
||||||
|
updated_at: l.updated_at.to_rfc3339(),
|
||||||
|
group_by_due_date: l.group_by_due_date,
|
||||||
|
})
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_list(name: String) -> Result<TaskListDto, String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let list = s.repo.as_mut().unwrap().create_list(name).map_err(|e| e.to_string())?;
|
||||||
|
Ok(TaskListDto {
|
||||||
|
id: list.id.to_string(),
|
||||||
|
title: list.title.clone(),
|
||||||
|
created_at: list.created_at.to_rfc3339(),
|
||||||
|
updated_at: list.updated_at.to_rfc3339(),
|
||||||
|
group_by_due_date: list.group_by_due_date,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_list(list_id: String) -> Result<(), String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let id = Uuid::parse_str(&list_id).map_err(|e| e.to_string())?;
|
||||||
|
s.repo.as_mut().unwrap().delete_list(id).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Task commands ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
pub fn list_tasks(list_id: String) -> Result<Vec<TaskDto>, String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let id = Uuid::parse_str(&list_id).map_err(|e| e.to_string())?;
|
||||||
|
let tasks = s.repo.as_ref().unwrap().list_tasks(id).map_err(|e| e.to_string())?;
|
||||||
|
Ok(tasks.iter().map(|t| task_to_dto(t)).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_task(list_id: String, title: String, description: String) -> Result<TaskDto, String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let id = Uuid::parse_str(&list_id).map_err(|e| e.to_string())?;
|
||||||
|
let mut task = Task::new(title);
|
||||||
|
if !description.is_empty() {
|
||||||
|
task.description = description;
|
||||||
|
}
|
||||||
|
let created = s.repo.as_mut().unwrap().create_task(id, task).map_err(|e| e.to_string())?;
|
||||||
|
Ok(task_to_dto(&created))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_task(list_id: String, task: TaskDto) -> Result<(), String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let lid = Uuid::parse_str(&list_id).map_err(|e| e.to_string())?;
|
||||||
|
let tid = Uuid::parse_str(&task.id).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
let mut existing = s.repo.as_ref().unwrap().get_task(lid, tid).map_err(|e| e.to_string())?;
|
||||||
|
existing.title = task.title;
|
||||||
|
existing.description = task.description;
|
||||||
|
existing.due_date = task
|
||||||
|
.due_date
|
||||||
|
.as_deref()
|
||||||
|
.and_then(|d| chrono::DateTime::parse_from_rfc3339(d).ok())
|
||||||
|
.map(|d| d.with_timezone(&chrono::Utc));
|
||||||
|
|
||||||
|
s.repo.as_mut().unwrap().update_task(lid, existing).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_task(list_id: String, task_id: String) -> Result<(), String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let lid = Uuid::parse_str(&list_id).map_err(|e| e.to_string())?;
|
||||||
|
let tid = Uuid::parse_str(&task_id).map_err(|e| e.to_string())?;
|
||||||
|
s.repo.as_mut().unwrap().delete_task(lid, tid).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toggle_task(list_id: String, task_id: String) -> Result<TaskDto, String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let lid = Uuid::parse_str(&list_id).map_err(|e| e.to_string())?;
|
||||||
|
let tid = Uuid::parse_str(&task_id).map_err(|e| e.to_string())?;
|
||||||
|
let repo = s.repo.as_mut().unwrap();
|
||||||
|
let mut task = repo.get_task(lid, tid).map_err(|e| e.to_string())?;
|
||||||
|
match task.status {
|
||||||
|
TaskStatus::Backlog => task.complete(),
|
||||||
|
TaskStatus::Completed => task.uncomplete(),
|
||||||
|
}
|
||||||
|
repo.update_task(lid, task.clone()).map_err(|e| e.to_string())?;
|
||||||
|
Ok(task_to_dto(&task))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reorder_task(list_id: String, task_id: String, new_position: u32) -> Result<(), String> {
|
||||||
|
let mut s = STATE.lock().unwrap();
|
||||||
|
ensure_repo(&mut s)?;
|
||||||
|
let lid = Uuid::parse_str(&list_id).map_err(|e| e.to_string())?;
|
||||||
|
let tid = Uuid::parse_str(&task_id).map_err(|e| e.to_string())?;
|
||||||
|
s.repo
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.reorder_task(lid, tid, new_position as usize)
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Test function ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
pub fn greet(name: String) -> String {
|
||||||
|
format!("Hello, {name}! From Rust via flutter_rust_bridge.")
|
||||||
|
}
|
||||||
1018
apps/flutter/rust/src/frb_generated.rs
Normal file
1018
apps/flutter/rust/src/frb_generated.rs
Normal file
File diff suppressed because it is too large
Load diff
2
apps/flutter/rust/src/lib.rs
Normal file
2
apps/flutter/rust/src/lib.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod frb_generated; /* AUTO INJECTED BY flutter_rust_bridge. This line may not be accurate, and you can change it according to your needs. */
|
||||||
|
pub mod api;
|
||||||
Loading…
Reference in a new issue