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 · modeblame

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