Skip to content

Commit

Permalink
Merge pull request #60 from Nexus-Mods/combine-operators
Browse files Browse the repository at this point in the history
Implement `/` as an operator alias for `Join` and `Combine`, switch useages of these over to this new operator
  • Loading branch information
halgari authored Nov 11, 2024
2 parents 7b21495 + 7463301 commit 371b035
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static NxUnpackerBuilder AddFilesWithFileSystemOutput(this NxUnpackerBuil
for (var x = 0; x < entries.Length; x++)
{
var entry = entries[x];
var outputPath = outputDirectory.Combine(entry.FilePath);
var outputPath = outputDirectory / entry.FilePath;
outputProviders[x] = new OutputAbsolutePathProvider(outputPath, entry.FilePath, entry.Entry);
}
builder.Outputs.AddRange(outputProviders);
Expand Down
4 changes: 2 additions & 2 deletions src/NexusMods.Paths.Benchmarks/Benchmarks/Paths.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public AbsolutePath NexusJoinSmall()
{
// Not a fair test here since one is a string concat; other includes
// normalization to OS path.
return CurrentPath.AbsolutePath.Combine("foo");
return CurrentPath.AbsolutePath / "foo";
}

[Benchmark]
Expand All @@ -104,7 +104,7 @@ public string SystemJoinLarge()
[Benchmark]
public AbsolutePath NexusJoinLarge()
{
return CurrentPath.AbsolutePath.Combine("foo/bar/baz/quz/qax");
return CurrentPath.AbsolutePath / "foo/bar/baz/quz/qax";
}

[Benchmark]
Expand Down
6 changes: 6 additions & 0 deletions src/NexusMods.Paths/AbsolutePath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ public AbsolutePath Combine(RelativePath path)
var res = PathHelpers.JoinParts(GetFullPath(), path.Path, FileSystem.OS);
return FromSanitizedFullPath(res, FileSystem);
}

/// <summary>
/// Combines the current path with a relative path.
/// </summary>
public static AbsolutePath operator / (AbsolutePath path, RelativePath relativePath)
=> path.Combine(relativePath);

/// <summary/>
[Obsolete(message: "This will be removed once dependents have updated.", error: true)]
Expand Down
30 changes: 15 additions & 15 deletions src/NexusMods.Paths/FileSystemAbstraction/BaseFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ internal AbsolutePath GetMappedPath(AbsolutePath originalPath)
if (newParentDirectory == default) return originalPath;

var relativePath = originalPath.RelativeTo(originalParentDirectory);
var newPath = newParentDirectory.Combine(relativePath);
var newPath = newParentDirectory / relativePath;

return newPath;
}
Expand Down Expand Up @@ -189,10 +189,10 @@ public virtual AbsolutePath GetKnownPath(KnownPath knownPath)
KnownPath.MyDocumentsDirectory => FromUnsanitizedFullPath(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)),
KnownPath.MyGamesDirectory => FromUnsanitizedDirectoryAndFileName(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My Games"),

KnownPath.XDG_CONFIG_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_CONFIG_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory).Combine(".config")),
KnownPath.XDG_CACHE_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_CACHE_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory).Combine(".cache")),
KnownPath.XDG_DATA_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_DATA_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory).Combine(".local").Combine("share")),
KnownPath.XDG_STATE_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_STATE_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory).Combine(".local").Combine("state")),
KnownPath.XDG_CONFIG_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_CONFIG_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory) / ".config"),
KnownPath.XDG_CACHE_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_CACHE_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory) / ".cache"),
KnownPath.XDG_DATA_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_DATA_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory) / ".local" / "share"),
KnownPath.XDG_STATE_HOME => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_STATE_HOME)}", static fs => fs.GetKnownPath(KnownPath.HomeDirectory) / ".local" / "state"),
KnownPath.XDG_RUNTIME_DIR => GetXDGBaseDirectory($"{nameof(KnownPath.XDG_RUNTIME_DIR)}", static fs => fs.GetKnownPath(KnownPath.TempDirectory)),
};

Expand Down Expand Up @@ -244,18 +244,18 @@ public static (Dictionary<AbsolutePath, AbsolutePath> pathMappings, Dictionary<K
KnownPath.EntryDirectory => fileSystem.GetKnownPath(knownPath),
KnownPath.CurrentDirectory => fileSystem.GetKnownPath(knownPath),

KnownPath.CommonApplicationDataDirectory => rootDirectory.Combine("ProgramData"),
KnownPath.ProgramFilesDirectory => rootDirectory.Combine("Program Files"),
KnownPath.ProgramFilesX86Directory => rootDirectory.Combine("Program Files (x86)"),
KnownPath.CommonProgramFilesDirectory => rootDirectory.Combine("Program Files/Common Files"),
KnownPath.CommonProgramFilesX86Directory => rootDirectory.Combine("Program Files (x86)/Common Files"),
KnownPath.CommonApplicationDataDirectory => rootDirectory / "ProgramData",
KnownPath.ProgramFilesDirectory => rootDirectory / "Program Files",
KnownPath.ProgramFilesX86Directory => rootDirectory / "Program Files (x86)",
KnownPath.CommonProgramFilesDirectory => rootDirectory / "Program Files/Common Files",
KnownPath.CommonProgramFilesX86Directory => rootDirectory / "Program Files (x86)/Common Files",

KnownPath.HomeDirectory => newHomeDirectory,
KnownPath.MyDocumentsDirectory => newHomeDirectory.Combine("Documents"),
KnownPath.MyGamesDirectory => newHomeDirectory.Combine("Documents/My Games"),
KnownPath.LocalApplicationDataDirectory => newHomeDirectory.Combine("AppData/Local"),
KnownPath.ApplicationDataDirectory => newHomeDirectory.Combine("AppData/Roaming"),
KnownPath.TempDirectory => newHomeDirectory.Combine("AppData/Local/Temp"),
KnownPath.MyDocumentsDirectory => newHomeDirectory / "Documents",
KnownPath.MyGamesDirectory => newHomeDirectory / "Documents/My Games",
KnownPath.LocalApplicationDataDirectory => newHomeDirectory / "AppData/Local",
KnownPath.ApplicationDataDirectory => newHomeDirectory / "AppData/Roaming",
KnownPath.TempDirectory => newHomeDirectory / "AppData/Local/Temp",

_ => default
};
Expand Down
5 changes: 5 additions & 0 deletions src/NexusMods.Paths/RelativePath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ public RelativePath Join(RelativePath other)
{
return new RelativePath(PathHelpers.JoinParts(Path, other.Path, OS));
}

/// <summary>
/// Appends another path to an existing path.
/// </summary>
public static RelativePath operator /(RelativePath self, RelativePath other) => self.Join(other);

/// <summary>
/// Returns true if the relative path starts with a given string.
Expand Down
4 changes: 2 additions & 2 deletions src/NexusMods.Paths/TemporaryFileManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public TemporaryPath CreateFile(Extension? ext = default, bool deleteOnDispose =
if (_isDisposed)
throw new ObjectDisposedException(nameof(TemporaryFileManager));

var path = _basePath.Combine(Guid.NewGuid().ToString());
var path = _basePath / Guid.NewGuid().ToString();
if (path.Extension != default)
path = path.AppendExtension(ext ?? KnownExtensions.Tmp);

Expand All @@ -58,7 +58,7 @@ public TemporaryPath CreateFolder(string prefix = "", bool deleteOnDispose = tru
if (_isDisposed)
throw new ObjectDisposedException(nameof(TemporaryFileManager));

var path = _basePath.Combine(prefix + Guid.NewGuid());
var path = _basePath / (prefix + Guid.NewGuid());
_fileSystem.CreateDirectory(path);
return new TemporaryPath(_fileSystem, path, deleteOnDispose);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public class NxBuilderExtensionsTests
public async Task NxPackerBuilder_CanAddFolderFromIFileSystem_AndExtractToIFileSystem(InMemoryFileSystem fs, AbsolutePath folderPath)
{
// Arrange
var file1 = folderPath.Combine("file1.txt");
var file2 = folderPath.Combine("subfolder/file2.txt");
var file1 = folderPath / "file1.txt";
var file2 = folderPath / "subfolder/file2.txt";
await fs.WriteAllTextAsync(file1, "Content 1");
await fs.WriteAllTextAsync(file2, "Content 2");

var builder = new NxPackerBuilder();
var outputPath = folderPath.Parent.Combine("output.nx");
var outputPath = folderPath.Parent / "output.nx";

// Act
builder.AddFolder(folderPath)
Expand All @@ -38,11 +38,11 @@ public async Task NxPackerBuilder_CanAddFolderFromIFileSystem_AndExtractToIFileS
entries.Should().Contain(e => e.FilePath == "subfolder/file2.txt");

// Verify we can extract all files
var extractFolder = folderPath.Parent.Combine("extracted");
var extractFolder = folderPath.Parent / "extracted";
unpacker.AddAllFilesWithFileSystemOutput(extractFolder).Extract();

var extractedFile1 = extractFolder.Combine("file1.txt");
var extractedFile2 = extractFolder.Combine("subfolder/file2.txt");
var extractedFile1 = extractFolder / "file1.txt";
var extractedFile2 = extractFolder / "subfolder/file2.txt";

fs.FileExists(extractedFile1).Should().BeTrue();
fs.FileExists(extractedFile2).Should().BeTrue();
Expand All @@ -52,7 +52,7 @@ public async Task NxPackerBuilder_CanAddFolderFromIFileSystem_AndExtractToIFileS

// Verify we can extract a single file.
unpacker = NxUnpackerBuilderExtensions.FromFile(outputPath);
var extractedFile1Copy = extractFolder.Combine("file1-copy.txt");
var extractedFile1Copy = extractFolder / "file1-copy.txt";
var file1Entry = entries.First(x => x.FilePath == "file1.txt");
unpacker.AddFileWithFileSystemOutput(file1Entry, extractedFile1Copy).Extract();
(await fs.ReadAllTextAsync(extractedFile1Copy)).Should().Be("Content 1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public async Task GetFileData_HandlesOutOfBoundsOverflow(IFileSystem fileSystem)

private static async Task<AbsolutePath> CreateTestFile(IFileSystem fileSystem, byte[] testData)
{
var path = fileSystem.GetKnownPath(KnownPath.TempDirectory).Combine(Guid.NewGuid().ToString());
var path = fileSystem.GetKnownPath(KnownPath.TempDirectory) / Guid.NewGuid().ToString();
await fileSystem.WriteAllBytesAsync(path, testData);
return path;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public void Constructor_CreatesFile(IFileSystem fileSystem)

private static AbsolutePath CreateTestPath(IFileSystem fileSystem)
{
return fileSystem.GetKnownPath(KnownPath.TempDirectory).Combine(Guid.NewGuid().ToString());
return fileSystem.GetKnownPath(KnownPath.TempDirectory) / Guid.NewGuid().ToString();
}

private static void CleanupTestFile(IFileSystem fileSystem, AbsolutePath path)
Expand Down
8 changes: 4 additions & 4 deletions tests/NexusMods.Paths.Tests/FileSystem/BaseFileSystemTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public void Test_PathMapping(InMemoryFileSystem fs, AbsolutePath originalPath, A
public void Test_PathMapping_WithDirectory(InMemoryFileSystem fs,
AbsolutePath originalDirectoryPath, AbsolutePath newDirectoryPath, string fileName)
{
var originalFilePath = originalDirectoryPath.Combine(fileName);
var newFilePath = newDirectoryPath.Combine(fileName);
var originalFilePath = originalDirectoryPath / fileName;
var newFilePath = newDirectoryPath / fileName;

var overlayFileSystem = (BaseFileSystem)fs.CreateOverlayFileSystem(
new Dictionary<AbsolutePath, AbsolutePath>
Expand Down Expand Up @@ -116,7 +116,7 @@ public void Test_EnumerateRootDirectories_Windows()
{
var driveLetter = (char)iDriveLetter;
var originalPath = fs.FromUnsanitizedFullPath($"{driveLetter}:/");
var newPath = rootDirectory.Combine(Guid.NewGuid().ToString("D"));
var newPath = rootDirectory / Guid.NewGuid().ToString("D");
return (originalPath, newPath);
}).ToDictionary(x => x.originalPath, x => x.newPath);

Expand Down Expand Up @@ -167,7 +167,7 @@ public void Test_EnumerateRootDirectories_WithCrossPlatformPathMappings()
{
var driveLetter = (char)iDriveLetter;
var originalPath = fs.FromUnsanitizedDirectoryAndFileName("/", driveLetter.ToString());
var newPath = rootDirectory.Combine(Guid.NewGuid().ToString("D"));
var newPath = rootDirectory / Guid.NewGuid().ToString("D");
return (originalPath, newPath);
}).ToDictionary(x => x.originalPath, x => x.newPath);

Expand Down
18 changes: 9 additions & 9 deletions tests/NexusMods.Paths.Tests/FileSystem/FileSystemTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void Test_DeleteDirectoryShouldDeleteEmpty()
{
var fs = new Paths.FileSystem();

var directory = fs.FromUnsanitizedFullPath(AppContext.BaseDirectory).Combine("TestDirectory");
var directory = fs.FromUnsanitizedFullPath(AppContext.BaseDirectory) / "TestDirectory";
fs.CreateDirectory(directory);

fs.DeleteDirectory(directory, recursive: false);
Expand All @@ -49,8 +49,8 @@ public void Test_DeleteDirectoryShouldNotDeleteNonEmpty()
{
var fs = new Paths.FileSystem();

var directory = fs.FromUnsanitizedFullPath(AppContext.BaseDirectory).Combine("TestDirectory");
var child = directory.Combine("Child");
var directory = fs.FromUnsanitizedFullPath(AppContext.BaseDirectory) / ("TestDirectory");
var child = directory / "Child";

fs.CreateDirectory(directory);
fs.CreateDirectory(child);
Expand Down Expand Up @@ -85,7 +85,7 @@ public void Test_EnumerateFileEntries()
public async Task Test_CreateMemoryMappedFile_CanOpen(RelativePath relativePath, byte[] contents)
{
var fs = new Paths.FileSystem();
var file = fs.GetKnownPath(KnownPath.TempDirectory).Combine(relativePath);
var file = fs.GetKnownPath(KnownPath.TempDirectory) / relativePath;
await using (var stream = fs.CreateFile(file))
{
stream.Write(contents);
Expand All @@ -107,7 +107,7 @@ public async Task Test_CreateMemoryMappedFile_CanOpen(RelativePath relativePath,
public async Task Test_CreateMemoryMappedFile_CanCreateAndWrite()
{
var fs = new Paths.FileSystem();
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory).Combine(Path.GetRandomFileName());
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory) / Path.GetRandomFileName();
var contents = new byte[] { 1, 2, 3, 4, 5 };

// Create a new MemoryMappedFile
Expand Down Expand Up @@ -155,7 +155,7 @@ and we propagate this when opening the MemoryMappedFile.
public void Test_ReadBytesRandom()
{
var fs = new Paths.FileSystem();
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory).Combine(Path.GetRandomFileName());
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory) / Path.GetRandomFileName();
var contents = new byte[] { 1, 2, 3, 4, 5 };
using (var stream = fs.CreateFile(tempFile))
{
Expand All @@ -171,7 +171,7 @@ public void Test_ReadBytesRandom()
public void Test_ReadBytesRandomWithOffset()
{
var fs = new Paths.FileSystem();
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory).Combine(Path.GetRandomFileName());
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory) / Path.GetRandomFileName();
var contents = new byte[] { 1, 2, 3, 4, 5 };
using (var stream = fs.CreateFile(tempFile))
{
Expand All @@ -188,7 +188,7 @@ public void Test_ReadBytesRandomWithOffset()
public async Task Test_ReadBytesRandomAsync()
{
var fs = new Paths.FileSystem();
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory).Combine(Path.GetRandomFileName());
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory) / Path.GetRandomFileName();
var contents = new byte[] { 1, 2, 3, 4, 5 };
await using (var stream = fs.CreateFile(tempFile))
{
Expand All @@ -204,7 +204,7 @@ public async Task Test_ReadBytesRandomAsync()
public async Task Test_ReadBytesRandomAsyncWithOffset()
{
var fs = new Paths.FileSystem();
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory).Combine(Path.GetRandomFileName());
var tempFile = fs.GetKnownPath(KnownPath.TempDirectory) / Path.GetRandomFileName();
var contents = new byte[] { 1, 2, 3, 4, 5 };
await using (var stream = fs.CreateFile(tempFile))
{
Expand Down
Loading

0 comments on commit 371b035

Please sign in to comment.