[gjs: 1/2] Make GFileEnumerator iterable and async iterable
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 1/2] Make GFileEnumerator iterable and async iterable
- Date: Sun, 7 Aug 2022 23:40:19 +0000 (UTC)
commit 3b1eee40e92eb0445f08731b0d58807375f5413c
Author: Sonny Piers <sonny fastmail net>
Date: Sun Aug 7 01:45:17 2022 +0200
Make GFileEnumerator iterable and async iterable
installed-tests/js/testGio.js | 30 ++++++++++++++++++++++
modules/core/overrides/Gio.js | 60 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+)
---
diff --git a/installed-tests/js/testGio.js b/installed-tests/js/testGio.js
index 0f315b7b8..fc94bb587 100644
--- a/installed-tests/js/testGio.js
+++ b/installed-tests/js/testGio.js
@@ -311,3 +311,33 @@ describe('Gio.add_action_entries override', function () {
expect(() => app.add_action_entries(entries)).toThrow();
});
});
+
+describe('Gio.FileEnumerator overrides', function () {
+ it('iterates synchronously', function () {
+ const dir = Gio.File.new_for_path('.');
+ let count = 0;
+ for (const value of dir.enumerate_children(
+ 'standard::name',
+ Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ null
+ )) {
+ expect(value).toBeInstanceOf(Gio.FileInfo);
+ count++;
+ }
+ expect(count).toBeGreaterThan(0);
+ });
+
+ it('iterates asynchronously', async function () {
+ const dir = Gio.File.new_for_path('.');
+ let count = 0;
+ for await (const value of dir.enumerate_children(
+ 'standard::name',
+ Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ null
+ )) {
+ expect(value).toBeInstanceOf(Gio.FileInfo);
+ count++;
+ }
+ expect(count).toBeGreaterThan(0);
+ });
+});
diff --git a/modules/core/overrides/Gio.js b/modules/core/overrides/Gio.js
index 1dfa54e55..6303b8023 100644
--- a/modules/core/overrides/Gio.js
+++ b/modules/core/overrides/Gio.js
@@ -545,6 +545,66 @@ function _init() {
return this.replace_contents_bytes_async(contents, etag, make_backup, flags, cancellable, callback);
};
+ Gio.FileEnumerator.prototype[Symbol.iterator] = function* FileEnumeratorIterator() {
+ while (true) {
+ try {
+ const info = this.next_file(null);
+ if (info === null)
+ break;
+ yield info;
+ } catch (err) {
+ this.close(null);
+ throw err;
+ }
+ }
+ this.close(null);
+ };
+
+ Gio.FileEnumerator.prototype[Symbol.asyncIterator] = async function* AsyncFileEnumatorIterator() {
+ const self = this;
+
+ function next() {
+ return new Promise((resolve, reject) => {
+ self.next_files_async(1, Gio.PRIORITY_DEFAULT, null, (_self, res) => {
+ try {
+ const files = self.next_files_finish(res);
+ resolve(files.length === 0 ? null : files[0]);
+ } catch (err) {
+ reject(err);
+ }
+ });
+ });
+ }
+
+ function close() {
+ return new Promise((resolve, reject) => {
+ self.close_async(Gio.PRIORITY_DEFAULT, null, (_self, res) => {
+ try {
+ resolve(self.close_finish(res));
+ } catch (err) {
+ reject(err);
+ }
+ });
+ });
+ }
+
+ while (true) {
+ try {
+ // eslint-disable-next-line no-await-in-loop
+ const info = await next();
+ if (info === null)
+ break;
+ yield info;
+ } catch (err) {
+ // eslint-disable-next-line no-await-in-loop
+ await close();
+ throw err;
+ }
+ }
+
+ return close();
+ };
+
// Override Gio.Settings and Gio.SettingsSchema - the C API asserts if
// trying to access a nonexistent schema or key, which is not handy for
// shell-extension writers
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]