Skip to content

Commit

Permalink
Improve plugin interface and errors (#565)
Browse files Browse the repository at this point in the history
  • Loading branch information
abitofevrything authored Oct 16, 2023
1 parent 17dfca5 commit 32507f3
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/nyxx.dart
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,4 @@ export 'package:http/http.dart'
BaseResponse,
StreamedResponse;
export 'package:logging/logging.dart' show Logger, Level;
export 'package:runtime_type/runtime_type.dart' show RuntimeType;
12 changes: 11 additions & 1 deletion lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:logging/logging.dart';
import 'package:nyxx/src/builders/presence.dart';
import 'package:nyxx/src/builders/voice.dart';
import 'package:nyxx/src/client_options.dart';
import 'package:nyxx/src/errors.dart';
import 'package:nyxx/src/event_mixin.dart';
import 'package:nyxx/src/gateway/gateway.dart';
import 'package:nyxx/src/http/handler.dart';
Expand All @@ -16,12 +17,21 @@ import 'package:nyxx/src/models/user/user.dart';
import 'package:nyxx/src/plugin/plugin.dart';
import 'package:nyxx/src/utils/flags.dart';
import 'package:oauth2/oauth2.dart';
import 'package:runtime_type/runtime_type.dart';

/// A helper function to nest and execute calls to plugin connect methods.
Future<T> _doConnect<T extends Nyxx>(ApiOptions apiOptions, ClientOptions clientOptions, Future<T> Function() connect, List<NyxxPlugin> plugins) {
final actualClientType = RuntimeType<T>();

for (final plugin in plugins) {
if (!actualClientType.isSubtypeOf(plugin.clientType)) {
throw PluginError('Unsupported client type: plugin needs ${plugin.clientType.internalType}, client was ${actualClientType.internalType}');
}
}

connect = plugins.fold(
connect,
(previousConnect, plugin) => () async => (await plugin.doConnect(apiOptions, clientOptions, previousConnect)) as T,
(previousConnect, plugin) => () async => actualClientType.castInstance(await plugin.doConnect(apiOptions, clientOptions, previousConnect)),
);
return connect();
}
Expand Down
12 changes: 12 additions & 0 deletions lib/src/errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,15 @@ class AlreadyRespondedError extends AlreadyAcknowledgedError {
@override
String toString() => 'Interaction has already been responded to';
}

/// An error thrown when an issue with a client's plugin is encountered.
class PluginError extends Error {
/// The message for this [PluginError].
final String message;

/// Create a new [PluginError].
PluginError(this.message);

@override
String toString() => message;
}
2 changes: 1 addition & 1 deletion lib/src/models/channel/thread.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class PartialThreadMember {

/// {@template thread_member}
/// Additional information associated with a [Member] in a [Thread].
/// {@endtemplate thread_member}
/// {@endtemplate}
class ThreadMember extends PartialThreadMember {
/// The manager for this [ThreadMember].
final ChannelManager manager;
Expand Down
13 changes: 12 additions & 1 deletion lib/src/plugin/plugin.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import 'dart:async';

import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
import 'package:nyxx/src/api_options.dart';
import 'package:nyxx/src/client.dart';
import 'package:nyxx/src/client_options.dart';
import 'package:runtime_type/runtime_type.dart';

/// Provides access to the connection and closing process for implementing plugins.
abstract class NyxxPlugin<ClientType extends Nyxx> {
/// The name of this plugin.
String get name;
String get name => runtimeType.toString();

/// A logger that can be used to log messages from this plugin.
Logger get logger => Logger(name);

/// The type of client this plugin requires.
RuntimeType<ClientType> get clientType => RuntimeType<ClientType>();

late final Expando<NyxxPluginState<ClientType, NyxxPlugin<ClientType>>> _states = Expando('$name plugin states');

Expand Down Expand Up @@ -64,6 +72,9 @@ class NyxxPluginState<ClientType extends Nyxx, PluginType extends NyxxPlugin<Cli
/// The plugin this state belongs to.
final PluginType plugin;

/// A logger that can be used to log messages from this plugin.
Logger get logger => plugin.logger;

/// Create a new plugin state.
NyxxPluginState(this.plugin);

Expand Down

0 comments on commit 32507f3

Please sign in to comment.