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

feat(bindings/dart): Add dart binding #5591

Open
wants to merge 34 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
36420cf
init
asukaminato0721 Feb 1, 2025
024de61
add license head
asukaminato0721 Feb 1, 2025
e5831d6
now the draft is done
asukaminato0721 Feb 1, 2025
ec45dc9
add Capability
asukaminato0721 Feb 1, 2025
5af69cf
add init example
asukaminato0721 Feb 1, 2025
63dce09
add readme && gitignore
asukaminato0721 Feb 1, 2025
b823b13
use script to build
asukaminato0721 Feb 1, 2025
16aaace
remove uses
asukaminato0721 Feb 1, 2025
da7d2fb
add RUST_LOG
asukaminato0721 Feb 1, 2025
9ae344f
fix opendal path
asukaminato0721 Feb 1, 2025
ec73e43
fix name
asukaminato0721 Feb 1, 2025
903d0d7
now it can go to build, use tmate
asukaminato0721 Feb 1, 2025
210c639
try fix compile error
asukaminato0721 Feb 1, 2025
bbc7107
tmp remove Operator
asukaminato0721 Feb 1, 2025
1ef21b8
fix version
asukaminato0721 Feb 1, 2025
9a253f5
add gitignore
asukaminato0721 Feb 1, 2025
1c5ad8c
add some api && add code gen result
asukaminato0721 Feb 1, 2025
91ff558
add test
asukaminato0721 Feb 1, 2025
b2bbec0
rm js comment
asukaminato0721 Feb 1, 2025
4cab262
rm gen
asukaminato0721 Feb 1, 2025
f6185aa
do some fix
asukaminato0721 Feb 8, 2025
86f6907
back to release build
asukaminato0721 Feb 8, 2025
2823808
test file
asukaminato0721 Feb 8, 2025
013a292
fix step 1
asukaminato0721 Feb 10, 2025
dc206f5
try fix
asukaminato0721 Feb 10, 2025
60f30a0
private cap
asukaminato0721 Feb 10, 2025
73c8b59
gen
asukaminato0721 Feb 10, 2025
1178961
rm cap
asukaminato0721 Feb 10, 2025
3f41677
fmt
asukaminato0721 Feb 10, 2025
4056c2f
add example in readme
asukaminato0721 Feb 10, 2025
7f2ee6e
use dart stdlib style
asukaminato0721 Feb 11, 2025
e372207
2.8.0
asukaminato0721 Feb 11, 2025
f42d676
dart dep version
asukaminato0721 Feb 11, 2025
96e0456
use Manager to give class
asukaminato0721 Feb 13, 2025
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ integrations export-ignore
bindings/c export-ignore
bindings/cpp export-ignore
bindings/d export-ignore
bindings/dart export-ignore
bindings/dotnet export-ignore
bindings/go export-ignore
bindings/haskell export-ignore
Expand Down
86 changes: 86 additions & 0 deletions .github/workflows/ci_bindings_dart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: Bindings Dart CI

on:
push:
branches:
- main
tags:
- "*"
pull_request:
branches:
- main
paths:
- "core/**"
- "bindings/dart/**"
- ".github/workflows/ci_bindings_dart.yml"
workflow_dispatch:

env:
FLUTTER_VERSION: "3.27.3"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Rust toolchain
uses: ./.github/actions/setup

- name: Install Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: 'stable'

- name: Install flutter_rust_bridge_codegen and cargo-expand and fvm
working-directory: bindings/dart
run: |
set -eux -o pipefail
# cargo install cargo-expand
# cargo install flutter_rust_bridge_codegen --version "2.7.1"

- name: Check generated bridge code is sync
working-directory: bindings/dart
run: |
set -eux -o pipefail
git diff

- name: Flutter pub get
working-directory: bindings/dart
run: flutter pub get

- name: build lib
working-directory: bindings/dart/rust
run: |
set -eux -o pipefail
cargo build -r # frb will load the so in release/, so release build here

- name: test
working-directory: bindings/dart
run: |
dart run lib/opendal_test.dart
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ OpenDAL's development is guided by its vision of **One Layer, All Storage** and
| [C Binding] | - | [![Docs Dev]][C Binding Dev Docs] |
| [Cpp Binding] | - | [![Docs Dev]][Cpp Binding Dev Docs] |
| [D Binding] | - | - |
| [Dart Binding] | - | - |
| [Dotnet Binding] | - | - |
| [Go Binding] | [![Go Binding Image]][Go Binding Link] | [![Docs Release]][Go Release Docs] |
| [Haskell Binding] | - | - |
Expand All @@ -42,6 +43,7 @@ OpenDAL's development is guided by its vision of **One Layer, All Storage** and
[Cpp Binding]: bindings/cpp/README.md
[Cpp Binding Dev Docs]: https://opendal.apache.org/docs/cpp/
[D Binding]: bindings/d/README.md
[Dart Binding]: bindings/dart/README.md
[Dotnet Binding]: bindings/dotnet/README.md
[Go Binding]: bindings/go/README.md
[Go Binding Image]: https://badge.fury.io/go/github.com%2Fapache%2Fopendal%2Fbindings%2Fgo.svg
Expand Down
1 change: 1 addition & 0 deletions bindings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This folder contains the bindings for OpenDAL. Currently, we support the followi
* [C++](cpp/README.md)
* [C#](dotnet/README.md)
* [D](d/README.md)
* [Dart](dart/README.md)
* [Go](go/README.md)
* [Haskell](haskell/README.md)
* [Lua](lua/README.md)
Expand Down
27 changes: 27 additions & 0 deletions bindings/dart/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# See https://www.dartlang.org/guides/libraries/private-files

# Files and directories created by pub
.dart_tool/
.packages
build/
# If you're building an application, you may want to check-in your pubspec.lock
pubspec.lock

# Directory created by dartdoc
# If you don't generate documentation locally you can remove this line.
doc/api/

# dotenv environment variables file
.env*

# Avoid committing generated Javascript files:
*.dart.js
*.info.json # Produced by the --dump-info flag.
*.js # When generated by dart2js. Don't specify *.js if your
# project includes source files written in JavaScript.
*.js_
*.js.deps
*.js.map

.flutter-plugins
.flutter-plugins-dependencies
18 changes: 18 additions & 0 deletions bindings/dart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Apache OpenDAL™ Dart Binding (WIP)

## Development

```
flutter pub get
flutter_rust_bridge_codegen generate
cd rust
cargo build -r
cd ..
dart run lib/opendal_test.dart
```

## License and Trademarks

Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0

Apache OpenDAL, OpenDAL, and Apache are either registered trademarks or trademarks of the Apache Software Foundation.
20 changes: 20 additions & 0 deletions bindings/dart/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

analyzer:
exclude:
- rust/target/**.dart # contains dumped debug info, instead of normal code
21 changes: 21 additions & 0 deletions bindings/dart/flutter_rust_bridge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

rust_input: crate::api
rust_root: rust/
dart_output: lib/src/rust
local: true
120 changes: 120 additions & 0 deletions bindings/dart/lib/opendal.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import 'src/rust/frb_generated.dart';
import 'src/rust/api/opendal_api.dart';

class FileManager {
final Operator _operator;

FileManager._(this._operator);

static FileManager initOp(
{required String schemeStr, required Map<String, String> map}) {
return FileManager._(Operator(schemeStr: schemeStr, map: map));
}

File call(String path) {
return File._(path: path, operator: _operator);
}
}

class DirectoryManager {
final Operator _operator;

DirectoryManager._(this._operator);

static DirectoryManager initOp(
{required String schemeStr, required Map<String, String> map}) {
return DirectoryManager._(Operator(schemeStr: schemeStr, map: map));
}

Directory call(String path) {
return Directory._(path: path, operator: _operator);
}
}

class File {
final String path;
final Operator _operator;

File._({required this.path, required Operator operator})
: _operator = operator;

Future<bool> exists() {
return _operator.isExist(path: path);
}

bool existsSync() {
return _operator.isExistSync(path: path);
}

Future<Metadata> stat() {
return _operator.stat(path: path);
}

Metadata statSync() {
return _operator.statSync(path: path);
}

Future<void> delete() {
return _operator.delete(path: path);
}

Future<void> rename(String newPath) {
return _operator.rename(from: path, to: newPath);
}

void renameSync(String newPath) {
_operator.renameSync(from: path, to: newPath);
}

void deleteSync() {
_operator.deleteSync(path: path);
}
}

class Directory {
final String path;
final Operator _operator;

Directory._({required this.path, required Operator operator})
: _operator = operator;

Future<void> create() {
return _operator.createDir(path: path);
}

void createSync() {
_operator.createDirSync(path: path);
}

Future<bool> exists() {
return _operator.isExist(path: path);
}

bool existsSync() {
return _operator.isExistSync(path: path);
}

Future<void> rename(String newPath) {
return _operator.rename(from: path, to: newPath);
}

void renameSync(String newPath) {
_operator.renameSync(from: path, to: newPath);
}

Future<Metadata> stat() {
return _operator.stat(path: path);
}

Metadata statSync() {
return _operator.statSync(path: path);
}

Future<void> delete() {
return _operator.delete(path: path);
}

void deleteSync() {
_operator.deleteSync(path: path);
}
}
44 changes: 44 additions & 0 deletions bindings/dart/lib/opendal_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:test/test.dart';
import 'src/rust/frb_generated.dart';
import 'src/rust/api/opendal_api.dart';
import 'opendal.dart';

void main() {
group('opendal unit test', () {
group('opendal fs schema', () {
test('File and Directory functions in fs schema', () async {
await RustLib.init();
final File = FileManager.initOp(schemeStr: "fs", map: {"root": "/tmp"});
var testFile = File("test_1.txt");
expect(await testFile.exists(), false);

var anotherFile = File("test.txt");
expect(await anotherFile.exists(), false);

final Directory =
DirectoryManager.initOp(schemeStr: "fs", map: {"root": "/tmp"});
var testDir = Directory("test_dir/");
await testDir.create();
expect(await testDir.exists(), true);
});
});

group('opendal memory schema', () {
test('File and Directory functions in memory schema', () async {
final File =
FileManager.initOp(schemeStr: "memory", map: {"root": "/tmp"});
final Directory =
DirectoryManager.initOp(schemeStr: "memory", map: {"root": "/tmp"});
var testDir = Directory("test/");
await testDir.create();
expect(
await testDir.exists(), isTrue); // Directory exists after creation

final meta = await testDir.stat();
expect(meta, isNotNull);
expect(meta.isFile, false);
expect(meta.isDirectory, true);
});
});
});
}
Loading