Skip to content

Commit 9b806fa

Browse files
committed
Added SystemPath
1 parent aa5cb7b commit 9b806fa

8 files changed

Lines changed: 266 additions & 37 deletions

File tree

Abstract.FileSystem.sln

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,23 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abstract.FileSystem", "Abst
77
EndProject
88
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{AC210C33-986C-44A9-8900-F612D2BC8A6C}"
99
EndProject
10-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abstract.FileSystem.Test", "Tests\Abstract.FileSystem.Test\Abstract.FileSystem.Test.csproj", "{80DED7E1-90C4-43D1-8043-1B7693FCB42B}"
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Abstract.FileSystem.Test", "Tests\Abstract.FileSystem.Test\Abstract.FileSystem.Test.csproj", "{80DED7E1-90C4-43D1-8043-1B7693FCB42B}"
1111
EndProject
1212
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{A77E2487-9254-4819-905B-1721F147D704}"
1313
EndProject
14+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C9EAD40A-9A9A-4309-816A-D2CCEA0F81A6}"
15+
ProjectSection(SolutionItems) = preProject
16+
appveyor.yml = appveyor.yml
17+
LICENSE = LICENSE
18+
testenvironments.json = testenvironments.json
19+
EndProjectSection
20+
EndProject
1421
Global
1522
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1623
Debug|Any CPU = Debug|Any CPU
1724
Release|Any CPU = Release|Any CPU
1825
EndGlobalSection
1926
GlobalSection(ProjectConfigurationPlatforms) = postSolution
20-
{A77E2487-9254-4819-905B-1721F147D704}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21-
{A77E2487-9254-4819-905B-1721F147D704}.Release|Any CPU.ActiveCfg = Release|Any CPU
2227
{3305D6E6-D721-48AA-AA78-1F05361F8257}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2328
{3305D6E6-D721-48AA-AA78-1F05361F8257}.Debug|Any CPU.Build.0 = Debug|Any CPU
2429
{3305D6E6-D721-48AA-AA78-1F05361F8257}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -27,12 +32,15 @@ Global
2732
{80DED7E1-90C4-43D1-8043-1B7693FCB42B}.Debug|Any CPU.Build.0 = Debug|Any CPU
2833
{80DED7E1-90C4-43D1-8043-1B7693FCB42B}.Release|Any CPU.ActiveCfg = Release|Any CPU
2934
{80DED7E1-90C4-43D1-8043-1B7693FCB42B}.Release|Any CPU.Build.0 = Release|Any CPU
35+
{A77E2487-9254-4819-905B-1721F147D704}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36+
{A77E2487-9254-4819-905B-1721F147D704}.Release|Any CPU.ActiveCfg = Release|Any CPU
3037
EndGlobalSection
3138
GlobalSection(SolutionProperties) = preSolution
3239
HideSolutionNode = FALSE
3340
EndGlobalSection
3441
GlobalSection(NestedProjects) = preSolution
3542
{80DED7E1-90C4-43D1-8043-1B7693FCB42B} = {AC210C33-986C-44A9-8900-F612D2BC8A6C}
43+
{A77E2487-9254-4819-905B-1721F147D704} = {C9EAD40A-9A9A-4309-816A-D2CCEA0F81A6}
3644
EndGlobalSection
3745
GlobalSection(ExtensibilityGlobals) = postSolution
3846
SolutionGuid = {B62B7086-D21E-4583-A926-5664C42E1BFA}

Abstract.FileSystem/OsType.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11

22
namespace Abstract.FileSystem
33
{
4+
/// <summary>
5+
/// Identifier for the OS.
6+
/// </summary>
47
public enum OsType
58
{
9+
/// <summary>
10+
/// Unix based os
11+
/// </summary>
612
Unix,
13+
14+
/// <summary>
15+
/// Windows
16+
/// </summary>
717
Windows
818
}
919
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Abstract.FileSystem.Test
2+
{
3+
/// <summary>
4+
/// Extensions for paths
5+
/// </summary>
6+
public static class StringPathExtensions
7+
{
8+
/// <summary>
9+
/// Format a path string based on the path settins of the OS
10+
/// </summary>
11+
/// <param name="path"></param>
12+
/// <returns></returns>
13+
public static string FormatPath(this string path)
14+
{
15+
return SystemPath.FormatPath(path);
16+
}
17+
}
18+
}

Abstract.FileSystem/SystemPath.cs

Lines changed: 101 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.ComponentModel;
4-
using System.Globalization;
5-
using System.IO;
6-
using System.Linq;
3+
using System.Diagnostics;
74
using System.Runtime.InteropServices;
8-
using System.Text;
95

106
namespace Abstract.FileSystem
117
{
8+
[Serializable]
9+
[DebuggerDisplay("{" + nameof(_path) + "}")]
1210
public class SystemPath
1311
{
1412
internal const char WinSeparator = '\\';
1513
internal const char UncSeparator = '\\';
1614
internal const char UnixSeparator = '/';
1715

18-
public static SystemPath Create(string path)
19-
{
20-
return new SystemPath(path);
21-
}
22-
2316
static SystemPath()
2417
{
2518
OsType = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? OsType.Windows : OsType.Unix;
2619
}
2720

2821
private readonly string _path;
2922

30-
private SystemPath(string path)
23+
/// <summary>
24+
/// Create a new SystemPath from a string path
25+
/// </summary>
26+
/// <param name="path"></param>
27+
public SystemPath(string path)
3128
{
32-
_path = NormalizePath(path);
29+
_path = FormatPath(path);
3330
}
3431

32+
/// <summary>
33+
/// Cast a string path to a SystemPath
34+
/// </summary>
35+
/// <param name="path"></param>
3536
public static implicit operator SystemPath(string path)
3637
{
3738
if (path is null)
@@ -42,61 +43,120 @@ public static implicit operator SystemPath(string path)
4243
return new SystemPath(path);
4344
}
4445

46+
/// <summary>
47+
/// Cast a SystemPath to a string path
48+
/// </summary>
49+
/// <param name="path"></param>
4550
public static implicit operator string(SystemPath path)
4651
{
4752
return path?.ToString();
4853
}
4954

55+
/// <summary>
56+
/// Gets the type of OS. Defines the how the PathSeparator is used
57+
/// </summary>
5058
public static OsType OsType { get; }
5159

60+
/// <summary>
61+
/// Combine a SystemPath and a string with the / separator
62+
/// </summary>
63+
/// <param name="left"></param>
64+
/// <param name="right"></param>
65+
/// <returns></returns>
5266
public static SystemPath operator /(SystemPath left, string right)
5367
{
5468
return new SystemPath(Combine(left, right));
5569
}
5670

71+
/// <summary>
72+
/// Add a segment to the SystemPath without adding a separatro
73+
/// </summary>
74+
/// <param name="left"></param>
75+
/// <param name="right"></param>
76+
/// <returns></returns>
5777
public static SystemPath operator +(SystemPath left, string right)
5878
{
5979
return new SystemPath(left.ToString() + right);
6080
}
6181

82+
/// <summary>
83+
/// Equalitycomparer of two SystemPaths
84+
/// </summary>
85+
/// <param name="a"></param>
86+
/// <param name="b"></param>
87+
/// <returns></returns>
6288
public static bool operator ==(SystemPath a, SystemPath b)
6389
{
6490
return EqualityComparer<SystemPath>.Default.Equals(a, b);
6591
}
6692

93+
/// <summary>
94+
/// Unequalitycomparer of two SystemPaths
95+
/// </summary>
96+
/// <param name="a"></param>
97+
/// <param name="b"></param>
98+
/// <returns></returns>
6799
public static bool operator !=(SystemPath a, SystemPath b)
68100
{
69101
return !EqualityComparer<SystemPath>.Default.Equals(a, b);
70102
}
71103

104+
/// <summary>
105+
/// Compare a SystemPath to this SystemPath
106+
/// </summary>
107+
/// <param name="other"></param>
108+
/// <returns></returns>
72109
protected bool Equals(SystemPath other)
73110
{
74111
var stringComparison = OsType == OsType.Unix ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
75112
return string.Equals(_path, other._path, stringComparison);
76113
}
77114

115+
/// <summary>
116+
/// Compare a object to this SystemPath
117+
/// </summary>
118+
/// <param name="obj"></param>
119+
/// <returns></returns>
78120
public override bool Equals(object obj)
79121
{
80122
if (ReferenceEquals(objA: null, obj))
123+
{
81124
return false;
125+
}
126+
82127
if (ReferenceEquals(this, obj))
128+
{
83129
return true;
130+
}
131+
84132
if (obj.GetType() != GetType())
133+
{
134+
if(obj is string str)
135+
{
136+
return Equals(this, (SystemPath)str);
137+
}
138+
85139
return false;
140+
}
141+
86142
return Equals((SystemPath)obj);
87143
}
88144

145+
/// <summary>
146+
///
147+
/// </summary>
148+
/// <returns></returns>
89149
public override int GetHashCode()
90150
{
91151
return _path?.GetHashCode() ?? 0;
92152
}
93153

94-
public override string ToString()
95-
{
96-
return ((IFormattable)this).ToString(format: null, formatProvider: null);
97-
}
98-
99-
public static string NormalizePath(string path)
154+
/// <summary>
155+
/// Format a path string based on the path settins of the OS
156+
/// </summary>
157+
/// <param name="path"></param>
158+
/// <returns></returns>
159+
public static string FormatPath(string path)
100160
{
101161
if (OsType == OsType.Unix)
102162
{
@@ -106,25 +166,33 @@ public static string NormalizePath(string path)
106166
return path.Replace(UnixSeparator, WinSeparator);
107167
}
108168

109-
public static string Combine(SystemPath path, params string[] elements)
169+
/// <summary>
170+
/// Combine a SystemPath and multiple further string segments
171+
/// </summary>
172+
/// <param name="path"></param>
173+
/// <param name="segments"></param>
174+
/// <returns></returns>
175+
public static string Combine(SystemPath path, params string[] segments)
110176
{
111-
throw new NotImplementedException();
112-
}
177+
var separator = OsType == OsType.Unix ? UnixSeparator : WinSeparator;
113178

114-
internal static bool IsWinRoot(string root)
115-
=> root?.Length == 2 &&
116-
char.IsLetter(root[index: 0]) &&
117-
root[index: 1] == ':';
179+
var left = path._path;
180+
foreach(var right in segments)
181+
{
182+
left = $"{left}{separator}{right}";
183+
}
118184

119-
internal static bool IsUnixRoot(string root)
120-
=> root?.Length == 1 &&
121-
root[index: 0] == UnixSeparator;
185+
return left;
186+
}
122187

123-
internal static bool IsUncRoot(string root)
124-
=> root?.Length >= 3 &&
125-
root[index: 0] == UncSeparator &&
126-
root[index: 1] == UncSeparator &&
127-
root.Skip(count: 2).All(char.IsLetterOrDigit);
188+
/// <summary>
189+
/// Get the string equivalent of this object
190+
/// </summary>
191+
/// <returns></returns>
192+
public override string ToString()
193+
{
194+
return _path;
195+
}
128196
}
129197

130198
}

Tests/Abstract.FileSystem.Test/Abstract.FileSystem.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12+
<PackageReference Include="FluentAssertions" Version="6.12.0" />
1213
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
1314
<PackageReference Include="Moq" Version="4.20.69" />
1415
<PackageReference Include="NUnit" Version="3.13.3" />

0 commit comments

Comments
 (0)