Visitar URL original
Made DiscordMessageFile a more generic file container by AlexanderTPohl · Pull Request #2422 · DSharpPlus/DSharpPlus · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions DSharpPlus/Entities/AddFileOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;

namespace DSharpPlus.Entities;

/// <summary>
/// Additional flags for handling file upload streams.
/// </summary>
[Flags]
public enum AddFileOptions
{
/// <summary>
/// No additional behavior. The stream will read to completion and is left at that position after sending.
/// </summary>
None = 0,

/// <summary>
/// Resets the stream to its original position after sending.
/// </summary>
ResetStream = 0x1,

/// <summary>
/// Closes the stream upon sending.
/// </summary>
CloseStream = 0x2,

/// <summary>
/// Immediately reads the stream to completion and copies its contents to an in-memory stream.
/// </summary>
/// <remarks>
/// <para>
/// Note that this incurs an additional memory overhead and may perform synchronous I/O and should only be used if the source stream cannot be kept open any longer.
/// </para>
/// <para>
/// If specified together with <see cref="CloseStream"/>, the stream will closed immediately after the copy.
/// </para>
/// </remarks>
CopyStream = 0x4,
}
116 changes: 9 additions & 107 deletions DSharpPlus/Entities/BaseDiscordMessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using DSharpPlus.Net;

namespace DSharpPlus.Entities;
Expand Down Expand Up @@ -107,8 +106,8 @@ public T DisableV2Components()
/// <summary>
/// Files to send on this webhook request.
/// </summary>
public IReadOnlyList<DiscordMessageFile> Files => this.files;
internal List<DiscordMessageFile> files = [];
public IReadOnlyList<DiscordFile> Files => this.files;
internal List<DiscordFile> files = [];

/// <summary>
/// Mentions to send on this webhook request.
Expand Down Expand Up @@ -476,7 +475,7 @@ public T AddFile(string fileName, Stream stream, AddFileOptions fileOptions)

stream = ResolveStream(stream, fileOptions);
long? resetPosition = fileOptions.HasFlag(AddFileOptions.ResetStream) ? stream.Position : null;
this.files.Add(new DiscordMessageFile(fileName, stream, resetPosition, fileOptions: fileOptions));
this.files.Add(new DiscordFile(fileName, stream, resetPosition, fileOptions: fileOptions));

return (T)this;
}
Expand Down Expand Up @@ -511,13 +510,13 @@ public T AddFiles(IDictionary<string, Stream> files, AddFileOptions fileOptions)

Stream stream = ResolveStream(file.Value, fileOptions);
long? resetPosition = fileOptions.HasFlag(AddFileOptions.ResetStream) ? stream.Position : null;
this.files.Add(new DiscordMessageFile(file.Key, stream, resetPosition, fileOptions: fileOptions));
this.files.Add(new DiscordFile(file.Key, stream, resetPosition, fileOptions: fileOptions));
}

return (T)this;
}

public T AddFiles(IEnumerable<DiscordMessageFile> files)
public T AddFiles(IEnumerable<DiscordFile> files)
{
this.files.AddRange(files);
return (T)this;
Expand Down Expand Up @@ -563,65 +562,6 @@ public virtual void Clear()
this.Flags = default;
}

/// <inheritdoc/>
public void Dispose()
{
// We don't bother to fully implement the dispose pattern
// since deriving from this type outside this assembly is unusual.

foreach (DiscordMessageFile file in this.files)
{
if (file.FileOptions.HasFlag(AddFileOptions.CloseStream))
{
if (file.Stream is RequestStreamWrapper wrapper)
{
wrapper.UnderlyingStream.Dispose();
}
else
{
file.Stream.Dispose();
}
}
}

GC.SuppressFinalize(this);
}

/// <inheritdoc/>
public async ValueTask DisposeAsync()
{
foreach (DiscordMessageFile file in this.files)
{
if (file.FileOptions.HasFlag(AddFileOptions.CloseStream))
{
if (file.Stream is RequestStreamWrapper wrapper)
{
await wrapper.UnderlyingStream.DisposeAsync();
}
else
{
await file.Stream.DisposeAsync();
}
}
}

GC.SuppressFinalize(this);
}

/// <summary>
/// Helper method to reset stream positions used several times by the API client.
/// </summary>
internal void ResetFileStreamPositions()
{
foreach (DiscordMessageFile file in this.files)
{
if (file.ResetPositionTo is long pos)
{
file.Stream.Seek(pos, SeekOrigin.Begin);
}
}
}

/// <summary>
/// Helper method to resolve stream copies depending on the file mode parameter.
/// </summary>
Expand Down Expand Up @@ -748,56 +688,18 @@ private void ThrowIfV2Enabled([CallerMemberName] string caller = "")
IDiscordMessageBuilder IDiscordMessageBuilder.AddFile(string fileName, Stream stream, bool resetStream) => AddFile(fileName, stream, resetStream);
IDiscordMessageBuilder IDiscordMessageBuilder.AddFile(FileStream stream, bool resetStream) => AddFile(stream, resetStream);
IDiscordMessageBuilder IDiscordMessageBuilder.AddFiles(IDictionary<string, Stream> files, bool resetStreams) => AddFiles(files, resetStreams);
IDiscordMessageBuilder IDiscordMessageBuilder.AddFiles(IEnumerable<DiscordMessageFile> files) => AddFiles(files);
IDiscordMessageBuilder IDiscordMessageBuilder.AddFiles(IEnumerable<DiscordFile> files) => AddFiles(files);
IDiscordMessageBuilder IDiscordMessageBuilder.AddFile(string fileName, Stream stream, AddFileOptions fileOptions) => AddFile(fileName, stream, fileOptions);
IDiscordMessageBuilder IDiscordMessageBuilder.AddFile(FileStream stream, AddFileOptions fileOptions) => AddFile(stream, fileOptions);
IDiscordMessageBuilder IDiscordMessageBuilder.AddFiles(IDictionary<string, Stream> files, AddFileOptions fileOptions) => AddFiles(files, fileOptions);
IDiscordMessageBuilder IDiscordMessageBuilder.AddMention(IMention mention) => AddMention(mention);
IDiscordMessageBuilder IDiscordMessageBuilder.AddMentions(IEnumerable<IMention> mentions) => AddMentions(mentions);
}

/// <summary>
/// Additional flags for files added to a message builder.
/// </summary>
[Flags]
public enum AddFileOptions
{
/// <summary>
/// No additional behavior. The stream will read to completion and is left at that position after sending.
/// </summary>
None = 0,

/// <summary>
/// Resets the stream to its original position after sending.
/// </summary>
ResetStream = 0x1,

/// <summary>
/// Closes the stream upon disposal of the message builder.
/// </summary>
/// <remarks>
/// Streams will not be disposed upon sending. Disposal of the message builder is necessary.
/// </remarks>
CloseStream = 0x2,

/// <summary>
/// Immediately reads the stream to completion and copies its contents to an in-memory stream.
/// </summary>
/// <remarks>
/// <para>
/// Note that this incurs an additional memory overhead and may perform synchronous I/O and should only be used if the source stream cannot be kept open any longer.
/// </para>
/// <para>
/// If specified together with <see cref="CloseStream"/>, the stream will closed immediately after the copy.
/// </para>
/// </remarks>
CopyStream = 0x4,
}

/// <summary>
/// Base interface for any discord message builder.
/// </summary>
public interface IDiscordMessageBuilder : IDisposable, IAsyncDisposable
public interface IDiscordMessageBuilder
{
/// <summary>
/// Getter / setter for message content.
Expand All @@ -822,7 +724,7 @@ public interface IDiscordMessageBuilder : IDisposable, IAsyncDisposable
/// <summary>
/// All files on this message.
/// </summary>
public IReadOnlyList<DiscordMessageFile> Files { get; }
public IReadOnlyList<DiscordFile> Files { get; }

/// <summary>
/// All components on this message.
Expand Down Expand Up @@ -1011,7 +913,7 @@ public interface IDiscordMessageBuilder : IDisposable, IAsyncDisposable
/// </summary>
/// <param name="files">Previously attached files to reattach</param>
/// <returns></returns>
public IDiscordMessageBuilder AddFiles(IEnumerable<DiscordMessageFile> files);
public IDiscordMessageBuilder AddFiles(IEnumerable<DiscordFile> files);

/// <summary>
/// Adds an allowed mention to this message.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
using System.IO;
namespace DSharpPlus.Entities;
/// <summary>
/// Represents files that should be sent to Discord as part of a <seealso cref="DiscordMessageBuilder"/>.
/// </summary>
public record struct DiscordMessageFile
{
public DiscordMessageFile
(
string fileName,
Stream stream,
long? resetPositionTo = null,
string? fileType = null,
string? contentType = null,
AddFileOptions fileOptions = AddFileOptions.None
)
{
this.FileName = fileName ?? "file";
this.FileType = fileType;
this.ContentType = contentType;
this.FileOptions = fileOptions;
this.Stream = stream;
this.ResetPositionTo = resetPositionTo;
}
/// <summary>
/// Gets the FileName of the File.
/// </summary>
public string FileName { get; internal set; }
/// <summary>
/// Gets the stream of the File.
/// </summary>
public Stream Stream { get; internal set; }
internal string? FileType { get; set; }
internal string? ContentType { get; set; }
/// <summary>
/// Gets the position the File should be reset to.
/// </summary>
internal long? ResetPositionTo { get; set; }
internal AddFileOptions FileOptions { get; set; }
}
using System.IO;

namespace DSharpPlus.Entities;

/// <summary>
/// Represents a file to be sent to Discord.
/// </summary>
public record struct DiscordFile
{
public DiscordFile
(
string fileName,
Stream stream,
long? resetPositionTo = null,
string? fileType = null,
string? contentType = null,
AddFileOptions fileOptions = AddFileOptions.None
)
{
this.FileName = fileName ?? "file";
this.FileType = fileType;
this.ContentType = contentType;
this.FileOptions = fileOptions;
this.Stream = stream;
this.ResetPositionTo = resetPositionTo;
}

/// <summary>
/// Gets the FileName of the File.
/// </summary>
public string FileName { get; internal set; }

/// <summary>
/// Gets the stream of the File.
/// </summary>
public Stream Stream { get; internal set; }

internal string? FileType { get; set; }

internal string? ContentType { get; set; }

/// <summary>
/// Gets the position the File should be reset to.
/// </summary>
internal long? ResetPositionTo { get; set; }
internal AddFileOptions FileOptions { get; set; }
}
2 changes: 1 addition & 1 deletion DSharpPlus/Entities/Guild/DiscordGuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2292,7 +2292,7 @@ public async Task<DiscordMessageSticker> CreateStickerAsync(string name, string
extension = "json";
}

return await this.Discord.ApiClient.CreateGuildStickerAsync(this.Id, name, description ?? string.Empty, tags, new DiscordMessageFile(null, imageContents, null, extension, contentType), reason);
return await this.Discord.ApiClient.CreateGuildStickerAsync(this.Id, name, description ?? string.Empty, tags, new DiscordFile(null, imageContents, null, extension, contentType), reason);
}

/// <summary>
Expand Down
Loading
Loading