| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  | namespace ServiceLib.Common | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     public class SemanticVersion | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |         private readonly int major; | 
					
						
							|  |  |  |         private readonly int minor; | 
					
						
							|  |  |  |         private readonly int patch; | 
					
						
							|  |  |  |         private readonly string version; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         public SemanticVersion(int major, int minor, int patch) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             this.major = major; | 
					
						
							|  |  |  |             this.minor = minor; | 
					
						
							|  |  |  |             this.patch = patch; | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |             version = $"{major}.{minor}.{patch}"; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 11:54:38 +00:00
										 |  |  |         public SemanticVersion(string? version) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             try | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 if (string.IsNullOrEmpty(version)) | 
					
						
							| 
									
										
										
										
											2024-09-18 11:54:38 +00:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                     major = 0; | 
					
						
							|  |  |  |                     minor = 0; | 
					
						
							|  |  |  |                     patch = 0; | 
					
						
							| 
									
										
										
										
											2024-09-18 11:54:38 +00:00
										 |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 this.version = version.RemovePrefix('v'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-14 02:57:40 +00:00
										 |  |  |                 var parts = this.version.Split('.'); | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 if (parts.Length == 2) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                     major = int.Parse(parts.First()); | 
					
						
							|  |  |  |                     minor = int.Parse(parts.Last()); | 
					
						
							|  |  |  |                     patch = 0; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-10-14 02:57:40 +00:00
										 |  |  |                 else if (parts.Length is 3 or 4) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                     major = int.Parse(parts[0]); | 
					
						
							|  |  |  |                     minor = int.Parse(parts[1]); | 
					
						
							|  |  |  |                     patch = int.Parse(parts[2]); | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     throw new ArgumentException("Invalid version string"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             catch | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 major = 0; | 
					
						
							|  |  |  |                 minor = 0; | 
					
						
							|  |  |  |                 patch = 0; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override bool Equals(object? obj) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (obj is SemanticVersion other) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 return major == other.major && minor == other.minor && patch == other.patch; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public override int GetHashCode() | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |             return major.GetHashCode() ^ minor.GetHashCode() ^ patch.GetHashCode(); | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <summary> | 
					
						
							|  |  |  |         /// Use ToVersionString(string? prefix) instead if possible. | 
					
						
							|  |  |  |         /// </summary> | 
					
						
							|  |  |  |         /// <returns>major.minor.patch</returns> | 
					
						
							|  |  |  |         public override string ToString() | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |             return version; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public string ToVersionString(string? prefix = null) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (prefix == null) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 return version; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 return $"{prefix}{version}"; | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 09:25:05 +00:00
										 |  |  |         public static bool operator ==(SemanticVersion v1, SemanticVersion v2) | 
					
						
							|  |  |  |         { return v1.Equals(v2); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public static bool operator !=(SemanticVersion v1, SemanticVersion v2) | 
					
						
							|  |  |  |         { return !v1.Equals(v2); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public static bool operator >=(SemanticVersion v1, SemanticVersion v2) | 
					
						
							|  |  |  |         { return v1.GreaterEquals(v2); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         public static bool operator <=(SemanticVersion v1, SemanticVersion v2) | 
					
						
							|  |  |  |         { return v1.LessEquals(v2); } | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         #region Private | 
					
						
							| 
									
										
										
										
											2023-05-14 09:25:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |         private bool GreaterEquals(SemanticVersion other) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |             if (major < other.major) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |             else if (major > other.major) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 if (minor < other.minor) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 else if (minor > other.minor) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                     if (patch < other.patch) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                     { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                     else if (patch > other.patch) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                     { | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private bool LessEquals(SemanticVersion other) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |             if (major < other.major) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |             else if (major > other.major) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 if (minor < other.minor) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 { | 
					
						
							|  |  |  |                     return true; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                 else if (minor > other.minor) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                 { | 
					
						
							|  |  |  |                     return false; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                     if (patch < other.patch) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                     { | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  |                     else if (patch > other.patch) | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |                     { | 
					
						
							|  |  |  |                         return false; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         return true; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-05-14 09:25:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-09 13:54:56 +00:00
										 |  |  |         #endregion Private | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-03-06 02:47:31 +00:00
										 |  |  | } |