openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.1.0-beta.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/Generated/Internal/ModelSerializationExtensions.cs

399lines · modecode

1// <auto-generated/>
2
3#nullable disable
4
5using System;
6using System.ClientModel.Primitives;
7using System.Collections.Generic;
8using System.Diagnostics;
9using System.Globalization;
10using System.Text.Json;
11using System.Xml;
12
13namespace OpenAI
14{
15 internal static class ModelSerializationExtensions
16 {
17 internal static readonly ModelReaderWriterOptions WireOptions = new ModelReaderWriterOptions("W");
18 internal static readonly BinaryData SentinelValue = BinaryData.FromObjectAsJson("__EMPTY__");
19
20 public static object GetObject(this JsonElement element)
21 {
22 switch (element.ValueKind)
23 {
24 case JsonValueKind.String:
25 return element.GetString();
26 case JsonValueKind.Number:
27 if (element.TryGetInt32(out int intValue))
28 {
29 return intValue;
30 }
31 if (element.TryGetInt64(out long longValue))
32 {
33 return longValue;
34 }
35 return element.GetDouble();
36 case JsonValueKind.True:
37 return true;
38 case JsonValueKind.False:
39 return false;
40 case JsonValueKind.Undefined:
41 case JsonValueKind.Null:
42 return null;
43 case JsonValueKind.Object:
44 var dictionary = new Dictionary<string, object>();
45 foreach (var jsonProperty in element.EnumerateObject())
46 {
47 dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject());
48 }
49 return dictionary;
50 case JsonValueKind.Array:
51 var list = new List<object>();
52 foreach (var item in element.EnumerateArray())
53 {
54 list.Add(item.GetObject());
55 }
56 return list.ToArray();
57 default:
58 throw new NotSupportedException($"Not supported value kind {element.ValueKind}");
59 }
60 }
61
62 public static byte[] GetBytesFromBase64(this JsonElement element, string format)
63 {
64 if (element.ValueKind == JsonValueKind.Null)
65 {
66 return null;
67 }
68
69 return format switch
70 {
71 "U" => TypeFormatters.FromBase64UrlString(element.GetRequiredString()),
72 "D" => element.GetBytesFromBase64(),
73 _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format))
74 };
75 }
76
77 public static DateTimeOffset GetDateTimeOffset(this JsonElement element, string format) => format switch
78 {
79 "U" when element.ValueKind == JsonValueKind.Number => DateTimeOffset.FromUnixTimeSeconds(element.GetInt64()),
80 _ => TypeFormatters.ParseDateTimeOffset(element.GetString(), format)
81 };
82
83 public static TimeSpan GetTimeSpan(this JsonElement element, string format) => TypeFormatters.ParseTimeSpan(element.GetString(), format);
84
85 public static char GetChar(this JsonElement element)
86 {
87 if (element.ValueKind == JsonValueKind.String)
88 {
89 var text = element.GetString();
90 if (text == null || text.Length != 1)
91 {
92 throw new NotSupportedException($"Cannot convert \"{text}\" to a char");
93 }
94 return text[0];
95 }
96 else
97 {
98 throw new NotSupportedException($"Cannot convert {element.ValueKind} to a char");
99 }
100 }
101
102 [Conditional("DEBUG")]
103 public static void ThrowNonNullablePropertyIsNull(this JsonProperty property)
104 {
105 throw new JsonException($"A property '{property.Name}' defined as non-nullable but received as null from the service. This exception only happens in DEBUG builds of the library and would be ignored in the release build");
106 }
107
108 public static string GetRequiredString(this JsonElement element)
109 {
110 var value = element.GetString();
111 if (value == null)
112 {
113 throw new InvalidOperationException($"The requested operation requires an element of type 'String', but the target element has type '{element.ValueKind}'.");
114 }
115 return value;
116 }
117
118 public static void WriteStringValue(this Utf8JsonWriter writer, DateTimeOffset value, string format)
119 {
120 writer.WriteStringValue(TypeFormatters.ToString(value, format));
121 }
122
123 public static void WriteStringValue(this Utf8JsonWriter writer, DateTime value, string format)
124 {
125 writer.WriteStringValue(TypeFormatters.ToString(value, format));
126 }
127
128 public static void WriteStringValue(this Utf8JsonWriter writer, TimeSpan value, string format)
129 {
130 writer.WriteStringValue(TypeFormatters.ToString(value, format));
131 }
132
133 public static void WriteStringValue(this Utf8JsonWriter writer, char value)
134 {
135 writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
136 }
137
138 public static void WriteBase64StringValue(this Utf8JsonWriter writer, byte[] value, string format)
139 {
140 if (value == null)
141 {
142 writer.WriteNullValue();
143 return;
144 }
145 switch (format)
146 {
147 case "U":
148 writer.WriteStringValue(TypeFormatters.ToBase64UrlString(value));
149 break;
150 case "D":
151 writer.WriteBase64StringValue(value);
152 break;
153 default:
154 throw new ArgumentException($"Format is not supported: '{format}'", nameof(format));
155 }
156 }
157
158 public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset value, string format)
159 {
160 if (format != "U")
161 {
162 throw new ArgumentOutOfRangeException(nameof(format), "Only 'U' format is supported when writing a DateTimeOffset as a Number.");
163 }
164 writer.WriteNumberValue(value.ToUnixTimeSeconds());
165 }
166
167 public static void WriteObjectValue<T>(this Utf8JsonWriter writer, T value, ModelReaderWriterOptions options = null)
168 {
169 switch (value)
170 {
171 case null:
172 writer.WriteNullValue();
173 break;
174 case IJsonModel<T> jsonModel:
175 jsonModel.Write(writer, options ?? WireOptions);
176 break;
177 case byte[] bytes:
178 writer.WriteBase64StringValue(bytes);
179 break;
180 case BinaryData bytes0:
181 writer.WriteBase64StringValue(bytes0);
182 break;
183 case JsonElement json:
184 json.WriteTo(writer);
185 break;
186 case int i:
187 writer.WriteNumberValue(i);
188 break;
189 case decimal d:
190 writer.WriteNumberValue(d);
191 break;
192 case double d0:
193 if (double.IsNaN(d0))
194 {
195 writer.WriteStringValue("NaN");
196 }
197 else
198 {
199 writer.WriteNumberValue(d0);
200 }
201 break;
202 case float f:
203 writer.WriteNumberValue(f);
204 break;
205 case long l:
206 writer.WriteNumberValue(l);
207 break;
208 case string s:
209 writer.WriteStringValue(s);
210 break;
211 case bool b:
212 writer.WriteBooleanValue(b);
213 break;
214 case Guid g:
215 writer.WriteStringValue(g);
216 break;
217 case DateTimeOffset dateTimeOffset:
218 writer.WriteStringValue(dateTimeOffset, "O");
219 break;
220 case DateTime dateTime:
221 writer.WriteStringValue(dateTime, "O");
222 break;
223 case IEnumerable<KeyValuePair<string, object>> enumerable:
224 writer.WriteStartObject();
225 foreach (var pair in enumerable)
226 {
227 writer.WritePropertyName(pair.Key);
228 writer.WriteObjectValue<object>(pair.Value, options);
229 }
230 writer.WriteEndObject();
231 break;
232 case IEnumerable<object> objectEnumerable:
233 writer.WriteStartArray();
234 foreach (var item in objectEnumerable)
235 {
236 writer.WriteObjectValue<object>(item, options);
237 }
238 writer.WriteEndArray();
239 break;
240 case TimeSpan timeSpan:
241 writer.WriteStringValue(timeSpan, "P");
242 break;
243 default:
244 throw new NotSupportedException($"Not supported type {value.GetType()}");
245 }
246 }
247
248 public static void WriteObjectValue(this Utf8JsonWriter writer, object value, ModelReaderWriterOptions options = null)
249 {
250 writer.WriteObjectValue<object>(value, options);
251 }
252
253 internal static bool IsSentinelValue(BinaryData value)
254 {
255 ReadOnlySpan<byte> sentinelSpan = SentinelValue.ToMemory().Span;
256 ReadOnlySpan<byte> valueSpan = value.ToMemory().Span;
257 return sentinelSpan.SequenceEqual(valueSpan);
258 }
259
260 internal static class TypeFormatters
261 {
262 private const string RoundtripZFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ";
263 public const string DefaultNumberFormat = "G";
264
265 public static string ToString(bool value) => value ? "true" : "false";
266
267 public static string ToString(DateTime value, string format) => value.Kind switch
268 {
269 DateTimeKind.Utc => ToString((DateTimeOffset)value, format),
270 _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Generated clients require it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.")
271 };
272
273 public static string ToString(DateTimeOffset value, string format) => format switch
274 {
275 "D" => value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture),
276 "U" => value.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture),
277 "O" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture),
278 "o" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture),
279 "R" => value.ToString("r", CultureInfo.InvariantCulture),
280 _ => value.ToString(format, CultureInfo.InvariantCulture)
281 };
282
283 public static string ToString(TimeSpan value, string format) => format switch
284 {
285 "P" => XmlConvert.ToString(value),
286 _ => value.ToString(format, CultureInfo.InvariantCulture)
287 };
288
289 public static string ToString(byte[] value, string format) => format switch
290 {
291 "U" => ToBase64UrlString(value),
292 "D" => Convert.ToBase64String(value),
293 _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format))
294 };
295
296 public static string ToBase64UrlString(byte[] value)
297 {
298 int numWholeOrPartialInputBlocks = checked(value.Length + 2) / 3;
299 int size = checked(numWholeOrPartialInputBlocks * 4);
300 char[] output = new char[size];
301
302 int numBase64Chars = Convert.ToBase64CharArray(value, 0, value.Length, output, 0);
303
304 int i = 0;
305 for (; i < numBase64Chars; i++)
306 {
307 char ch = output[i];
308 if (ch == '+')
309 {
310 output[i] = '-';
311 }
312 else
313 {
314 if (ch == '/')
315 {
316 output[i] = '_';
317 }
318 else
319 {
320 if (ch == '=')
321 {
322 break;
323 }
324 }
325 }
326 }
327
328 return new string(output, 0, i);
329 }
330
331 public static byte[] FromBase64UrlString(string value)
332 {
333 int paddingCharsToAdd = (value.Length % 4) switch
334 {
335 0 => 0,
336 2 => 2,
337 3 => 1,
338 _ => throw new InvalidOperationException("Malformed input")
339 };
340 char[] output = new char[(value.Length + paddingCharsToAdd)];
341 int i = 0;
342 for (; i < value.Length; i++)
343 {
344 char ch = value[i];
345 if (ch == '-')
346 {
347 output[i] = '+';
348 }
349 else
350 {
351 if (ch == '_')
352 {
353 output[i] = '/';
354 }
355 else
356 {
357 output[i] = ch;
358 }
359 }
360 }
361
362 for (; i < output.Length; i++)
363 {
364 output[i] = '=';
365 }
366
367 return Convert.FromBase64CharArray(output, 0, output.Length);
368 }
369
370 public static DateTimeOffset ParseDateTimeOffset(string value, string format) => format switch
371 {
372 "U" => DateTimeOffset.FromUnixTimeSeconds(long.Parse(value, CultureInfo.InvariantCulture)),
373 _ => DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal)
374 };
375
376 public static TimeSpan ParseTimeSpan(string value, string format) => format switch
377 {
378 "P" => XmlConvert.ToTimeSpan(value),
379 _ => TimeSpan.ParseExact(value, format, CultureInfo.InvariantCulture)
380 };
381
382 public static string ConvertToString(object value, string format = null) => value switch
383 {
384 null => "null",
385 string s => s,
386 bool b => ToString(b),
387 int or float or double or long or decimal => ((IFormattable)value).ToString(DefaultNumberFormat, CultureInfo.InvariantCulture),
388 byte[] b0 when format != null => ToString(b0, format),
389 IEnumerable<string> s0 => string.Join(",", s0),
390 DateTimeOffset dateTime when format != null => ToString(dateTime, format),
391 TimeSpan timeSpan when format != null => ToString(timeSpan, format),
392 TimeSpan timeSpan0 => XmlConvert.ToString(timeSpan0),
393 Guid guid => guid.ToString(),
394 BinaryData binaryData => ConvertToString(binaryData.ToArray(), format),
395 _ => value.ToString()
396 };
397 }
398 }
399}
400