You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by "asukaminato0721 (via GitHub)" <gi...@apache.org> on 2025/02/01 09:15:03 UTC

[PR] init [opendal]

asukaminato0721 opened a new pull request, #5591:
URL: https://github.com/apache/opendal/pull/5591

   # Which issue does this PR close?
   
   <!--
   We generally require a GitHub issue to be filed for all bug fixes and enhancements. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123.
   -->
   
   Closes #2435.
   
   # Rationale for this change
   
   <!--
   Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed.
   Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes.
   -->
   
   # What changes are included in this PR?
   
   <!--
   There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR.
   -->
   
   add dart binding
   
   # Are there any user-facing changes?
   
   no
   <!--
   If there are user-facing changes then we may require documentation to be updated before approving the PR.
   -->
   
   <!---
   If there are any breaking changes to public APIs, please add the `breaking-changes` label.
   -->
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1947543632


##########
.github/workflows/ci_bindings_dart.yml:
##########
@@ -0,0 +1,89 @@
+# 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
+          curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
+          curl -fsSL https://fvm.app/install.sh | bash
+          cargo binstall --no-confirm --no-symlinks --force cargo-expand
+          cargo binstall --no-confirm --no-symlinks --force flutter_rust_bridge_codegen --version "2.7.1"

Review Comment:
   - fvm can be removed, though a bit of warning
   - <https://cjycode.com/flutter_rust_bridge/guides/miscellaneous/expanding-macros>
   - ok



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1950368198


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   Hi, I'm afraid we're still not on the same page. What I want to ask is how users feel about this library—will it feel native to them? Will they appreciate this API design?
   
   Take `dart:io` as an example. Should we expose a `File` class and provide methods like `rename` and `write` on it? Or is it a widely accepted API design pattern to have a struct that provides all the necessary APIs?
   
   Finally, is it a good idea to introduce something called `Operator` in the Dart ecosystem? Do they have a similar concept?
   
   ---
   
   In short, how will we design a native library in dart that allows users to access all storage services? Fortunately, it's powered by OpenDAL.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948980067


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   I get it. User can just import them and use them like native.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo merged PR #5591:
URL: https://github.com/apache/opendal/pull/5591


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1947547905


##########
.github/workflows/ci_bindings_dart.yml:
##########
@@ -0,0 +1,89 @@
+# 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
+          curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
+          curl -fsSL https://fvm.app/install.sh | bash
+          cargo binstall --no-confirm --no-symlinks --force cargo-expand
+          cargo binstall --no-confirm --no-symlinks --force flutter_rust_bridge_codegen --version "2.7.1"
+
+      - name: Generate bridge code
+        working-directory: bindings/dart
+        run: |
+          set -eux -o pipefail
+          mkdir -p lib/src/rust
+          RUST_LOG=warn flutter_rust_bridge_codegen generate

Review Comment:
   temporarily use git diff here



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948974424


##########
bindings/dart/pubspec.yaml:
##########
@@ -0,0 +1,33 @@
+# 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: opendal_dart

Review Comment:
   fixed



##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {

Review Comment:
   removed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1950369721


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   Let's take other bindings as examples:
   
   - Python expsoes `File` to users.
   - Java exposes `InputStream` and `OutputStream` to users.
   
   What's the similiar concept in dart?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948870949


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   > Does dart use this same API pattern
   
   yes, dart just change from like `rename_sync` to `renameSync`.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948874510


##########
bindings/dart/rust/src/lib.rs:
##########
@@ -0,0 +1,19 @@
+mod frb_generated; /* AUTO INJECTED BY flutter_rust_bridge. This line may not be accurate, and you can change it according to your needs. */

Review Comment:
   let me try.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948995358


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   https://github.com/apache/opendal/pull/5591/commits/2710cdcea340c82f367956b77acd0f26f365be15



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1947545142


##########
.github/workflows/ci_bindings_dart.yml:
##########
@@ -0,0 +1,89 @@
+# 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
+          curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
+          curl -fsSL https://fvm.app/install.sh | bash
+          cargo binstall --no-confirm --no-symlinks --force cargo-expand
+          cargo binstall --no-confirm --no-symlinks --force flutter_rust_bridge_codegen --version "2.7.1"
+
+      - name: Generate bridge code
+        working-directory: bindings/dart
+        run: |
+          set -eux -o pipefail
+          mkdir -p lib/src/rust
+          RUST_LOG=warn flutter_rust_bridge_codegen generate
+
+      - 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 --release
+
+      - name: test
+        working-directory: bindings/dart
+        run: |
+          dart run lib/example.dart

Review Comment:
   Dart is a programming language, and Flutter is a framework within which it is used.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on PR #5591:
URL: https://github.com/apache/opendal/pull/5591#issuecomment-2628909583

   currently the trait bound `opendal::Operator: SseEncode` is not satisfied
   
   ```rs
   error[E0277]: the trait bound `opendal::Operator: SseEncode` is not satisfied
       --> src/frb_generated.rs:1666:36
        |
   1666 |             transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
        |                                    ^ the trait `SseEncode` is not implemented for `opendal::Operator`
        |
        = help: the following other types implement trait `SseEncode`:
                  ()
                  (String, String)
                  HashMap<String, String>
                  Option<usize>
                  RustOpaqueBase<RustAutoOpaqueInner<opendal_api::Capability>, frb_generated::MoiArc<RustAutoOpaqueInner<opendal_api::Capability>>>
                  RustOpaqueBase<RustAutoOpaqueInner<opendal_api::Operator>, frb_generated::MoiArc<RustAutoOpaqueInner<opendal_api::Operator>>>
                  String
                  Vec<(String, String)>
                and 8 others
   note: required by a bound in `transform_result_sse`
       --> src/frb_generated.rs:35:1
        |
   35   | / flutter_rust_bridge::frb_generated_boilerplate!(
   36   | |     default_stream_sink_codec = SseCodec,
   37   | |     default_rust_opaque = RustOpaqueMoi,
   38   | |     default_rust_auto_opaque = RustAutoOpaqueMoi,
   39   | | );
        | | ^
        | | |
        | |_required by a bound in this function
        |   required by this bound in `transform_result_sse`
        = note: this error originates in the macro `$crate::frb_generated_sse_codec` which comes from the expansion of the macro `flutter_rust_bridge::frb_generated_boilerplate` (in Nightly builds, run with -Z macro-backtrace for more info)
   ```
   
   So I remove it to let build work.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo commented on PR #5591:
URL: https://github.com/apache/opendal/pull/5591#issuecomment-2709719186

   Hi, @asukaminato0721 would you like to create a tracking issue for the following tasks? I think we need examples, tests, docs and figure how to release it.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo commented on PR #5591:
URL: https://github.com/apache/opendal/pull/5591#issuecomment-2629299202

   Thank you so much, @asukaminato0721, for working on this. I will start reviewing this PR later next week. Wishing you a wonderful holiday in the meantime!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1947478818


##########
.github/workflows/ci_bindings_dart.yml:
##########
@@ -0,0 +1,89 @@
+# 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
+          curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
+          curl -fsSL https://fvm.app/install.sh | bash
+          cargo binstall --no-confirm --no-symlinks --force cargo-expand
+          cargo binstall --no-confirm --no-symlinks --force flutter_rust_bridge_codegen --version "2.7.1"

Review Comment:
   Hi, it's usually dangerous to download scripts and run them in CI.
   
   - We already have `subosito/flutter-action@v2`; do we still need FVM?
   - Why do we need `cargo-expand`?
   - To start, we can simply run `cargo install flutter_rust_bridge_codegen`.



##########
.github/workflows/ci_bindings_dart.yml:
##########
@@ -0,0 +1,89 @@
+# 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
+          curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
+          curl -fsSL https://fvm.app/install.sh | bash
+          cargo binstall --no-confirm --no-symlinks --force cargo-expand
+          cargo binstall --no-confirm --no-symlinks --force flutter_rust_bridge_codegen --version "2.7.1"
+
+      - name: Generate bridge code
+        working-directory: bindings/dart
+        run: |
+          set -eux -o pipefail
+          mkdir -p lib/src/rust
+          RUST_LOG=warn flutter_rust_bridge_codegen generate
+
+      - 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 --release

Review Comment:
   `cargo build` is enough for CI check.



##########
.github/workflows/ci_bindings_dart.yml:
##########
@@ -0,0 +1,89 @@
+# 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
+          curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
+          curl -fsSL https://fvm.app/install.sh | bash
+          cargo binstall --no-confirm --no-symlinks --force cargo-expand
+          cargo binstall --no-confirm --no-symlinks --force flutter_rust_bridge_codegen --version "2.7.1"
+
+      - name: Generate bridge code
+        working-directory: bindings/dart
+        run: |
+          set -eux -o pipefail
+          mkdir -p lib/src/rust
+          RUST_LOG=warn flutter_rust_bridge_codegen generate
+
+      - 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 --release
+
+      - name: test
+        working-directory: bindings/dart
+        run: |
+          dart run lib/example.dart

Review Comment:
   What is the relationship between Flutter and Dart?



##########
bindings/dart/README.md:
##########
@@ -0,0 +1,12 @@
+# Dart binding for opendal

Review Comment:
   Hi, please follow the same template like C and Python which includes trademarks and license.



##########
.github/workflows/ci_bindings_dart.yml:
##########
@@ -0,0 +1,89 @@
+# 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
+          curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
+          curl -fsSL https://fvm.app/install.sh | bash
+          cargo binstall --no-confirm --no-symlinks --force cargo-expand
+          cargo binstall --no-confirm --no-symlinks --force flutter_rust_bridge_codegen --version "2.7.1"
+
+      - name: Generate bridge code
+        working-directory: bindings/dart
+        run: |
+          set -eux -o pipefail
+          mkdir -p lib/src/rust
+          RUST_LOG=warn flutter_rust_bridge_codegen generate

Review Comment:
   Can we assume that `flutter_rust_bridge_codegen generate` has already been run locally, so we only need to check the diff in CI, and developers don't need to run it themselves?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948449140


##########
licenserc.toml:
##########
@@ -43,4 +43,7 @@ excludes = [
   # Test files
   "**/tests/data/**",
   "**/fixtures/data/**",
+  # dart binding generated file
+  "opendal_api.dart",

Review Comment:
   How about adding `bindings/dart/` before?



##########
bindings/dart/pubspec.yaml:
##########
@@ -0,0 +1,33 @@
+# 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: opendal_dart

Review Comment:
   Please just name as `opendal`.



##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {

Review Comment:
   Please don't expose the capability unless we decide to support it.



##########
bindings/dart/pubspec.yaml:
##########
@@ -0,0 +1,33 @@
+# 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: opendal_dart
+description: opendal dart binding

Review Comment:
   Please make it clear that opendal is an apache project, like Apache OpenDALâ„¢ Dart Binding.



##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   I noticed that we are following the same way of rust's API. Does dart use this same API pattern? Maybe we can take it's fs API or s3 SDK for an example.



##########
bindings/dart/rust/src/lib.rs:
##########
@@ -0,0 +1,19 @@
+mod frb_generated; /* AUTO INJECTED BY flutter_rust_bridge. This line may not be accurate, and you can change it according to your needs. */

Review Comment:
   Can we move this line?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "Xuanwo (via GitHub)" <gi...@apache.org>.
Xuanwo commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948975247


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   Hi, sorry for not making my statement clearer. What I want to know is how native Dart users perceive these APIs. Does our current API design meet their expectations?
   
   For example, `dart-io`'s API looks in this way: https://api.dart.dev/dart-io/dart-io-library.html
   
   ```
   import 'dart:io';
   
   void main() async {
     final filename = 'file.txt';
     var file = await File(filename).writeAsString('some content');
     // Do something with the file.
   }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on PR #5591:
URL: https://github.com/apache/opendal/pull/5591#issuecomment-2656551113

   @Xuanwo now it's like drop-in replacement.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on PR #5591:
URL: https://github.com/apache/opendal/pull/5591#issuecomment-2629041088

   I only ported part of the api so the test can pass. And currently all result is using unwrap (as a first version).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948872905


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   in the `lib/opendal_test.dart` file, there are some test cases.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1950646342


##########
bindings/dart/lib/src/rust/api/opendal_api.dart:
##########
@@ -0,0 +1,176 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.7.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';
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Capability>>
+abstract class Capability implements RustOpaqueInterface {
+  /// If operator supports blocking.
+  bool get blocking;
+
+  /// If operator supports copy.
+  bool get copy;
+
+  /// If operator supports create dir.
+  bool get createDir;
+
+  /// If operator supports delete.
+  bool get delete;
+
+  /// If operator supports list.
+  bool get list;
+
+  /// If backend supports list with limit.
+  bool get listWithLimit;
+
+  /// If backend supports list with recursive.
+  bool get listWithRecursive;
+
+  /// If backend supports list with start after.
+  bool get listWithStartAfter;
+
+  /// If operator supports presign.
+  bool get presign;
+
+  /// If operator supports presign read.
+  bool get presignRead;
+
+  /// If operator supports presign stat.
+  bool get presignStat;
+
+  /// If operator supports presign write.
+  bool get presignWrite;
+
+  /// If operator supports read.
+  bool get read;
+
+  /// If operator supports read with if matched.
+  bool get readWithIfMatch;
+
+  /// If operator supports read with if not match.
+  bool get readWithIfNoneMatch;
+
+  /// if operator supports read with override cache control.
+  bool get readWithOverrideCacheControl;
+
+  /// if operator supports `read` with override content disposition.
+  bool get readWithOverrideContentDisposition;
+
+  /// if operator supports read with override content type.
+  bool get readWithOverrideContentType;
+
+  /// If operator supports rename.
+  bool get rename;
+
+  /// If operator supports shared.
+  bool get shared;
+
+  /// If operator supports stat.
+  bool get stat;
+
+  /// If operator supports stat with if matched.
+  bool get statWithIfMatch;
+
+  /// If operator supports stat with if not match.
+  bool get statWithIfNoneMatch;
+
+  /// If operator supports write.
+  bool get write;
+
+  /// If operator supports write by append.
+  bool get writeCanAppend;
+
+  /// If operator supports write with empty content.
+  bool get writeCanEmpty;
+
+  /// If operator supports write can be called in multi times.
+  bool get writeCanMulti;
+
+  /// write_multi_max_size is the max size that services support in write_multi.
+  ///
+  /// For example, AWS S3 supports 5GiB as max in write_multi.
+  BigInt? get writeMultiMaxSize;
+
+  /// write_multi_min_size is the min size that services support in write_multi.
+  ///
+  /// For example, AWS S3 requires at least 5MiB in write_multi expect the last one.
+  BigInt? get writeMultiMinSize;
+
+  /// write_total_max_size is the max size that services support in write_total.
+  ///
+  /// For example, Cloudflare D1 supports 1MB as max in write_total.
+  BigInt? get writeTotalMaxSize;
+
+  /// If operator supports write with cache control.
+  bool get writeWithCacheControl;
+
+  /// If operator supports write with content disposition.
+  bool get writeWithContentDisposition;
+
+  /// If operator supports write with content type.
+  bool get writeWithContentType;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Metadata>>
+abstract class Metadata implements RustOpaqueInterface {
+  /// Content-Disposition of this object
+  String? get contentDisposition;
+
+  /// Content Length of this object
+  BigInt? get contentLength;
+
+  /// Content MD5 of this object.
+  String? get contentMd5;
+
+  /// Content Type of this object.
+  String? get contentType;
+
+  /// ETag of this object.
+  String? get etag;
+
+  /// Returns true if the <op.stat> object describes a file system directory.
+  bool get isDirectory;
+
+  /// Returns true if the <op.stat> object describes a regular file.
+  bool get isFile;
+
+  /// Last Modified of this object.
+  ///
+  /// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
+  String? get lastModified;
+}
+
+// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<Operator>>
+abstract class Operator implements RustOpaqueInterface {
+  Capability capability();
+
+  Future<void> check();
+
+  Future<void> createDir({required String path});
+
+  void createDirSync({required String path});
+
+  Future<void> delete({required String path});
+
+  void deleteSync({required String path});
+
+  Future<bool> isExist({required String path});
+
+  bool isExistSync({required String path});
+
+  factory Operator(
+          {required String schemeStr, required Map<String, String> map}) =>
+      RustLib.instance.api
+          .crateApiOpendalApiOperatorNew(schemeStr: schemeStr, map: map);
+
+  Future<void> rename({required String from, required String to});
+
+  void renameSync({required String from, required String to});
+
+  Future<Metadata> stat({required String path});
+
+  Metadata statSync({required String path});
+}

Review Comment:
   I redesign the api, now it works like dart stdlib.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(bindings/dart): Add dart binding [opendal]

Posted by "asukaminato0721 (via GitHub)" <gi...@apache.org>.
asukaminato0721 commented on code in PR #5591:
URL: https://github.com/apache/opendal/pull/5591#discussion_r1948975163


##########
bindings/dart/rust/src/lib.rs:
##########
@@ -0,0 +1,19 @@
+mod frb_generated; /* AUTO INJECTED BY flutter_rust_bridge. This line may not be accurate, and you can change it according to your needs. */

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@opendal.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org