Browse Source

Add XML docs

pull/988/head
Still Hsu 7 years ago
parent
commit
56987e212b
No known key found for this signature in database GPG Key ID: 8601A145FDA95209
26 changed files with 219 additions and 104 deletions
  1. +1
    -1
      docs/_overwrites/Common/IEmote.Inclusion.md
  2. +7
    -3
      docs/_overwrites/Common/IEmote.Overwrites.md
  3. +6
    -0
      src/Discord.Net.Commands/Attributes/CommandAttribute.cs
  4. +11
    -4
      src/Discord.Net.Commands/Attributes/GroupAttribute.cs
  5. +4
    -2
      src/Discord.Net.Commands/Attributes/NameAttribute.cs
  6. +9
    -5
      src/Discord.Net.Commands/Attributes/OverrideTypeReaderAttribute.cs
  7. +7
    -0
      src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs
  8. +3
    -5
      src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs
  9. +21
    -15
      src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs
  10. +17
    -7
      src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
  11. +2
    -1
      src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs
  12. +1
    -0
      src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs
  13. +21
    -16
      src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs
  14. +1
    -1
      src/Discord.Net.Commands/Attributes/PriorityAttribute.cs
  15. +2
    -3
      src/Discord.Net.Commands/Builders/CommandBuilder.cs
  16. +0
    -1
      src/Discord.Net.Commands/Builders/ModuleBuilder.cs
  17. +0
    -1
      src/Discord.Net.Commands/CommandMatch.cs
  18. +0
    -1
      src/Discord.Net.Commands/CommandService.cs
  19. +1
    -1
      src/Discord.Net.Commands/Results/ParseResult.cs
  20. +24
    -0
      src/Discord.Net.Commands/Results/PreconditionResult.cs
  21. +5
    -0
      src/Discord.Net.Commands/Results/RuntimeResult.cs
  22. +1
    -1
      src/Discord.Net.Core/CDN.cs
  23. +16
    -14
      src/Discord.Net.Core/Logging/LogSeverity.cs
  24. +28
    -11
      src/Discord.Net.Core/Utils/Cacheable.cs
  25. +1
    -1
      src/Discord.Net.Core/Utils/Comparers.cs
  26. +30
    -10
      src/Discord.Net.Core/Utils/MentionUtils.cs

+ 1
- 1
docs/_overwrites/Common/IEmote.Inclusion.md View File

@@ -7,7 +7,7 @@ public async Task SendAndReactAsync(ISocketMessageChannel channel)
var message = await channel.SendMessageAsync("I am a message.");

// Creates a Unicode-based emoji based on the Unicode string.
// This is effctively the same as new Emoji("💕").
// This is effectively the same as new Emoji("💕").
var heartEmoji = new Emoji("\U0001f495");
// Reacts to the message with the Emoji.
await message.AddReactionAsync(heartEmoji);


+ 7
- 3
docs/_overwrites/Common/IEmote.Overwrites.md View File

@@ -24,7 +24,7 @@ remarks: *content
> [!NOTE]
> A valid @Discord.Emote format is `<:emoteName:emoteId>`. This can be
> obtained by escaping with a `\` in front of the emote using the
> Discord chat client.
> Discord chat client.

This class represents a custom emoji. This type of emoji can be
created via the @Discord.Emote.Parse* or @Discord.Emote.TryParse*
@@ -42,11 +42,15 @@ remarks: *content

> [!NOTE]
> A valid @Discord.Emoji format is Unicode-based. This means only
> something like `🙃` or `\U0001f643` would work, instead of
> something like `🙃` or `\U0001f643` would work, instead of
> `:upside_down:`.
>
> A Unicode-based emoji can be obtained by escaping with a `\` in
> front of the emote using the Discord chat client or by looking up on
> [Emojipedia](https://emojipedia.org).

This class represents a standard Unicode-based emoji. This type of emoji
can be created by passing the unicode into its constructor.
can be created by passing the Unicode into the constructor.

---
uid: Discord.IEmote


+ 6
- 0
src/Discord.Net.Commands/Attributes/CommandAttribute.cs View File

@@ -15,10 +15,16 @@ namespace Discord.Commands
/// </summary>
public RunMode RunMode { get; set; } = RunMode.Default;

/// <inheritdoc />
public CommandAttribute()
{
Text = null;
}

/// <summary>
/// Initializes a new <see cref="CommandAttribute" /> attribute with the specified name.
/// </summary>
/// <param name="text">The name of the command.</param>
public CommandAttribute(string text)
{
Text = text;


+ 11
- 4
src/Discord.Net.Commands/Attributes/GroupAttribute.cs View File

@@ -2,19 +2,26 @@ using System;

namespace Discord.Commands
{
/// <summary> Marks the module as a command group. </summary>
/// <summary>
/// Marks the module as a command group.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class GroupAttribute : Attribute
{
/// <summary> Gets the prefix set for the module. </summary>
/// <summary>
/// Gets the prefix set for the module.
/// </summary>
public string Prefix { get; }

/// <inheritdoc />
public GroupAttribute()
{
Prefix = null;
}
/// <summary> Creates a <see cref="GroupAttribute"/> with the provided prefix. </summary>
/// <param name="prefix"> The prefix of the module group. </param>
/// <summary>
/// Initializes a new <see cref="GroupAttribute" /> with the provided prefix.
/// </summary>
/// <param name="prefix">The prefix of the module group.</param>
public GroupAttribute(string prefix)
{
Prefix = prefix;


+ 4
- 2
src/Discord.Net.Commands/Attributes/NameAttribute.cs View File

@@ -14,8 +14,10 @@ namespace Discord.Commands
/// </summary>
public string Text { get; }

/// <summary> Marks the public name of a command, module, or parameter with the provided name. </summary>
/// <param name="text"> The public name of the object. </param>
/// <summary>
/// Marks the public name of a command, module, or parameter with the provided name.
/// </summary>
/// <param name="text">The public name of the object.</param>
public NameAttribute(string text)
{
Text = text;


+ 9
- 5
src/Discord.Net.Commands/Attributes/OverrideTypeReaderAttribute.cs View File

@@ -4,20 +4,24 @@ using System.Reflection;

namespace Discord.Commands
{
/// <summary> Marks the <see cref="Type"/> to be read by the specified <see cref="TypeReader"/>. </summary>
/// <summary>
/// Marks the <see cref="Type"/> to be read by the specified <see cref="TypeReader" />.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public class OverrideTypeReaderAttribute : Attribute
{
private static readonly TypeInfo _typeReaderTypeInfo = typeof(TypeReader).GetTypeInfo();
private static readonly TypeInfo TypeReaderTypeInfo = typeof(TypeReader).GetTypeInfo();

/// <summary> Gets the specified <see cref="TypeReader"/> of the parameter. </summary>
/// <summary>
/// Gets the specified <see cref="TypeReader"/> of the parameter.
/// </summary>
public Type TypeReader { get; }

/// <summary> Marks the parameter to be read with the specified <see cref="TypeReader"/>. </summary>
/// <inheritdoc/>
/// <param name="overridenTypeReader">The <see cref="TypeReader"/> to be used with the parameter. </param>
public OverrideTypeReaderAttribute(Type overridenTypeReader)
{
if (!_typeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo()))
if (!TypeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo()))
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}.");
TypeReader = overridenTypeReader;


+ 7
- 0
src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs View File

@@ -9,6 +9,13 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
public abstract class ParameterPreconditionAttribute : Attribute
{
/// <summary>
/// Checks whether the condition is met before execution of the command.
/// </summary>
/// <param name="context">The context of the command.</param>
/// <param name="parameter">The parameter of the command being checked against.</param>
/// <param name="value">The raw value of the type.</param>
/// <param name="services">The service collection used for dependency injection.</param>
public abstract Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, ParameterInfo parameter, object value, IServiceProvider services);
}
}

+ 3
- 5
src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs View File

@@ -11,11 +11,9 @@ namespace Discord.Commands
/// Specify a group that this precondition belongs to.
/// </summary>
/// <remarks>
/// <para>
/// <see cref="Preconditions" /> of the same group require only one of the preconditions to pass in
/// order to be successful (A || B). Specifying <see cref="Group" /> = <see langword="null" /> or not
/// at all will require *all* preconditions to pass, just like normal (A && B).
/// </para>
/// <see cref="Preconditions" /> of the same group require only one of the preconditions to pass in order to
/// be successful (A || B). Specifying <see cref="Group" /> = <see langword="null" /> or not at all will
/// require *all* preconditions to pass, just like normal (A && B).
/// </remarks>
public string Group { get; set; } = null;



+ 21
- 15
src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs View File

@@ -4,43 +4,49 @@ using System.Threading.Tasks;
namespace Discord.Commands
{
/// <summary>
/// Requires the bot to have a specific permission in the channel a command is invoked in.
/// Requires the bot to have a specific permission in the channel a command is invoked in.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireBotPermissionAttribute : PreconditionAttribute
{
/// <summary>
/// Gets the specified <see cref="Discord.GuildPermission" /> of the precondition.
/// </summary>
public GuildPermission? GuildPermission { get; }
/// <summary>
/// Gets the specified <see cref="Discord.ChannelPermission" /> of the precondition.
/// </summary>
public ChannelPermission? ChannelPermission { get; }

/// <summary>
/// Requires the bot account to have a specific <see cref="GuildPermission"/>.
/// Requires the bot account to have a specific <see cref="Discord.GuildPermission" />.
/// </summary>
/// <remarks>This precondition will always fail if the command is being invoked in a private channel.</remarks>
/// <param name="permission">The GuildPermission that the bot must have. Multiple permissions can be specified by ORing the permissions together.</param>
/// <remarks>
/// This precondition will always fail if the command is being invoked in a <see cref="IPrivateChannel"/>.
/// </remarks>
/// <param name="permission">
/// The <see cref="Discord.GuildPermission"/> that the bot must have. Multiple permissions can be specified
/// by ORing the permissions together.
/// </param>
public RequireBotPermissionAttribute(GuildPermission permission)
{
GuildPermission = permission;
ChannelPermission = null;
}
/// <summary>
/// Requires that the bot account to have a specific <see cref="ChannelPermission"/>.
/// Requires that the bot account to have a specific <see cref="Discord.ChannelPermission"/>.
/// </summary>
/// <param name="permission">The ChannelPermission that the bot must have. Multiple permissions can be specified by ORing the permissions together.</param>
/// <example>
/// <code language="c#">
/// [Command("permission")]
/// [RequireBotPermission(ChannelPermission.ManageMessages)]
/// public async Task Purge()
/// {
/// }
/// </code>
/// </example>
/// <param name="permission">
/// The <see cref="Discord.ChannelPermission"/> that the bot must have. Multiple permissions can be
/// specified by ORing the permissions together.
/// </param>
public RequireBotPermissionAttribute(ChannelPermission permission)
{
ChannelPermission = permission;
GuildPermission = null;
}

/// <inheritdoc />
public override async Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
IGuildUser guildUser = null;


+ 17
- 7
src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs View File

@@ -3,28 +3,38 @@ using System.Threading.Tasks;

namespace Discord.Commands
{
/// <summary> Defines the type of command context. </summary>
/// <summary>
/// Defines the type of command context (i.e. where the command is being executed).
/// </summary>
[Flags]
public enum ContextType
{
/// <summary> Specifies the command to be executed within a guild. </summary>
/// <summary>
/// Specifies the command to be executed within a guild.
/// </summary>
Guild = 0x01,
/// <summary> Specifies the command to be executed within a DM. </summary>
/// <summary>
/// Specifies the command to be executed within a DM.
/// </summary>
DM = 0x02,
/// <summary> Specifies the command to be executed within a group. </summary>
/// <summary>
/// Specifies the command to be executed within a group.
/// </summary>
Group = 0x04
}

/// <summary>
/// Requires the command to be invoked in a specified context (e.g. in guild, DM).
/// Requires the command to be invoked in a specified context (e.g. in guild, DM).
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireContextAttribute : PreconditionAttribute
{
/// <summary> Gets the context required to execute the command. </summary>
/// <summary>
/// Gets the context required to execute the command.
/// </summary>
public ContextType Contexts { get; }

/// <summary> Requires that the command be invoked in the specified context. </summary>
/// <summary> Requires the command to be invoked in the specified context. </summary>
/// <param name="contexts">The type of context the command can be invoked in. Multiple contexts can be specified by ORing the contexts together.</param>
/// <example>
/// <code language="c#">


+ 2
- 1
src/Discord.Net.Commands/Attributes/Preconditions/RequireNsfwAttribute.cs View File

@@ -4,11 +4,12 @@ using System.Threading.Tasks;
namespace Discord.Commands
{
/// <summary>
/// Requires the command to be invoked in a channel marked NSFW.
/// Requires the command to be invoked in a channel marked NSFW.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireNsfwAttribute : PreconditionAttribute
{
/// <inheritdoc />
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
if (context.Channel is ITextChannel text && text.IsNsfw)


+ 1
- 0
src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs View File

@@ -10,6 +10,7 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireOwnerAttribute : PreconditionAttribute
{
/// <inheritdoc />
public override async Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
switch (context.Client.TokenType)


+ 21
- 16
src/Discord.Net.Commands/Attributes/Preconditions/RequireUserPermissionAttribute.cs View File

@@ -9,39 +9,44 @@ namespace Discord.Commands
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireUserPermissionAttribute : PreconditionAttribute
{
/// <summary>
/// Gets the specified <see cref="Discord.GuildPermission" /> of the precondition.
/// </summary>
public GuildPermission? GuildPermission { get; }
/// <summary>
/// Gets the specified <see cref="Discord.ChannelPermission" /> of the precondition.
/// </summary>
public ChannelPermission? ChannelPermission { get; }

/// <summary>
/// Requires that the user invoking the command to have a specific <see cref="GuildPermission"/>.
/// Requires that the user invoking the command to have a specific <see cref="Discord.GuildPermission" />.
/// </summary>
/// <remarks>This precondition will always fail if the command is being invoked in a private channel.</remarks>
/// <param name="permission">The GuildPermission that the user must have. Multiple permissions can be specified by ORing the permissions together.</param>
/// <remarks>
/// This precondition will always fail if the command is being invoked in a <see cref="IPrivateChannel"/>.
/// </remarks>
/// <param name="permission">
/// The <see cref="Discord.GuildPermission" /> that the user must have. Multiple permissions can be
/// specified by ORing the permissions together.
/// </param>
public RequireUserPermissionAttribute(GuildPermission permission)
{
GuildPermission = permission;
ChannelPermission = null;
}
/// <summary>
/// Requires that the user invoking the command to have a specific <see cref="ChannelPermission"/>.
/// Requires that the user invoking the command to have a specific <see cref="Discord.ChannelPermission"/>.
/// </summary>
/// <param name="permission">The ChannelPermission that the user must have. Multiple permissions can be specified by ORing the permissions together.</param>
/// <example>
/// <code language="c#">
/// [Command("permission")]
/// [RequireUserPermission(ChannelPermission.ReadMessageHistory | ChannelPermission.ReadMessages)]
/// public async Task HasPermission()
/// {
/// await ReplyAsync("You can read messages and the message history!");
/// }
/// </code>
/// </example>
/// <param name="permission">
/// The <see cref="Discord.ChannelPermission"/> that the user must have. Multiple permissions can be
/// specified by ORing the permissions together.
/// </param>
public RequireUserPermissionAttribute(ChannelPermission permission)
{
ChannelPermission = permission;
GuildPermission = null;
}

/// <inheritdoc />
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
var guildUser = context.User as IGuildUser;


+ 1
- 1
src/Discord.Net.Commands/Attributes/PriorityAttribute.cs View File

@@ -14,7 +14,7 @@ namespace Discord.Commands
public int Priority { get; }

/// <summary>
/// Creates a new <see cref="PriorityAttribute" /> with the given priority.
/// Initializes a new <see cref="PriorityAttribute" /> attribute with the given priority.
/// </summary>
public PriorityAttribute(int priority)
{


+ 2
- 3
src/Discord.Net.Commands/Builders/CommandBuilder.cs View File

@@ -1,8 +1,7 @@
using System;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;

namespace Discord.Commands.Builders
{
@@ -140,4 +139,4 @@ namespace Discord.Commands.Builders
return new CommandInfo(this, info, service);
}
}
}
}

+ 0
- 1
src/Discord.Net.Commands/Builders/ModuleBuilder.cs View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace Discord.Commands.Builders
{


+ 0
- 1
src/Discord.Net.Commands/CommandMatch.cs View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace Discord.Commands
{


+ 0
- 1
src/Discord.Net.Commands/CommandService.cs View File

@@ -6,7 +6,6 @@ using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Discord.Commands.Builders;
using Discord.Logging;



+ 1
- 1
src/Discord.Net.Commands/Results/ParseResult.cs View File

@@ -24,7 +24,7 @@ namespace Discord.Commands
Error = error;
ErrorReason = errorReason;
}
public static ParseResult FromSuccess(IReadOnlyList<TypeReaderResult> argValues, IReadOnlyList<TypeReaderResult> paramValues)
{
for (int i = 0; i < argValues.Count; i++)


+ 24
- 0
src/Discord.Net.Commands/Results/PreconditionResult.cs View File

@@ -2,6 +2,9 @@ using System.Diagnostics;

namespace Discord.Commands
{
/// <summary>
/// Represents a result type for command preconditions.
/// </summary>
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class PreconditionResult : IResult
{
@@ -13,19 +16,40 @@ namespace Discord.Commands
/// <inheritdoc/>
public bool IsSuccess => !Error.HasValue;

/// <summary>
/// Initializes a new <see cref="PreconditionResult" /> class with the command <paramref name="error"/> type
/// and reason.
/// </summary>
/// <param name="error">The type of failure.</param>
/// <param name="errorReason">The reason of failure.</param>
protected PreconditionResult(CommandError? error, string errorReason)
{
Error = error;
ErrorReason = errorReason;
}

/// <summary>
/// Returns a <see cref="PreconditionResult" /> with no errors.
/// </summary>
public static PreconditionResult FromSuccess()
=> new PreconditionResult(null, null);
/// <summary>
/// Returns a <see cref="PreconditionResult" /> with <see cref="CommandError.UnmetPrecondition" /> and the
/// specified reason.
/// </summary>
/// <param name="reason">The reason of failure.</param>
public static PreconditionResult FromError(string reason)
=> new PreconditionResult(CommandError.UnmetPrecondition, reason);
/// <summary>
/// Returns a <see cref="PreconditionResult" /> with the specified <paramref name="result"/> type.
/// </summary>
/// <param name="result">The result of failure.</param>
public static PreconditionResult FromError(IResult result)
=> new PreconditionResult(result.Error, result.ErrorReason);

/// <summary>
/// Returns a string indicating whether the <see cref="PreconditionResult"/> is successful.
/// </summary>
public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}";
private string DebuggerDisplay => IsSuccess ? "Success" : $"{Error}: {ErrorReason}";
}


+ 5
- 0
src/Discord.Net.Commands/Results/RuntimeResult.cs View File

@@ -5,6 +5,11 @@ namespace Discord.Commands
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public abstract class RuntimeResult : IResult
{
/// <summary>
/// Initializes a new <see cref="RuntimeResult" /> class with the type of error and reason.
/// </summary>
/// <param name="error">The type of failure, or <see langword="null" /> if none.</param>
/// <param name="reason">The reason of failure.</param>
protected RuntimeResult(CommandError? error, string reason)
{
Error = error;


+ 1
- 1
src/Discord.Net.Core/CDN.cs View File

@@ -3,7 +3,7 @@ using System;
namespace Discord
{
/// <summary>
/// A class containing the strings related to various Content Delivery Networks (CDNs).
/// Represents a class containing the strings related to various Content Delivery Networks (CDNs).
/// </summary>
public static class CDN
{


+ 16
- 14
src/Discord.Net.Core/Logging/LogSeverity.cs View File

@@ -1,31 +1,33 @@
namespace Discord
{
/// <summary> Specifies the severity of the log message. </summary>
/// <summary>
/// Specifies the severity of the log message.
/// </summary>
public enum LogSeverity
{
/// <summary>
/// Logs that contain the most severe level of error.
/// This type of error indicate that immediate attention may be required.
/// <summary>
/// Logs that contain the most severe level of error. This type of error indicate that immediate attention
/// may be required.
/// </summary>
Critical = 0,
/// <summary>
/// Logs that highlight when the flow of execution is stopped due to a failure.
/// <summary>
/// Logs that highlight when the flow of execution is stopped due to a failure.
/// </summary>
Error = 1,
/// <summary>
/// Logs that highlight an abnormal activity in the flow of execution.
/// <summary>
/// Logs that highlight an abnormal activity in the flow of execution.
/// </summary>
Warning = 2,
/// <summary>
/// Logs that track the general flow of the application.
/// <summary>
/// Logs that track the general flow of the application.
/// </summary>
Info = 3,
/// <summary>
/// Logs that are used for interactive investigation during development.
/// <summary>
/// Logs that are used for interactive investigation during development.
/// </summary>
Verbose = 4,
/// <summary>
/// Logs that contain the most detailed messages.
/// <summary>
/// Logs that contain the most detailed messages.
/// </summary>
Debug = 5
}


+ 28
- 11
src/Discord.Net.Core/Utils/Cacheable.cs View File

@@ -3,20 +3,29 @@ using System.Threading.Tasks;

namespace Discord
{
/// <summary> Contains an entity that may be cached. </summary>
/// <typeparam name="TEntity"> The type of entity that is cached. </typeparam>
/// <typeparam name="TId"> The type of this entity's ID. </typeparam>
/// <summary>
/// Represents a <see langword="struct"/> that contains an entity that may be cached.
/// </summary>
/// <typeparam name="TEntity">The type of entity that is cached.</typeparam>
/// <typeparam name="TId">The type of this entity's ID.</typeparam>
public struct Cacheable<TEntity, TId>
where TEntity : IEntity<TId>
where TId : IEquatable<TId>
{
/// <summary> Indicates whether this entity is cached. </summary>
/// <summary>
/// Gets whether this entity is cached.
/// </summary>
public bool HasValue { get; }
/// <summary> Gets the ID of this entity. </summary>
/// <summary>
/// Gets the ID of this entity.
/// </summary>
public TId Id { get; }
/// <summary> Gets the entity if it could be pulled from cache. </summary>
/// <summary>
/// Gets the entity if it could be pulled from cache.
/// </summary>
/// <remarks>
/// This value is not guaranteed to be set; in cases where the entity cannot be pulled from cache, it is null.
/// This value is not guaranteed to be set; in cases where the entity cannot be pulled from cache, it is
/// null.
/// </remarks>
public TEntity Value { get; }
private Func<Task<TEntity>> DownloadFunc { get; }
@@ -29,19 +38,27 @@ namespace Discord
DownloadFunc = downloadFunc;
}

/// <summary> Downloads this entity to cache. </summary>
/// <returns>An awaitable Task containing the downloaded entity.</returns>
/// <summary>
/// Downloads this entity to cache.
/// </summary>
/// <exception cref="Discord.Net.HttpException">Thrown when used from a user account.</exception>
/// <exception cref="NullReferenceException">Thrown when the message is deleted.</exception>
/// <returns>
/// An awaitable <see cref="Task"/> containing the downloaded entity.
/// </returns>
public async Task<TEntity> DownloadAsync()
{
return await DownloadFunc().ConfigureAwait(false);
}

/// <summary> Returns the cached entity if it exists; otherwise downloads it. </summary>
/// <returns>An awaitable Task containing a cached or downloaded entity.</returns>
/// <summary>
/// Returns the cached entity if it exists; otherwise downloads it.
/// </summary>
/// <exception cref="Discord.Net.HttpException">Thrown when used from a user account.</exception>
/// <exception cref="NullReferenceException">Thrown when the message is deleted and is not in cache.</exception>
/// <returns>
/// An awaitable <see cref="Task"/> containing a cached or downloaded entity.
/// </returns>
public async Task<TEntity> GetOrDownloadAsync() => HasValue ? Value : await DownloadAsync().ConfigureAwait(false);
}
}

+ 1
- 1
src/Discord.Net.Core/Utils/Comparers.cs View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace Discord
{
/// <summary>
/// Represents a collection of <see cref="IEqualityComparer{T}"/> for various Discord objects.
/// Represents a collection of <see cref="IEqualityComparer{T}"/> for various Discord objects.
/// </summary>
public static class DiscordComparers
{


+ 30
- 10
src/Discord.Net.Core/Utils/MentionUtils.cs View File

@@ -4,30 +4,42 @@ using System.Text;

namespace Discord
{
/// <summary> A helper class for mention-related parsing. </summary>
/// <summary>
/// Represents a helper class for mention-related parsing.
/// </summary>
public static class MentionUtils
{
private const char SanitizeChar = '\x200b';

//If the system can't be positive a user doesn't have a nickname, assume useNickname = true (source: Jake)
internal static string MentionUser(string id, bool useNickname = true) => useNickname ? $"<@!{id}>" : $"<@{id}>";
/// <summary> Returns a mention string based on the user ID. </summary>
/// <summary>
/// Returns a mention string based on the user ID.
/// </summary>
public static string MentionUser(ulong id) => MentionUser(id.ToString(), true);
internal static string MentionChannel(string id) => $"<#{id}>";
/// <summary> Returns a mention string based on the channel ID. </summary>
/// <summary>
/// Returns a mention string based on the channel ID.
/// </summary>
public static string MentionChannel(ulong id) => MentionChannel(id.ToString());
internal static string MentionRole(string id) => $"<@&{id}>";
/// <summary> Returns a mention string based on the role ID. </summary>
/// <summary>
/// Returns a mention string based on the role ID.
/// </summary>
public static string MentionRole(ulong id) => MentionRole(id.ToString());

/// <summary> Parses a provided user mention string. </summary>
/// <summary>
/// Parses a provided user mention string.
/// </summary>
public static ulong ParseUser(string text)
{
if (TryParseUser(text, out ulong id))
return id;
throw new ArgumentException("Invalid mention format", nameof(text));
}
/// <summary> Tries to parse a provided user mention string. </summary>
/// <summary>
/// Tries to parse a provided user mention string.
/// </summary>
public static bool TryParseUser(string text, out ulong userId)
{
if (text.Length >= 3 && text[0] == '<' && text[1] == '@' && text[text.Length - 1] == '>')
@@ -44,14 +56,18 @@ namespace Discord
return false;
}

/// <summary> Parses a provided channel mention string. </summary>
/// <summary>
/// Parses a provided channel mention string.
/// </summary>
public static ulong ParseChannel(string text)
{
if (TryParseChannel(text, out ulong id))
return id;
throw new ArgumentException("Invalid mention format", nameof(text));
}
/// <summary>Tries to parse a provided channel mention string. </summary>
/// <summary>
/// Tries to parse a provided channel mention string.
/// </summary>
public static bool TryParseChannel(string text, out ulong channelId)
{
if (text.Length >= 3 && text[0] == '<' && text[1] == '#' && text[text.Length - 1] == '>')
@@ -65,14 +81,18 @@ namespace Discord
return false;
}

/// <summary> Parses a provided role mention string. </summary>
/// <summary>
/// Parses a provided role mention string.
/// </summary>
public static ulong ParseRole(string text)
{
if (TryParseRole(text, out ulong id))
return id;
throw new ArgumentException("Invalid mention format", nameof(text));
}
/// <summary>Tries to parse a provided role mention string. </summary>
/// <summary>
/// Tries to parse a provided role mention string.
/// </summary>
public static bool TryParseRole(string text, out ulong roleId)
{
if (text.Length >= 4 && text[0] == '<' && text[1] == '@' && text[2] == '&' && text[text.Length - 1] == '>')


Loading…
Cancel
Save