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
6966d05
init
asukaminato0721 Feb 1, 2025
d920027
add license head
asukaminato0721 Feb 1, 2025
88d62b4
now the draft is done
asukaminato0721 Feb 1, 2025
5c340b5
add Capability
asukaminato0721 Feb 1, 2025
bfea0e1
add init example
asukaminato0721 Feb 1, 2025
aa053dc
add readme && gitignore
asukaminato0721 Feb 1, 2025
ce9334f
use script to build
asukaminato0721 Feb 1, 2025
35efbd8
remove uses
asukaminato0721 Feb 1, 2025
3d0905c
add RUST_LOG
asukaminato0721 Feb 1, 2025
000e65e
fix opendal path
asukaminato0721 Feb 1, 2025
4c8b29b
fix name
asukaminato0721 Feb 1, 2025
f0b35d8
now it can go to build, use tmate
asukaminato0721 Feb 1, 2025
bec1b17
try fix compile error
asukaminato0721 Feb 1, 2025
b436ec2
tmp remove Operator
asukaminato0721 Feb 1, 2025
9ac24d6
fix version
asukaminato0721 Feb 1, 2025
e54f639
add gitignore
asukaminato0721 Feb 1, 2025
e631a3f
add some api && add code gen result
asukaminato0721 Feb 1, 2025
8bf6a70
add test
asukaminato0721 Feb 1, 2025
d9b431b
rm js comment
asukaminato0721 Feb 1, 2025
c795426
rm gen
asukaminato0721 Feb 1, 2025
a22c23d
do some fix
asukaminato0721 Feb 8, 2025
50c446f
back to release build
asukaminato0721 Feb 8, 2025
47dd34b
Merge branch 'main' into dart-binding
asukaminato0721 Feb 8, 2025
e001637
test file
asukaminato0721 Feb 8, 2025
6298196
fix step 1
asukaminato0721 Feb 10, 2025
ae0a5cf
try fix
asukaminato0721 Feb 10, 2025
cc6e4ec
private cap
asukaminato0721 Feb 10, 2025
86fcbfa
gen
asukaminato0721 Feb 10, 2025
6c644de
rm cap
asukaminato0721 Feb 10, 2025
5c325e4
fmt
asukaminato0721 Feb 10, 2025
2710cdc
add example in readme
asukaminato0721 Feb 10, 2025
fab1e25
use dart stdlib style
asukaminato0721 Feb 11, 2025
f71df9f
2.8.0
asukaminato0721 Feb 11, 2025
e34b29f
dart dep version
asukaminato0721 Feb 11, 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
113 changes: 113 additions & 0 deletions bindings/dart/lib/opendal.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import 'src/rust/frb_generated.dart';
import 'src/rust/api/opendal_api.dart';

class OperatorManager {
static Operator? _operator;

static void initOperator({required String schemeStr, required Map<String, String> map}) {
if (_operator == null) {
_operator = Operator(schemeStr: schemeStr, map: map);
} else {
print("Warning: Operator is already initialized.");
}
}

static Operator get operator {
if (_operator == null) {
throw StateError('Operator has not been initialized. Call initOperator first.');
}
return _operator!;
}
}

class File {
final String path;

File(this.path);

static void initOperator({required String schemeStr, required Map<String, String> map}) {
OperatorManager.initOperator(schemeStr: schemeStr, map: map);
}

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

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

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

Metadata statSync() {
return OperatorManager.operator.statSync(path: path);
}

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

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

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

void deleteSync() {
OperatorManager.operator.deleteSync(path: path);
}
}

class Directory {
final String path;

Directory(this.path);

static void initOperator({required String schemeStr, required Map<String, String> map}) {
OperatorManager.initOperator(schemeStr: schemeStr, map: map);
}

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

void createSync() {
OperatorManager.operator.createDirSync(path: path);
}

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

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

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

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

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

Metadata statSync() {
return OperatorManager.operator.statSync(path: path);
}

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

void deleteSync() {
OperatorManager.operator.deleteSync(path: path);
}
}
45 changes: 45 additions & 0 deletions bindings/dart/lib/opendal_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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', () {
setUpAll(() async {
await RustLib.init();
File.initOperator(schemeStr: "fs", map: {"root": "/tmp"});
});
test('File and Directory functions in fs schema', () async {
var testFile = File("test_1.txt");
expect(await testFile.exists(), false);

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


var testDir = Directory("test_dir/");
await testDir.create();
expect(await testDir.exists(), true);
});
});

group('opendal memory schema', () {
setUpAll(() async {
Directory.initOperator(schemeStr: "memory", map: {"root": "/tmp"});
});

test('File and Directory functions in memory schema', () async {
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
Loading