Skip to content

Commit

Permalink
Moved all inbox .NET implementations to a corresponding OwlCore.Stora…
Browse files Browse the repository at this point in the history
…ge.System.* namespace

See #48
  • Loading branch information
Arlodotexe committed Mar 17, 2024
1 parent c35046e commit e3e1a4b
Show file tree
Hide file tree
Showing 19 changed files with 48 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/Extensions/IGetRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace OwlCore.Storage;

/// <summary>
/// Provides a fast-path for the <see cref="StorableChildExtensions.GetRootAsync(IStorableChild)"/> extension method.
/// Provides a fast-path for the <see cref="StorableChildExtensions.GetRootAsync(IStorableChild, CancellationToken)"/> extension method.
/// </summary>
public interface IGetRoot : IStorableChild
{
Expand Down
1 change: 1 addition & 0 deletions src/OwlCore.Storage.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ THIS IS A BREAKING RELEASE
Update asap, and do not use older versions or implementations.

[Breaking]
All inbox implementations that rely on .NET itself have been moved to the OwlCore.Storage.System.* namespace, making room for future inbox implementations (System.Formats.Tar, System.Data.Common, System.Resources, etc).
The default FileAccess.Read parameter for IFile.OpenStreamAsync has been removed. This is primarily to avoid confusion about why the default returned stream can't be written to, but follows the concept that simply opening a stream implies nothing about read/write preferences for that resource, so no default value should be used.
Generics for the Move and Copy interfaces and methods have been removed. This fixes an issue where only the fallback path was being used unless the most derived type was specified, and generally allows for more flexible implementations.
When "overwrite" in the Move and Copy interfaces / extension methods is set to false, the operation will fail if the destination already exists. Previously if overwrite was false, any existing destination file would be returned untouched with no data copied over.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using System.Threading.Tasks;
using IOPath = System.IO.Path;

namespace OwlCore.Storage.Archive;
namespace OwlCore.Storage.System.IO.Compression;

/// <summary>
/// A folder implementation wrapping a <see cref="ZipArchive"/> with
Expand Down Expand Up @@ -166,16 +166,16 @@ public async Task<IStorableChild> GetItemAsync(string id, CancellationToken canc
// Get folder
string subfolderId = NormalizeEnding(id);
var virtualFolders = GetVirtualFolders();

if (!virtualFolders.TryGetValue(subfolderId, out var subfolder))
throw new FileNotFoundException($"No item with ID '{id}' or '{subfolderId}' exists in '{Id}'.");

item = subfolder;
}

return item;
}

/// <inheritdoc/>
public async Task<IStorableChild> GetFirstByNameAsync(string name, CancellationToken cancellationToken = default)
=> await GetItemAsync(Id + name, cancellationToken);
Expand Down Expand Up @@ -205,7 +205,7 @@ public async Task<IStorableChild> GetFirstByNameAsync(string name, CancellationT
throw new ArgumentNullException(nameof(Archive));

return Archive.Mode != ZipArchiveMode.Create
? (Archive.GetEntry(entryName) ?? Archive.GetEntry(entryName.TrimEnd(ZIP_DIRECTORY_SEPARATOR)))
? Archive.GetEntry(entryName) ?? Archive.GetEntry(entryName.TrimEnd(ZIP_DIRECTORY_SEPARATOR))
: null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace OwlCore.Storage.Archive;
namespace OwlCore.Storage.System.IO.Compression;

/// <summary>
/// A file implementation wrapping a <see cref="ZipArchiveEntry"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace OwlCore.Storage.Archive;
namespace OwlCore.Storage.System.IO.Compression;

/// <summary>
/// A folder implementation wrapping a <see cref="ZipArchive"/>.
Expand Down Expand Up @@ -133,7 +133,7 @@ public Task<IFolderWatcher> GetFolderWatcherAsync(CancellationToken cancellation
}

/// <summary>
/// Manually opens the <see cref="Archive"/>.
/// Manually opens the archive for this folder.
/// </summary>
/// <returns>The opened archive.</returns>
public override async Task<ZipArchive> OpenArchiveAsync(CancellationToken cancellationToken = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Collections.Specialized;
using System.Threading.Tasks;

namespace OwlCore.Storage.Archive;
namespace OwlCore.Storage.System.IO.Compression;

/// <summary>
/// An empty implementation of an <see cref="IFolderWatcher"/> for <see cref="ZipArchiveFolder"/>.
Expand Down
4 changes: 2 additions & 2 deletions src/StreamFile.cs → src/System/IO/StreamFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
using System.Threading.Tasks;
using OwlCore.Storage.Memory;

namespace OwlCore.Storage;
namespace OwlCore.Storage.System.IO;

/// <summary>
/// A file implementation which holds a reference to the provided <see cref="StreamFile.Stream"/> and returns it in a non-disposable wrapper for <see cref="OpenStreamAsync"/>.
/// A file implementation which holds a reference to the provided <see cref="Stream"/> and returns it in a non-disposable wrapper for <see cref="OpenStreamAsync"/>.
/// </summary>
public class StreamFile : IFile
{
Expand Down
6 changes: 3 additions & 3 deletions src/SystemIO/SystemFile.cs → src/System/IO/SystemFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace OwlCore.Storage.SystemIO;
namespace OwlCore.Storage.System.IO;

/// <summary>
/// An <see cref="IFolder"/> implementation that uses System.IO.
Expand All @@ -20,7 +20,7 @@ public class SystemFile : IChildFile, IGetRoot
/// <param name="path">The path to the file.</param>
public SystemFile(string path)
{
foreach (var c in System.IO.Path.GetInvalidPathChars())
foreach (var c in global::System.IO.Path.GetInvalidPathChars())
{
if (path.Contains(c))
throw new FormatException($"Provided path contains invalid character: {c}");
Expand Down Expand Up @@ -53,7 +53,7 @@ public SystemFile(FileInfo info)
public string Id { get; }

/// <inheritdoc />
public string Name => _name ??= System.IO.Path.GetFileName(Path);
public string Name => _name ??= global::System.IO.Path.GetFileName(Path);

/// <summary>
/// Gets the path of the file on disk.
Expand Down
34 changes: 17 additions & 17 deletions src/SystemIO/SystemFolder.cs → src/System/IO/SystemFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#pragma warning disable CS1998

namespace OwlCore.Storage.SystemIO;
namespace OwlCore.Storage.System.IO;

/// <summary>
/// An <see cref="IFolder"/> implementation that uses System.IO.
Expand All @@ -24,7 +24,7 @@ public class SystemFolder : IModifiableFolder, IChildFolder, ICreateCopyOf, IMov
public SystemFolder(string path)
: this(new DirectoryInfo(path))
{
foreach (var c in System.IO.Path.GetInvalidPathChars())
foreach (var c in global::System.IO.Path.GetInvalidPathChars())
{
if (path.Contains(c))
throw new FormatException($"Provided path contains invalid character: {c}");
Expand All @@ -40,13 +40,13 @@ public SystemFolder(DirectoryInfo info)
_info = info;

// For consistency, always remove the trailing directory separator.
Path = info.FullName.TrimEnd(System.IO.Path.PathSeparator, System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar);
Path = info.FullName.TrimEnd(global::System.IO.Path.PathSeparator, global::System.IO.Path.DirectorySeparatorChar, global::System.IO.Path.AltDirectorySeparatorChar);

if (!Directory.Exists(Path))
throw new FileNotFoundException($"Directory not found at path {Path}");

Id = Path;
Name = System.IO.Path.GetFileName(Path) ?? throw new ArgumentException($"Could not determine directory name from path {Path}");
Name = global::System.IO.Path.GetFileName(Path) ?? throw new ArgumentException($"Could not determine directory name from path {Path}");
}

/// <summary>
Expand Down Expand Up @@ -145,8 +145,8 @@ public Task<IStorableChild> GetItemAsync(string id, CancellationToken cancellati
if (IsFile(id))
{
// Capture file name, combine with known path. Forces reading from current folder only.
var fileName = System.IO.Path.GetFileName(id) ?? throw new ArgumentException($"Could not determine file name from id: {id}");
var fullPath = System.IO.Path.Combine(Path, fileName);
var fileName = global::System.IO.Path.GetFileName(id) ?? throw new ArgumentException($"Could not determine file name from id: {id}");
var fullPath = global::System.IO.Path.Combine(Path, fileName);

if (!File.Exists(fullPath))
throw new FileNotFoundException($"The provided ID does not belong to an item in this folder.");
Expand All @@ -157,7 +157,7 @@ public Task<IStorableChild> GetItemAsync(string id, CancellationToken cancellati
if (IsFolder(id))
{
// Ensure containing directory matches current folder.
if (System.IO.Path.GetDirectoryName(id) != Path || !Directory.Exists(id))
if (global::System.IO.Path.GetDirectoryName(id) != Path || !Directory.Exists(id))
throw new FileNotFoundException($"The provided ID does not belong to an item in this folder.");

return Task.FromResult<IStorableChild>(new SystemFolder(id));
Expand All @@ -169,7 +169,7 @@ public Task<IStorableChild> GetItemAsync(string id, CancellationToken cancellati
/// <inheritdoc/>
public async Task<IStorableChild> GetFirstByNameAsync(string name, CancellationToken cancellationToken = default)
{
return await GetItemAsync(System.IO.Path.Combine(Path, name), cancellationToken);
return await GetItemAsync(global::System.IO.Path.Combine(Path, name), cancellationToken);
}

/// <inheritdoc />
Expand All @@ -182,7 +182,7 @@ public Task<IFolderWatcher> GetFolderWatcherAsync(CancellationToken cancellation
public Task DeleteAsync(IStorableChild item, CancellationToken cancellationToken = default)
{
// Ensure containing directory matches current folder.
if (GetParentPath(item.Id).TrimEnd(System.IO.Path.DirectorySeparatorChar) != Path)
if (GetParentPath(item.Id).TrimEnd(global::System.IO.Path.DirectorySeparatorChar) != Path)
throw new FileNotFoundException($"The provided item does not exist in this folder.");

if (IsFolder(item.Id))
Expand All @@ -202,7 +202,7 @@ public async Task<IChildFile> CreateCopyOfAsync(IFile fileToCopy, bool overwrite
return await fallback(this, fileToCopy, overwrite, cancellationToken);

// Handle using System.IO
var newPath = System.IO.Path.Combine(Path, systemFile.Name);
var newPath = global::System.IO.Path.Combine(Path, systemFile.Name);

// If the source and destination are the same, there's no need to copy.
if (systemFile.Path == newPath)
Expand All @@ -229,7 +229,7 @@ public async Task<IChildFile> MoveFromAsync(IChildFile fileToMove, IModifiableFo
return await fallback(this, fileToMove, source, overwrite, cancellationToken);

// Handle using System.IO
var newPath = System.IO.Path.Combine(Path, systemFile.Name);
var newPath = global::System.IO.Path.Combine(Path, systemFile.Name);
if (File.Exists(newPath) && !overwrite)
return new SystemFile(newPath);

Expand All @@ -244,7 +244,7 @@ public async Task<IChildFile> MoveFromAsync(IChildFile fileToMove, IModifiableFo
/// <inheritdoc />
public Task<IChildFolder> CreateFolderAsync(string name, bool overwrite = false, CancellationToken cancellationToken = default)
{
var newPath = System.IO.Path.Combine(Path, name);
var newPath = global::System.IO.Path.Combine(Path, name);

try
{
Expand All @@ -263,7 +263,7 @@ public Task<IChildFolder> CreateFolderAsync(string name, bool overwrite = false,
/// <inheritdoc />
public Task<IChildFile> CreateFileAsync(string name, bool overwrite = false, CancellationToken cancellationToken = default)
{
var newPath = System.IO.Path.Combine(Path, name);
var newPath = global::System.IO.Path.Combine(Path, name);

if (overwrite || !File.Exists(newPath))
File.Create(newPath).Dispose();
Expand All @@ -283,24 +283,24 @@ public Task<IChildFile> CreateFileAsync(string name, bool overwrite = false, Can
return Task.FromResult<IFolder?>(new SystemFolder(Info.Root));
}

private static bool IsFile(string path) => System.IO.Path.GetFileName(path) is { } str && str != string.Empty && File.Exists(path);
private static bool IsFile(string path) => global::System.IO.Path.GetFileName(path) is { } str && str != string.Empty && File.Exists(path);
private static bool IsFolder(string path) => Directory.Exists(path);

string GetParentPath(string relativePath)
{
// Path.GetDirectoryName() treats strings that end with a directory separator as a directory. If there's no trailing slash, it's treated as a file.
// Run it twice for folders. The first time only shaves off the trailing directory separator.
var parentDirectoryName = relativePath.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) ? System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(relativePath)) : System.IO.Path.GetDirectoryName(relativePath);
var parentDirectoryName = relativePath.EndsWith(global::System.IO.Path.DirectorySeparatorChar.ToString()) ? global::System.IO.Path.GetDirectoryName(global::System.IO.Path.GetDirectoryName(relativePath)) : global::System.IO.Path.GetDirectoryName(relativePath);

// It also doesn't return a string that has a path separator at the end.
return parentDirectoryName + System.IO.Path.DirectorySeparatorChar;
return parentDirectoryName + global::System.IO.Path.DirectorySeparatorChar;
}

string GetParentDirectoryName(string relativePath)
{
var parentPath = GetParentPath(relativePath);
var parentParentPath = GetParentPath(parentPath);

return parentPath.Replace(parentParentPath, "").TrimEnd(System.IO.Path.DirectorySeparatorChar);
return parentPath.Replace(parentParentPath, "").TrimEnd(global::System.IO.Path.DirectorySeparatorChar);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.IO;
using System.Threading.Tasks;

namespace OwlCore.Storage.SystemIO
namespace OwlCore.Storage.System.IO
{
/// <summary>
/// Watches for changes in a System.IO folder.
Expand Down Expand Up @@ -85,7 +85,7 @@ public ValueTask DisposeAsync()
/// Creates an System.IO based instance of <see cref="IStorable"/> given the provided <paramref name="path"/>.
/// </summary>
/// <param name="path">The path to use for the new item.</param>
/// <param name="minimalImplementation">Indicates whether or not to use a fully functional file/folder implementation, or a minimal implementation of <see cref="IStorable"/>. The latter is needed when an item is removed, since you can't interact with a deleted resource.</param>
/// <param name="minimalImplementation">Indicates whether to use a fully functional file/folder implementation, or a minimal implementation of <see cref="IStorable"/>. The latter is needed when an item is removed, since you can't interact with a deleted resource.</param>
/// <returns></returns>
/// <exception cref="ArgumentException">Could not determine if the provided path is a file or folder.</exception>
private static IStorable CreateStorableFromPath(string path, bool minimalImplementation = false)
Expand Down
2 changes: 1 addition & 1 deletion src/HttpFile.cs → src/System/Net/Http/HttpFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace OwlCore.Storage;
namespace OwlCore.Storage.System.Net.Http;

/// <summary>
/// A file implementation which calls GET on a provided HTTP URL and returns it for <see cref="OpenStreamAsync"/>.
Expand Down
4 changes: 2 additions & 2 deletions tests/OwlCore.Storage.Tests/Archive/ZipArchive/IFileTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.Archive;
using OwlCore.Storage.System.IO;
using OwlCore.Storage.System.IO.Compression;
using System.IO.Compression;
using OwlCore.Storage.SystemIO;

namespace OwlCore.Storage.Tests.Archive.ZipArchive;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.Archive;
using OwlCore.Storage.System.IO;
using OwlCore.Storage.System.IO.Compression;
using System.IO.Compression;
using OwlCore.Storage.SystemIO;

namespace OwlCore.Storage.Tests.Archive.ZipArchive;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.Archive;
using System.IO.Compression;
using OwlCore.Storage.Memory;
using OwlCore.Storage.System.IO.Compression;
using System.IO.Compression;

namespace OwlCore.Storage.Tests.Archive.ZipArchive;

Expand All @@ -16,7 +16,7 @@ public override Task<IFile> CreateFileAsync()
{
var archiveStream = new MemoryStream();
var sourceFile = new MemoryFile($"{Guid.NewGuid()}", $"{Guid.NewGuid()}", archiveStream);
var archive = new System.IO.Compression.ZipArchive(archiveStream, ZipArchiveMode.Update);
var archive = new global::System.IO.Compression.ZipArchive(archiveStream, ZipArchiveMode.Update);
var entry = archive.CreateEntry($"{Guid.NewGuid()}");

using (var entryStream = entry.Open())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.Archive;
using System.IO.Compression;
using OwlCore.Storage.Memory;
using OwlCore.Storage.System.IO.Compression;

namespace OwlCore.Storage.Tests.Archive.ZipArchive;

Expand Down
1 change: 1 addition & 0 deletions tests/OwlCore.Storage.Tests/HttpFileTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.System.Net.Http;

namespace OwlCore.Storage.Tests;

Expand Down
1 change: 1 addition & 0 deletions tests/OwlCore.Storage.Tests/StreamFileTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.System.IO;

namespace OwlCore.Storage.Tests
{
Expand Down
2 changes: 1 addition & 1 deletion tests/OwlCore.Storage.Tests/SystemIO/IFileTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using OwlCore.Storage.SystemIO;
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.System.IO;

namespace OwlCore.Storage.Tests.SystemIO;

Expand Down
2 changes: 1 addition & 1 deletion tests/OwlCore.Storage.Tests/SystemIO/IFolderTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using OwlCore.Storage.CommonTests;
using OwlCore.Storage.SystemIO;
using OwlCore.Storage.System.IO;

namespace OwlCore.Storage.Tests.SystemIO;

Expand Down

0 comments on commit e3e1a4b

Please sign in to comment.