11using System ;
22using System . Collections . Generic ;
3- using System . ComponentModel ;
4- using System . Globalization ;
5- using System . IO ;
6- using System . Linq ;
3+ using System . Diagnostics ;
74using System . Runtime . InteropServices ;
8- using System . Text ;
95
106namespace 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}
0 commit comments