Created
April 2, 2020 01:52
-
-
Save JakeSays/efbe3c70b296ca17386a6026e9984689 to your computer and use it in GitHub Desktop.
ObjectId struct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
namespace Std.BasicTypes | |
{ | |
[Serializable] | |
[StructLayout(LayoutKind.Sequential, Pack = 1)] | |
public struct ObjectId : IEquatable<ObjectId> | |
{ | |
public static readonly ObjectId Null; | |
public long Number { get; } | |
public int Version { get; } | |
public ObjectId(ObjectId source) | |
: this() | |
{ | |
Number = source.Number; | |
Version = source.Version; | |
} | |
public ObjectId(long number) | |
: this() | |
{ | |
Number = number; | |
Version = 0; | |
} | |
public ObjectId(long number, int version) | |
: this() | |
{ | |
Number = number; | |
Version = version; | |
} | |
public bool IsValid | |
{ | |
get => Number > 0 && Version >= 0; | |
} | |
public bool Equals(ObjectId other) | |
{ | |
return Number == other.Number && Version == other.Version; | |
} | |
public override int GetHashCode() | |
{ | |
unchecked | |
{ | |
return (Number.GetHashCode() * 397) ^ Version; | |
} | |
} | |
public static bool operator==(ObjectId left, ObjectId right) | |
{ | |
return left.Equals(right); | |
} | |
public static bool operator!=(ObjectId left, ObjectId right) | |
{ | |
return !left.Equals(right); | |
} | |
public override bool Equals(object obj) | |
{ | |
if (ReferenceEquals(null, obj)) | |
{ | |
return false; | |
} | |
return obj is ObjectId id && Equals(id); | |
} | |
public ObjectId WithVersion(int newVersion) | |
{ | |
return new ObjectId(Number, newVersion); | |
} | |
public override string ToString() | |
{ | |
return Number + ":" + Version; | |
} | |
public static ObjectId Parse(string text) | |
{ | |
var result = InternalParse(text, out var id); | |
switch (result) | |
{ | |
case ParseResult.Success: | |
return id; | |
case ParseResult.ArgNull: | |
throw new ArgumentNullException(nameof(text)); | |
case ParseResult.InvalidLength: | |
throw new FormatException("Invalid length"); | |
case ParseResult.InvalidFormat: | |
throw new FormatException("Invalid format"); | |
} | |
throw new InvalidOperationException(); | |
} | |
public static bool TryParse(string text, out ObjectId id) | |
{ | |
var result = InternalParse(text, out id); | |
return result == ParseResult.Success; | |
} | |
private enum ParseResult | |
{ | |
Success, | |
ArgNull, | |
InvalidLength, | |
InvalidFormat | |
} | |
private static ParseResult InternalParse(string text, out ObjectId result) | |
{ | |
result = Null; | |
if (text == null) | |
{ | |
return ParseResult.ArgNull; | |
} | |
if (text.Length == 0) | |
{ | |
return ParseResult.InvalidLength; | |
} | |
var parts = text.Split(':'); | |
if (parts.Length > 2) | |
{ | |
return ParseResult.InvalidFormat; | |
} | |
long id = 0; | |
var version = 0; | |
if (!long.TryParse(parts[0], out id)) | |
{ | |
return ParseResult.InvalidFormat; | |
} | |
if (parts.Length == 2 && | |
!int.TryParse(parts[1], out version)) | |
{ | |
return ParseResult.InvalidFormat; | |
} | |
result = new ObjectId(id, version); | |
return ParseResult.Success; | |
} | |
} | |
public static class ObjectIdExtensions | |
{ | |
public static bool IsValid(this ObjectId? id) | |
{ | |
var result = id.HasValue && id.Value.IsValid; | |
return result; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment