-
Notifications
You must be signed in to change notification settings - Fork 5
/
InMemoryLocation.cs
139 lines (115 loc) · 3.62 KB
/
InMemoryLocation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using System;
using System.IO;
using Testably.Abstractions.Testing.Helpers;
namespace Testably.Abstractions.Testing.Storage;
internal sealed class InMemoryLocation : IStorageLocation
{
internal static readonly StringComparison StringComparisonMode =
Execute.IsLinux
? StringComparison.Ordinal
: StringComparison.OrdinalIgnoreCase;
private readonly string _key;
private InMemoryLocation(IStorageDrive? drive,
string fullPath,
string friendlyName)
{
FullPath = fullPath
.NormalizePath()
.TrimOnWindows();
_key = NormalizeKey(FullPath);
Execute.OnNetFramework(()
=> friendlyName = friendlyName.TrimOnWindows());
IsRooted = drive?.Name == fullPath || drive?.Name.Substring(1) == fullPath;
FriendlyName = friendlyName;
Drive = drive;
}
#region IStorageLocation Members
/// <inheritdoc cref="IStorageLocation.Drive" />
public IStorageDrive? Drive { get; }
/// <inheritdoc cref="IStorageLocation.FriendlyName" />
public string FriendlyName { get; }
/// <inheritdoc cref="IStorageLocation.FullPath" />
public string FullPath { get; }
/// <inheritdoc cref="IStorageLocation.IsRooted" />
public bool IsRooted { get; }
/// <inheritdoc cref="IEquatable{IStorageLocation}.Equals(IStorageLocation)" />
public bool Equals(IStorageLocation? other)
{
if (ReferenceEquals(null, other))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
if (other is InMemoryLocation location)
{
return _key.Equals(location._key, StringComparisonMode);
}
return NormalizeKey(FullPath)
.Equals(NormalizeKey(other.FullPath), StringComparisonMode);
}
/// <inheritdoc cref="object.Equals(object?)" />
public override bool Equals(object? obj)
=> ReferenceEquals(this, obj) ||
(obj is IStorageLocation other && Equals(other));
#if NETSTANDARD2_0
/// <inheritdoc cref="object.GetHashCode()" />
public override int GetHashCode()
=> _key.ToLowerInvariant().GetHashCode();
#else
/// <inheritdoc cref="object.GetHashCode()" />
public override int GetHashCode()
=> _key.GetHashCode(StringComparisonMode);
#endif
/// <inheritdoc cref="IStorageLocation.GetParent()" />
public IStorageLocation? GetParent()
{
string? parentPath = Path.GetDirectoryName(FullPath);
if (Path.GetPathRoot(FullPath) == FullPath || parentPath == null)
{
return null;
}
return New(Drive,
parentPath,
GetFriendlyNameParent(parentPath));
}
private static string GetFriendlyNameParent(string parentPath)
=> Execute.OnNetFramework(
() => Path.GetFileName(parentPath),
() => parentPath);
#endregion
/// <summary>
/// Creates a new <see cref="IStorageLocation" /> on the specified <paramref name="drive" /> with the given
/// <paramref name="path" />
/// </summary>
/// <param name="drive">The drive on which the path is located.</param>
/// <param name="path">The full path on the <paramref name="drive" />.</param>
/// <param name="friendlyName">The friendly name is the provided name or the full path.</param>
internal static IStorageLocation New(IStorageDrive? drive,
string path,
string? friendlyName = null)
{
if (path == string.Empty)
{
throw ExceptionFactory.PathIsEmpty(nameof(path));
}
friendlyName ??= path;
return new InMemoryLocation(drive, path, friendlyName);
}
/// <inheritdoc cref="object.ToString()" />
public override string ToString()
=> FullPath;
private static string NormalizeKey(string fullPath)
{
#if FEATURE_PATH_ADVANCED
return Path.TrimEndingDirectorySeparator(fullPath);
#else
return FileFeatureExtensionMethods.TrimEndingDirectorySeparator(
fullPath,
Path.DirectorySeparatorChar,
Path.AltDirectorySeparatorChar);
#endif
}
}