From aa54c23c445b39cfaa38dc78eecd7f6da9c7d33f Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sat, 28 Oct 2023 12:13:33 +0200 Subject: [PATCH 1/2] refactor: use named records for version checks Signed-off-by: Nikolas Rimikis --- packages/neon/neon/lib/src/blocs/apps.dart | 17 +++++++++++------ .../neon/lib/src/models/app_implementation.dart | 10 +++++----- packages/neon/neon_dashboard/lib/src/app.dart | 8 -------- packages/neon/neon_files/lib/neon_files.dart | 7 ------- packages/neon/neon_news/lib/neon_news.dart | 2 +- packages/neon/neon_notes/lib/neon_notes.dart | 6 +++--- .../lib/neon_notifications.dart | 8 -------- packages/nextcloud/lib/nextcloud.dart | 1 + packages/nextcloud/lib/src/helpers/common.dart | 2 ++ packages/nextcloud/lib/src/helpers/core.dart | 10 +++++++--- packages/nextcloud/lib/src/helpers/news.dart | 7 ++++--- packages/nextcloud/lib/src/helpers/notes.dart | 10 +++++++--- packages/nextcloud/test/core_test.dart | 4 ++-- packages/nextcloud/test/news_test.dart | 4 ++-- packages/nextcloud/test/notes_test.dart | 4 ++-- 15 files changed, 47 insertions(+), 53 deletions(-) create mode 100644 packages/nextcloud/lib/src/helpers/common.dart diff --git a/packages/neon/neon/lib/src/blocs/apps.dart b/packages/neon/neon/lib/src/blocs/apps.dart index 411e1a77..7200037d 100644 --- a/packages/neon/neon/lib/src/blocs/apps.dart +++ b/packages/neon/neon/lib/src/blocs/apps.dart @@ -123,9 +123,9 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates final notSupported = {}; try { - final (coreSupported, coreMinimumVersion) = _account.client.core.isSupported(capabilities.requireData); - if (!coreSupported) { - notSupported['core'] = coreMinimumVersion.toString(); + final coreCheck = _account.client.core.isSupported(capabilities.requireData); + if (!coreCheck.isSupported) { + notSupported['core'] = coreCheck.minimumVersion.toString(); } } catch (e, s) { debugPrint(e.toString()); @@ -134,9 +134,14 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates for (final app in apps.requireData) { try { - final (supported, minimumVersion) = await app.isSupported(_account, capabilities.requireData); - if (!(supported ?? true)) { - notSupported[app.id] = minimumVersion; + final check = await app.isSupported(_account, capabilities.requireData); + + if (check == null) { + continue; + } + + if (!check.isSupported) { + notSupported[app.id] = check.minimumVersion; } } catch (e, s) { debugPrint(e.toString()); diff --git a/packages/neon/neon/lib/src/models/app_implementation.dart b/packages/neon/neon/lib/src/models/app_implementation.dart index bca76377..e57aa2bd 100644 --- a/packages/neon/neon/lib/src/models/app_implementation.dart +++ b/packages/neon/neon/lib/src/models/app_implementation.dart @@ -15,6 +15,7 @@ import 'package:neon/src/settings/models/storage.dart'; import 'package:neon/src/utils/provider.dart'; import 'package:neon/src/widgets/drawer_destination.dart'; import 'package:nextcloud/core.dart' as core; +import 'package:nextcloud/nextcloud.dart' show VersionSupported; import 'package:provider/provider.dart'; import 'package:rxdart/rxdart.dart'; import 'package:vector_graphics/vector_graphics.dart'; @@ -36,15 +37,14 @@ abstract class AppImplementation /// Checks if the app is supported on the server of the [account]. /// - /// A `supported` value of `null` means that it can not be known if the app is supported. + /// A value of `null` means that it can not be known if the app is supported. /// This is the case for apps that depend on the server version like files and we assume that the app is supported. /// The server support is handled differently. - /// - /// The first value of the record is the supported status and the second value is the supported minimum version. - FutureOr<(bool? supported, String? minimumVersion)> isSupported( + FutureOr?> isSupported( final Account account, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, - ); + ) => + null; final blocsCache = AccountCache(); diff --git a/packages/neon/neon_dashboard/lib/src/app.dart b/packages/neon/neon_dashboard/lib/src/app.dart index 69c4c1f6..9c4f5f38 100644 --- a/packages/neon/neon_dashboard/lib/src/app.dart +++ b/packages/neon/neon_dashboard/lib/src/app.dart @@ -6,7 +6,6 @@ import 'package:neon_dashboard/src/blocs/dashboard.dart'; import 'package:neon_dashboard/src/options.dart'; import 'package:neon_dashboard/src/pages/main.dart'; import 'package:neon_dashboard/src/routes.dart'; -import 'package:nextcloud/core.dart' as core; import 'package:nextcloud/nextcloud.dart'; /// Implementation of the server `dashboard` app. @@ -34,11 +33,4 @@ class DashboardApp extends AppImplementation - const (null, null); } diff --git a/packages/neon/neon_files/lib/neon_files.dart b/packages/neon/neon_files/lib/neon_files.dart index d6df44da..6942c5ac 100644 --- a/packages/neon/neon_files/lib/neon_files.dart +++ b/packages/neon/neon_files/lib/neon_files.dart @@ -72,11 +72,4 @@ class FilesApp extends AppImplementation { @override final RouteBase route = $filesAppRoute; - - @override - (bool? supported, String? minimumVersion) isSupported( - final Account account, - final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, - ) => - const (null, null); } diff --git a/packages/neon/neon_news/lib/neon_news.dart b/packages/neon/neon_news/lib/neon_news.dart index 53948723..81fef6e0 100644 --- a/packages/neon/neon_news/lib/neon_news.dart +++ b/packages/neon/neon_news/lib/neon_news.dart @@ -85,7 +85,7 @@ class NewsApp extends AppImplementation { BehaviorSubject getUnreadCounter(final NewsBloc bloc) => bloc.unreadCounter; @override - Future<(bool? supported, String? minimumVersion)> isSupported( + Future> isSupported( final Account account, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, ) => diff --git a/packages/neon/neon_notes/lib/neon_notes.dart b/packages/neon/neon_notes/lib/neon_notes.dart index 620174a3..d0a1d314 100644 --- a/packages/neon/neon_notes/lib/neon_notes.dart +++ b/packages/neon/neon_notes/lib/neon_notes.dart @@ -71,11 +71,11 @@ class NotesApp extends AppImplementation { final RouteBase route = $notesAppRoute; @override - (bool? supported, String? minimumVersion) isSupported( + VersionSupported isSupported( final Account account, final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, ) { - final (supported, minimumVersion) = account.client.notes.isSupported(capabilities); - return (supported, minimumVersion.toString()); + final result = account.client.notes.isSupported(capabilities); + return (isSupported: result.isSupported, minimumVersion: result.minimumVersion.toString()); } } diff --git a/packages/neon/neon_notifications/lib/neon_notifications.dart b/packages/neon/neon_notifications/lib/neon_notifications.dart index 82c149d0..89dbaec0 100644 --- a/packages/neon/neon_notifications/lib/neon_notifications.dart +++ b/packages/neon/neon_notifications/lib/neon_notifications.dart @@ -13,7 +13,6 @@ import 'package:neon/utils.dart'; import 'package:neon/widgets.dart'; import 'package:neon_notifications/l10n/localizations.dart'; import 'package:neon_notifications/routes.dart'; -import 'package:nextcloud/core.dart' as core; import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/notifications.dart' as notifications; import 'package:rxdart/rxdart.dart'; @@ -54,11 +53,4 @@ class NotificationsApp extends AppImplementation getUnreadCounter(final NotificationsBloc bloc) => bloc.unreadCounter; - - @override - (bool? supported, String? minimumVersion) isSupported( - final Account account, - final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, - ) => - const (null, null); } diff --git a/packages/nextcloud/lib/nextcloud.dart b/packages/nextcloud/lib/nextcloud.dart index b43863e9..bffeff8f 100644 --- a/packages/nextcloud/lib/nextcloud.dart +++ b/packages/nextcloud/lib/nextcloud.dart @@ -4,4 +4,5 @@ export 'package:dynamite_runtime/models.dart'; export 'ids.dart'; export 'src/client.dart'; +export 'src/helpers/common.dart'; export 'webdav.dart'; diff --git a/packages/nextcloud/lib/src/helpers/common.dart b/packages/nextcloud/lib/src/helpers/common.dart new file mode 100644 index 00000000..f2e6b9a1 --- /dev/null +++ b/packages/nextcloud/lib/src/helpers/common.dart @@ -0,0 +1,2 @@ +/// The result of a version check. +typedef VersionSupported = ({bool isSupported, T minimumVersion}); diff --git a/packages/nextcloud/lib/src/helpers/core.dart b/packages/nextcloud/lib/src/helpers/core.dart index f4982e51..de13b505 100644 --- a/packages/nextcloud/lib/src/helpers/core.dart +++ b/packages/nextcloud/lib/src/helpers/core.dart @@ -1,6 +1,7 @@ // ignore_for_file: public_member_api_docs import 'package:nextcloud/src/api/core.openapi.dart' as core; +import 'package:nextcloud/src/helpers/common.dart'; /// Version of core/Server supported const supportedVersion = 27; @@ -9,9 +10,12 @@ extension CoreVersionSupported on core.Client { /// Check if the core/Server version is supported by this client /// /// Also returns the supported version number - (bool, int) isSupported(final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities) => ( - capabilities.version.major == supportedVersion, - supportedVersion, + VersionSupported isSupported( + final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, + ) => + ( + isSupported: capabilities.version.major == supportedVersion, + minimumVersion: supportedVersion, ); } diff --git a/packages/nextcloud/lib/src/helpers/news.dart b/packages/nextcloud/lib/src/helpers/news.dart index f907424c..0761a554 100644 --- a/packages/nextcloud/lib/src/helpers/news.dart +++ b/packages/nextcloud/lib/src/helpers/news.dart @@ -1,6 +1,7 @@ // ignore_for_file: public_member_api_docs import 'package:nextcloud/src/api/news.openapi.dart' as news; +import 'package:nextcloud/src/helpers/common.dart'; /// API version of the news app supported const supportedVersion = 'v1-3'; @@ -9,11 +10,11 @@ extension NewsVersionSupported on news.Client { /// Check if the news app version is supported by this client /// /// Also returns the supported API version number - Future<(bool, String)> isSupported() async { + Future> isSupported() async { final response = await getSupportedApiVersions(); return ( - response.body.apiLevels!.contains(supportedVersion), - supportedVersion, + isSupported: response.body.apiLevels!.contains(supportedVersion), + minimumVersion: supportedVersion, ); } } diff --git a/packages/nextcloud/lib/src/helpers/notes.dart b/packages/nextcloud/lib/src/helpers/notes.dart index dbde1c7d..e0c16c62 100644 --- a/packages/nextcloud/lib/src/helpers/notes.dart +++ b/packages/nextcloud/lib/src/helpers/notes.dart @@ -1,6 +1,7 @@ import 'package:collection/collection.dart'; import 'package:nextcloud/src/api/core.openapi.dart' as core; import 'package:nextcloud/src/api/notes.openapi.dart' as notes; +import 'package:nextcloud/src/helpers/common.dart'; import 'package:version/version.dart'; /// API version of the notes app supported @@ -11,11 +12,14 @@ extension NotesVersionSupported on notes.Client { /// Check if the notes app version is supported by this client /// /// Also returns the supported API version number - (bool, int) isSupported(final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities) => ( - capabilities.capabilities.notesCapabilities?.notes.apiVersion + VersionSupported isSupported( + final core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data capabilities, + ) => + ( + isSupported: capabilities.capabilities.notesCapabilities?.notes.apiVersion ?.map(Version.parse) .firstWhereOrNull((final version) => version.major == supportedVersion) != null, - supportedVersion, + minimumVersion: supportedVersion, ); } diff --git a/packages/nextcloud/test/core_test.dart b/packages/nextcloud/test/core_test.dart index 0fdd1c80..766d6976 100644 --- a/packages/nextcloud/test/core_test.dart +++ b/packages/nextcloud/test/core_test.dart @@ -25,8 +25,8 @@ void main() { expect(response.statusCode, 200); expect(() => response.headers, isA()); - final (supported, _) = client.core.isSupported(response.body.ocs.data); - expect(supported, isTrue); + final result = client.core.isSupported(response.body.ocs.data); + expect(result.isSupported, isTrue); }); test('Is supported from status', () async { diff --git a/packages/nextcloud/test/news_test.dart b/packages/nextcloud/test/news_test.dart index 7ca96f47..ece64797 100644 --- a/packages/nextcloud/test/news_test.dart +++ b/packages/nextcloud/test/news_test.dart @@ -38,8 +38,8 @@ void main() { ); test('Is supported', () async { - final (supported, _) = await client.news.isSupported(); - expect(supported, isTrue); + final result = await client.news.isSupported(); + expect(result.isSupported, isTrue); }); test('Add feed', () async { diff --git a/packages/nextcloud/test/notes_test.dart b/packages/nextcloud/test/notes_test.dart index 800dc371..1d49683e 100644 --- a/packages/nextcloud/test/notes_test.dart +++ b/packages/nextcloud/test/notes_test.dart @@ -25,8 +25,8 @@ void main() { expect(response.statusCode, 200); expect(() => response.headers, isA()); - final (supported, _) = client.notes.isSupported(response.body.ocs.data); - expect(supported, isTrue); + final result = client.notes.isSupported(response.body.ocs.data); + expect(result.isSupported, isTrue); }); test('Create note favorite', () async { From 559e1226f8628fdd18d93a63d88a617c8f3b8e0b Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sat, 28 Oct 2023 13:47:58 +0200 Subject: [PATCH 2/2] refactor: use named records for the sortbox Signed-off-by: Nikolas Rimikis --- .../lib/src/sort_box/sort_box_builder.dart | 4 ++-- packages/neon/neon_files/lib/sort/files.dart | 4 ++-- .../neon_files/lib/widgets/browser_view.dart | 2 +- .../neon/neon_news/lib/sort/articles.dart | 4 ++-- packages/neon/neon_news/lib/sort/feeds.dart | 4 ++-- packages/neon/neon_news/lib/sort/folders.dart | 10 +++++----- .../neon_news/lib/widgets/folders_view.dart | 4 ++-- .../neon/neon_notes/lib/sort/categories.dart | 2 +- packages/neon/neon_notes/lib/sort/notes.dart | 4 ++-- .../neon_notes/lib/widgets/notes_view.dart | 2 +- packages/sort_box/lib/sort_box.dart | 20 +++++++++++-------- packages/sort_box/test/sort_box_test.dart | 20 +++++++++---------- 12 files changed, 42 insertions(+), 38 deletions(-) diff --git a/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart b/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart index 2a6e323f..0e10259b 100644 --- a/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart +++ b/packages/neon/neon/lib/src/sort_box/sort_box_builder.dart @@ -38,7 +38,7 @@ class SortBoxBuilder extends StatelessWidget { final SortBoxWidgetBuilder builder; /// Pre sorts input. - final Set<(T property, SortBoxOrder order)>? presort; + final Set>? presort; @override Widget build(final BuildContext context) { @@ -52,7 +52,7 @@ class SortBoxBuilder extends StatelessWidget { builder: (final context, final property, final _) => ValueListenableBuilder( valueListenable: sortBoxOrder, builder: (final context, final order, final _) { - final box = (property, order); + final box = (property: property, order: order); return builder(context, sortBox.sort(input, box, presort)); }, diff --git a/packages/neon/neon_files/lib/sort/files.dart b/packages/neon/neon_files/lib/sort/files.dart index b46bc14a..408691fc 100644 --- a/packages/neon/neon_files/lib/sort/files.dart +++ b/packages/neon/neon_files/lib/sort/files.dart @@ -9,10 +9,10 @@ final filesSortBox = SortBox( }, { FilesSortProperty.modifiedDate: { - (FilesSortProperty.name, SortBoxOrder.ascending), + (property: FilesSortProperty.name, order: SortBoxOrder.ascending), }, FilesSortProperty.size: { - (FilesSortProperty.name, SortBoxOrder.ascending), + (property: FilesSortProperty.name, order: SortBoxOrder.ascending), }, }, ); diff --git a/packages/neon/neon_files/lib/widgets/browser_view.dart b/packages/neon/neon_files/lib/widgets/browser_view.dart index 98d3ed90..e8f13861 100644 --- a/packages/neon/neon_files/lib/widgets/browser_view.dart +++ b/packages/neon/neon_files/lib/widgets/browser_view.dart @@ -80,7 +80,7 @@ class _FilesBrowserViewState extends State { sortProperty: widget.bloc.options.filesSortPropertyOption, sortBoxOrder: widget.bloc.options.filesSortBoxOrderOption, presort: const { - (FilesSortProperty.isFolder, SortBoxOrder.ascending), + (property: FilesSortProperty.isFolder, order: SortBoxOrder.ascending), }, input: files, builder: (final context, final sorted) { diff --git a/packages/neon/neon_news/lib/sort/articles.dart b/packages/neon/neon_news/lib/sort/articles.dart index 1909d98d..f7ef3dd0 100644 --- a/packages/neon/neon_news/lib/sort/articles.dart +++ b/packages/neon/neon_news/lib/sort/articles.dart @@ -8,10 +8,10 @@ final articlesSortBox = SortBox( }, { ArticlesSortProperty.alphabetical: { - (ArticlesSortProperty.publishDate, SortBoxOrder.descending), + (property: ArticlesSortProperty.publishDate, order: SortBoxOrder.descending), }, ArticlesSortProperty.byFeed: { - (ArticlesSortProperty.alphabetical, SortBoxOrder.ascending), + (property: ArticlesSortProperty.alphabetical, order: SortBoxOrder.ascending), }, }, ); diff --git a/packages/neon/neon_news/lib/sort/feeds.dart b/packages/neon/neon_news/lib/sort/feeds.dart index a873f87c..3fa890bd 100644 --- a/packages/neon/neon_news/lib/sort/feeds.dart +++ b/packages/neon/neon_news/lib/sort/feeds.dart @@ -7,10 +7,10 @@ final feedsSortBox = SortBox( }, { FeedsSortProperty.alphabetical: { - (FeedsSortProperty.unreadCount, SortBoxOrder.descending), + (property: FeedsSortProperty.unreadCount, order: SortBoxOrder.descending), }, FeedsSortProperty.unreadCount: { - (FeedsSortProperty.alphabetical, SortBoxOrder.ascending), + (property: FeedsSortProperty.alphabetical, order: SortBoxOrder.ascending), }, }, ); diff --git a/packages/neon/neon_news/lib/sort/folders.dart b/packages/neon/neon_news/lib/sort/folders.dart index 9cc93215..19f06bd8 100644 --- a/packages/neon/neon_news/lib/sort/folders.dart +++ b/packages/neon/neon_news/lib/sort/folders.dart @@ -2,17 +2,17 @@ part of '../neon_news.dart'; final foldersSortBox = SortBox( { - FoldersSortProperty.alphabetical: (final folderFeedsWrapper) => folderFeedsWrapper.$1.name.toLowerCase(), - FoldersSortProperty.unreadCount: (final folderFeedsWrapper) => folderFeedsWrapper.$3, + FoldersSortProperty.alphabetical: (final folderFeedsWrapper) => folderFeedsWrapper.folder.name.toLowerCase(), + FoldersSortProperty.unreadCount: (final folderFeedsWrapper) => folderFeedsWrapper.unreadCount, }, { FoldersSortProperty.alphabetical: { - (FoldersSortProperty.unreadCount, SortBoxOrder.descending), + (property: FoldersSortProperty.unreadCount, order: SortBoxOrder.descending), }, FoldersSortProperty.unreadCount: { - (FoldersSortProperty.alphabetical, SortBoxOrder.ascending), + (property: FoldersSortProperty.alphabetical, order: SortBoxOrder.ascending), }, }, ); -typedef FolderFeedsWrapper = (news.Folder folder, int feedCount, int unreadCount); +typedef FolderFeedsWrapper = ({news.Folder folder, int feedCount, int unreadCount}); diff --git a/packages/neon/neon_news/lib/widgets/folders_view.dart b/packages/neon/neon_news/lib/widgets/folders_view.dart index 1e7a1a92..c23425e2 100644 --- a/packages/neon/neon_news/lib/widgets/folders_view.dart +++ b/packages/neon/neon_news/lib/widgets/folders_view.dart @@ -23,7 +23,7 @@ class NewsFoldersView extends StatelessWidget { final feedCount = feedsInFolder.length; final unreadCount = feedsInFolder.fold(0, (final a, final b) => a + b.unreadCount!); - return (folder, feedCount, unreadCount); + return (folder: folder, feedCount: feedCount, unreadCount: unreadCount); }).toList() : null, builder: (final context, final sorted) => NeonListView( @@ -45,7 +45,7 @@ class NewsFoldersView extends StatelessWidget { final BuildContext context, final FolderFeedsWrapper folderFeedsWrapper, ) { - final (folder, feedCount, unreadCount) = folderFeedsWrapper; + final (folder: folder, feedCount: feedCount, unreadCount: unreadCount) = folderFeedsWrapper; return ListTile( title: Text( folder.name, diff --git a/packages/neon/neon_notes/lib/sort/categories.dart b/packages/neon/neon_notes/lib/sort/categories.dart index 32c16df8..d61eb680 100644 --- a/packages/neon/neon_notes/lib/sort/categories.dart +++ b/packages/neon/neon_notes/lib/sort/categories.dart @@ -7,7 +7,7 @@ final categoriesSortBox = SortBox( }, { CategoriesSortProperty.notesCount: { - (CategoriesSortProperty.alphabetical, SortBoxOrder.ascending), + (property: CategoriesSortProperty.alphabetical, order: SortBoxOrder.ascending), }, }, ); diff --git a/packages/neon/neon_notes/lib/sort/notes.dart b/packages/neon/neon_notes/lib/sort/notes.dart index b40e3c49..bec3c67a 100644 --- a/packages/neon/neon_notes/lib/sort/notes.dart +++ b/packages/neon/neon_notes/lib/sort/notes.dart @@ -8,10 +8,10 @@ final notesSortBox = SortBox( }, { NotesSortProperty.alphabetical: { - (NotesSortProperty.lastModified, SortBoxOrder.descending), + (property: NotesSortProperty.lastModified, order: SortBoxOrder.descending), }, NotesSortProperty.lastModified: { - (NotesSortProperty.alphabetical, SortBoxOrder.ascending), + (property: NotesSortProperty.alphabetical, order: SortBoxOrder.ascending), }, }, ); diff --git a/packages/neon/neon_notes/lib/widgets/notes_view.dart b/packages/neon/neon_notes/lib/widgets/notes_view.dart index f73cd8ef..7225ed17 100644 --- a/packages/neon/neon_notes/lib/widgets/notes_view.dart +++ b/packages/neon/neon_notes/lib/widgets/notes_view.dart @@ -16,7 +16,7 @@ class NotesView extends StatelessWidget { builder: (final context, final notesList) => SortBoxBuilder( sortBox: notesSortBox, presort: const { - (NotesSortProperty.favorite, SortBoxOrder.ascending), + (property: NotesSortProperty.favorite, order: SortBoxOrder.ascending), }, sortProperty: bloc.options.notesSortPropertyOption, sortBoxOrder: bloc.options.notesSortBoxOrderOption, diff --git a/packages/sort_box/lib/sort_box.dart b/packages/sort_box/lib/sort_box.dart index 55a12586..7da6c27f 100644 --- a/packages/sort_box/lib/sort_box.dart +++ b/packages/sort_box/lib/sort_box.dart @@ -1,6 +1,11 @@ /// Signature of a function returning a [Comparable]. typedef ComparableGetter = Comparable Function(T); +/// The box to sort by. +/// +/// A box contains a property and a corresponding order. +typedef Box = ({T property, SortBoxOrder order}); + /// Sorting Box to sort [List]s on multiple properties. class SortBox { /// Constructs a new SortBox. @@ -17,7 +22,7 @@ class SortBox { /// A mapping of values [T] to their *Boxes*. /// /// The Boxes are applied if two elements are considered equal regarding their property [T]. - final Map> _boxes; + final Map>> _boxes; /// Sorts the [input] list according to their [box]. /// @@ -28,8 +33,8 @@ class SortBox { /// This function sorts the input in place and a reference to it mutating the provided list. List sort( final List input, - final (T property, SortBoxOrder order) box, [ - final Set<(T property, SortBoxOrder order)>? presort, + final Box box, [ + final Set>? presort, ]) { if (input.length <= 1) { return input; @@ -38,7 +43,7 @@ class SortBox { final boxes = { ...?presort, box, - ...?_boxes[box.$1], + ...?_boxes[box.property], }; final sorted = input..sort((final item1, final item2) => _compare(item1, item2, boxes.iterator..moveNext())); @@ -49,16 +54,15 @@ class SortBox { int _compare( final R item1, final R item2, - final Iterator<(T property, SortBoxOrder order)> iterator, + final Iterator> iterator, ) { final box = iterator.current; - final (property, sortBoxOrder) = box; - final comparableGetter = _properties[property]!; + final comparableGetter = _properties[box.property]!; final comparable1 = comparableGetter(item1); final comparable2 = comparableGetter(item2); - final order = switch (sortBoxOrder) { + final order = switch (box.order) { SortBoxOrder.ascending => comparable1.compareTo(comparable2), SortBoxOrder.descending => comparable2.compareTo(comparable1), }; diff --git a/packages/sort_box/test/sort_box_test.dart b/packages/sort_box/test/sort_box_test.dart index 01fa842b..d563fe89 100644 --- a/packages/sort_box/test/sort_box_test.dart +++ b/packages/sort_box/test/sort_box_test.dart @@ -31,14 +31,14 @@ void main() { }, { FruitSort.alphabetical: { - (FruitSort.count, SortBoxOrder.ascending), + (property: FruitSort.count, order: SortBoxOrder.ascending), }, FruitSort.count: { - (FruitSort.alphabetical, SortBoxOrder.ascending), + (property: FruitSort.alphabetical, order: SortBoxOrder.ascending), }, FruitSort.price: { - (FruitSort.alphabetical, SortBoxOrder.descending), - (FruitSort.count, SortBoxOrder.ascending), + (property: FruitSort.alphabetical, order: SortBoxOrder.descending), + (property: FruitSort.count, order: SortBoxOrder.ascending), }, }, ); @@ -52,7 +52,7 @@ void main() { const Fruit('Banana', 4), const Fruit('Apple', 5), ]; - final sorted = sortBox.sort(fruits, (FruitSort.alphabetical, SortBoxOrder.ascending)); + final sorted = sortBox.sort(fruits, (property: FruitSort.alphabetical, order: SortBoxOrder.ascending)); for (var i = 0; i < 3; i++) { expect(sorted[i].name, 'Apple'); @@ -70,7 +70,7 @@ void main() { const Fruit('Banana', 2), const Fruit('Apple', 3), ]; - final sorted = sortBox.sort(fruits, (FruitSort.count, SortBoxOrder.ascending)); + final sorted = sortBox.sort(fruits, (property: FruitSort.count, order: SortBoxOrder.ascending)); final names = ['Apple', 'Banana', 'Apple', 'Apple', 'Banana']; for (var i = 0; i < 5; i++) { @@ -91,7 +91,7 @@ void main() { const Fruit('Banana', 1), const Fruit('Apple', 2), ]; - final sorted = sortBox.sort(fruits, (FruitSort.count, SortBoxOrder.ascending)); + final sorted = sortBox.sort(fruits, (property: FruitSort.count, order: SortBoxOrder.ascending)); final names = ['Apple', 'Banana', 'Apple', 'Apple', 'Banana']; for (var i = 0; i < 5; i++) { @@ -112,7 +112,7 @@ void main() { const Fruit('Banana', 2), const Fruit('Apple', 5), ]; - final sorted = sortBox.sort(fruits, (FruitSort.alphabetical, SortBoxOrder.ascending)); + final sorted = sortBox.sort(fruits, (property: FruitSort.alphabetical, order: SortBoxOrder.ascending)); for (var i = 0; i < 3; i++) { expect(sorted[i].name, 'Apple'); @@ -134,7 +134,7 @@ void main() { const Fruit('Elderberry', 1), const Fruit('Damson', 1), ]; - final sorted = sortBox.sort(fruits, (FruitSort.count, SortBoxOrder.ascending)); + final sorted = sortBox.sort(fruits, (property: FruitSort.count, order: SortBoxOrder.ascending)); final names = ['Apple', 'Banana', 'Coconut', 'Damson', 'Elderberry']; for (var i = 0; i < 5; i++) { @@ -152,7 +152,7 @@ void main() { const Fruit('Banana', 1, 3), const Fruit('Apple', 2, 3), ]; - final sorted = sortBox.sort(fruits, (FruitSort.price, SortBoxOrder.ascending)); + final sorted = sortBox.sort(fruits, (property: FruitSort.price, order: SortBoxOrder.ascending)); final price = [0, 2, 3, 3, 3]; for (var i = 0; i < 5; i++) {