Forge
csharp4405de34
1using System.Runtime.CompilerServices;
2using System.Runtime.InteropServices;
3using System.Text.Json;
4using System.Text.Json.Serialization;
5
6namespace AgentClientProtocol;
7
8[StructLayout(LayoutKind.Auto)]
9[JsonConverter(typeof(RequestIdJsonConverter))]
10public readonly struct RequestId : IEquatable<RequestId>
11{
12 readonly RequestIdType type;
13 readonly long numberValue;
14 readonly string? stringValue;
15
16 public RequestIdType Type => type;
17 public bool IsValid => type is not RequestIdType.Invalid;
18
19 public RequestId(long value)
20 {
21 type = RequestIdType.Number;
22 numberValue = value;
23 }
24
25 public RequestId(string value)
26 {
27 type = RequestIdType.String;
28 stringValue = value;
29 }
30
31 [MethodImpl(MethodImplOptions.AggressiveInlining)]
32 public long AsNumber()
33 {
34 if (type is not RequestIdType.Number) ThrowTypeIsNot("number");
35 return numberValue;
36 }
37
38 [MethodImpl(MethodImplOptions.AggressiveInlining)]
39 public string AsString()
40 {
41 if (type is not RequestIdType.String) ThrowTypeIsNot("string");
42 return stringValue!;
43 }
44
45 static void ThrowTypeIsNot(string expected)
46 {
47 throw new InvalidOperationException($"RequestId type is not a {expected}");
48 }
49
50 public override string ToString()
51 {
52 return type switch
53 {
54 RequestIdType.Invalid => "",
55 RequestIdType.Number => numberValue.ToString(),
56 RequestIdType.String => stringValue!,
57 _ => "",
58 };
59 }
60
61 public bool Equals(RequestId other)
62 {
63 if (type != other.type) return false;
64
65 return type switch
66 {
67 RequestIdType.Number => numberValue == other.numberValue,
68 RequestIdType.String => stringValue == other.stringValue,
69 _ => false,
70 };
71 }
72
73 public override bool Equals(object? obj)
74 {
75 return obj is RequestId id && Equals(id);
76 }
77
78 public override int GetHashCode()
79 {
80 return type switch
81 {
82 RequestIdType.Number => HashCode.Combine(0, numberValue),
83 RequestIdType.String => HashCode.Combine(1, stringValue),
84 _ => 0,
85 };
86 }
87
88 public static bool operator ==(RequestId left, RequestId right)
89 {
90 return left.Equals(right);
91 }
92
93 public static bool operator !=(RequestId left, RequestId right)
94 {
95 return !(left == right);
96 }
97
98 public static implicit operator RequestId(long value)
99 {
100 return new RequestId(value);
101 }
102
103 public static implicit operator RequestId(string value)
104 {
105 return new RequestId(value);
106 }
107}
108
109public enum RequestIdType : byte
110{
111 Invalid,
112 Number,
113 String
114}
115
116public sealed class RequestIdJsonConverter : JsonConverter<RequestId>
117{
118 public override RequestId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
119 {
120 return reader.TokenType switch
121 {
122 JsonTokenType.Number => new RequestId(reader.GetInt64()),
123 JsonTokenType.String => new RequestId(reader.GetString()!),
124 _ => throw new JsonException("Invalid type for RequestId. Expected long or string.")
125 };
126 }
127
128 public override void Write(Utf8JsonWriter writer, RequestId value, JsonSerializerOptions options)
129 {
130 switch (value.Type)
131 {
132 case RequestIdType.Number:
133 writer.WriteNumberValue(value.AsNumber());
134 break;
135 case RequestIdType.String:
136 writer.WriteStringValue(value.AsString());
137 break;
138 }
139 }
140}
View only · write via MCP/CIDE