openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.0.0-beta.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/Generated/Internal/ModelSerializationExtensions.cs

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