Skip to content

Instantly share code, notes, and snippets.

@JakeSays
Created April 2, 2020 01:52
Show Gist options
  • Save JakeSays/efbe3c70b296ca17386a6026e9984689 to your computer and use it in GitHub Desktop.
Save JakeSays/efbe3c70b296ca17386a6026e9984689 to your computer and use it in GitHub Desktop.
ObjectId struct
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