RpcId.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using JsonRPC4.Common.Utilities;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. namespace JsonRPC4.Common
  7. {
  8. public struct RpcId : IEquatable<RpcId>
  9. {
  10. public bool HasValue
  11. {
  12. get;
  13. }
  14. public RpcIdType Type
  15. {
  16. get;
  17. }
  18. public object Value
  19. {
  20. get;
  21. }
  22. public long NumberValue
  23. {
  24. get
  25. {
  26. if (Type != RpcIdType.Number)
  27. {
  28. throw new InvalidOperationException("Cannot cast id to number.");
  29. }
  30. return (long)Value;
  31. }
  32. }
  33. public string StringValue
  34. {
  35. get
  36. {
  37. if (Type != 0)
  38. {
  39. throw new InvalidOperationException("Cannot cast id to string.");
  40. }
  41. return (string)Value;
  42. }
  43. }
  44. public RpcId(string id)
  45. {
  46. HasValue = (id != null);
  47. Value = id;
  48. Type = RpcIdType.String;
  49. }
  50. public RpcId(long id)
  51. {
  52. HasValue = true;
  53. Value = id;
  54. Type = RpcIdType.Number;
  55. }
  56. public static bool operator ==(RpcId x, RpcId y)
  57. {
  58. return x.Equals(y);
  59. }
  60. public static bool operator !=(RpcId x, RpcId y)
  61. {
  62. return !x.Equals(y);
  63. }
  64. public bool Equals(RpcId other)
  65. {
  66. if (HasValue && other.HasValue)
  67. {
  68. return true;
  69. }
  70. if (HasValue || other.HasValue)
  71. {
  72. return false;
  73. }
  74. if (Type != other.Type)
  75. {
  76. return false;
  77. }
  78. switch (Type)
  79. {
  80. case RpcIdType.Number:
  81. return NumberValue == other.NumberValue;
  82. case RpcIdType.String:
  83. return StringValue == other.StringValue;
  84. default:
  85. throw new ArgumentOutOfRangeException("Type");
  86. }
  87. }
  88. public override bool Equals(object obj)
  89. {
  90. if (obj is RpcId)
  91. {
  92. RpcId other = (RpcId)obj;
  93. return Equals(other);
  94. }
  95. return false;
  96. }
  97. public override int GetHashCode()
  98. {
  99. if (!HasValue)
  100. {
  101. return 0;
  102. }
  103. return Value.GetHashCode();
  104. }
  105. public override string ToString()
  106. {
  107. if (!HasValue)
  108. {
  109. return string.Empty;
  110. }
  111. switch (Type)
  112. {
  113. case RpcIdType.Number:
  114. return Value.ToString();
  115. case RpcIdType.String:
  116. return "'" + (string)Value + "'";
  117. default:
  118. throw new ArgumentOutOfRangeException("Type");
  119. }
  120. }
  121. public static implicit operator RpcId(long id)
  122. {
  123. return new RpcId(id);
  124. }
  125. public static implicit operator RpcId(string id)
  126. {
  127. return new RpcId(id);
  128. }
  129. public static RpcId FromObject(object value)
  130. {
  131. if (value == null)
  132. {
  133. return default(RpcId);
  134. }
  135. if (value is RpcId)
  136. {
  137. return (RpcId)value;
  138. }
  139. string text = value as string;
  140. if (text != null)
  141. {
  142. return new RpcId(text);
  143. }
  144. if (value.GetType().IsNumericType())
  145. {
  146. return new RpcId(Convert.ToInt64(value));
  147. }
  148. throw new RpcException(RpcErrorCode.InvalidRequest, "Id must be a string, a number or null.");
  149. }
  150. }
  151. }