// <auto-generated />
// This file was automatically generated by quicktype from JSON schemas.
// DO NOT EDIT THIS FILE DIRECTLY! Instead, edit the TypeScript schemas and regenerate.

// <auto-generated />
//
// To parse this JSON data, add NuGet 'System.Text.Json' then do one of these:
//
//    using WindowsHelper.Models;
//
//    var rpcRequest = RpcRequest.FromJson(jsonString);
//    var rpcResponse = RpcResponse.FromJson(jsonString);
//    var getAccessibilityTreeDetailsParams = GetAccessibilityTreeDetailsParams.FromJson(jsonString);
//    var getAccessibilityTreeDetailsResult = GetAccessibilityTreeDetailsResult.FromJson(jsonString);
//    var getAccessibilityContextParams = GetAccessibilityContextParams.FromJson(jsonString);
//    var getAccessibilityContextResult = GetAccessibilityContextResult.FromJson(jsonString);
//    var pasteTextParams = PasteTextParams.FromJson(jsonString);
//    var pasteTextResult = PasteTextResult.FromJson(jsonString);
//    var muteSystemAudioParams = MuteSystemAudioParams.FromJson(jsonString);
//    var muteSystemAudioResult = MuteSystemAudioResult.FromJson(jsonString);
//    var restoreSystemAudioParams = RestoreSystemAudioParams.FromJson(jsonString);
//    var restoreSystemAudioResult = RestoreSystemAudioResult.FromJson(jsonString);
//    var setShortcutsParams = SetShortcutsParams.FromJson(jsonString);
//    var setShortcutsResult = SetShortcutsResult.FromJson(jsonString);
//    var keyDownEvent = KeyDownEvent.FromJson(jsonString);
//    var keyUpEvent = KeyUpEvent.FromJson(jsonString);
//    var flagsChangedEvent = FlagsChangedEvent.FromJson(jsonString);
//    var helperEvent = HelperEvent.FromJson(jsonString);
#nullable enable
#pragma warning disable CS8618
#pragma warning disable CS8601
#pragma warning disable CS8603

namespace WindowsHelper.Models
{
    using System;
    using System.Collections.Generic;

    using System.Text.Json;
    using System.Text.Json.Serialization;
    using System.Globalization;

    public partial class RpcRequest
    {
        [JsonPropertyName("id")]
        public Guid Id { get; set; }

        [JsonPropertyName("method")]
        public Method Method { get; set; }

        [JsonPropertyName("params")]
        public object Params { get; set; }
    }

    public partial class RpcResponse
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("error")]
        public Error Error { get; set; }

        [JsonPropertyName("id")]
        public string Id { get; set; }

        [JsonPropertyName("result")]
        public object Result { get; set; }
    }

    public partial class Error
    {
        [JsonPropertyName("code")]
        public long Code { get; set; }

        [JsonPropertyName("data")]
        public object Data { get; set; }

        [JsonPropertyName("message")]
        public string Message { get; set; }
    }

    public partial class GetAccessibilityTreeDetailsParams
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("rootId")]
        public string RootId { get; set; }
    }

    public partial class GetAccessibilityTreeDetailsResult
    {
        [JsonPropertyName("tree")]
        public object Tree { get; set; }
    }

    public partial class GetAccessibilityContextParams
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("editableOnly")]
        public bool? EditableOnly { get; set; }
    }

    public partial class GetAccessibilityContextResult
    {
        [JsonPropertyName("context")]
        public Context Context { get; set; }
    }

    public partial class Context
    {
        [JsonPropertyName("application")]
        public Application Application { get; set; }

        [JsonPropertyName("focusedElement")]
        public FocusedElement FocusedElement { get; set; }

        [JsonPropertyName("textSelection")]
        public TextSelection TextSelection { get; set; }

        [JsonPropertyName("timestamp")]
        public double Timestamp { get; set; }

        [JsonPropertyName("windowInfo")]
        public WindowInfo WindowInfo { get; set; }
    }

    public partial class Application
    {
        [JsonPropertyName("bundleIdentifier")]
        public string BundleIdentifier { get; set; }

        [JsonPropertyName("name")]
        public string Name { get; set; }

        [JsonPropertyName("version")]
        public string Version { get; set; }
    }

    public partial class FocusedElement
    {
        [JsonPropertyName("description")]
        public string Description { get; set; }

        [JsonPropertyName("isEditable")]
        public bool IsEditable { get; set; }

        [JsonPropertyName("role")]
        public string Role { get; set; }

        [JsonPropertyName("title")]
        public string Title { get; set; }

        [JsonPropertyName("value")]
        public string Value { get; set; }
    }

    public partial class TextSelection
    {
        [JsonPropertyName("fullContent")]
        public string FullContent { get; set; }

        [JsonPropertyName("isEditable")]
        public bool IsEditable { get; set; }

        [JsonPropertyName("postSelectionText")]
        public string PostSelectionText { get; set; }

        [JsonPropertyName("preSelectionText")]
        public string PreSelectionText { get; set; }

        [JsonPropertyName("selectedText")]
        public string SelectedText { get; set; }

        [JsonPropertyName("selectionRange")]
        public SelectionRange SelectionRange { get; set; }
    }

    public partial class SelectionRange
    {
        [JsonPropertyName("length")]
        public long Length { get; set; }

        [JsonPropertyName("location")]
        public long Location { get; set; }
    }

    public partial class WindowInfo
    {
        [JsonPropertyName("title")]
        public string Title { get; set; }

        [JsonPropertyName("url")]
        public string Url { get; set; }
    }

    public partial class PasteTextParams
    {
        [JsonPropertyName("transcript")]
        public string Transcript { get; set; }
    }

    public partial class PasteTextResult
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("message")]
        public string Message { get; set; }

        [JsonPropertyName("success")]
        public bool Success { get; set; }
    }

    public partial class MuteSystemAudioResult
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("message")]
        public string Message { get; set; }

        [JsonPropertyName("success")]
        public bool Success { get; set; }
    }

    public partial class RestoreSystemAudioResult
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("message")]
        public string Message { get; set; }

        [JsonPropertyName("success")]
        public bool Success { get; set; }
    }

    public partial class SetShortcutsParams
    {
        [JsonPropertyName("pushToTalk")]
        public List<string> PushToTalk { get; set; }

        [JsonPropertyName("toggleRecording")]
        public List<string> ToggleRecording { get; set; }
    }

    public partial class SetShortcutsResult
    {
        [JsonPropertyName("success")]
        public bool Success { get; set; }
    }

    public partial class KeyDownEvent
    {
        [JsonPropertyName("payload")]
        public KeyDownEventPayload Payload { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("timestamp")]
        public DateTimeOffset? Timestamp { get; set; }

        [JsonPropertyName("type")]
        public KeyDownEventType Type { get; set; }
    }

    public partial class KeyDownEventPayload
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("altKey")]
        public bool? AltKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("code")]
        public string Code { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("ctrlKey")]
        public bool? CtrlKey { get; set; }

        /// <summary>
        /// State of the Fn key.
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("fnKeyPressed")]
        public bool? FnKeyPressed { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("key")]
        public string Key { get; set; }

        /// <summary>
        /// Raw key code, e.g., from CGEvent
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("keyCode")]
        public long? KeyCode { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("metaKey")]
        public bool? MetaKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("shiftKey")]
        public bool? ShiftKey { get; set; }
    }

    public partial class KeyUpEvent
    {
        [JsonPropertyName("payload")]
        public KeyUpEventPayload Payload { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("timestamp")]
        public DateTimeOffset? Timestamp { get; set; }

        [JsonPropertyName("type")]
        public KeyUpEventType Type { get; set; }
    }

    public partial class KeyUpEventPayload
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("altKey")]
        public bool? AltKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("code")]
        public string Code { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("ctrlKey")]
        public bool? CtrlKey { get; set; }

        /// <summary>
        /// State of the Fn key.
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("fnKeyPressed")]
        public bool? FnKeyPressed { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("key")]
        public string Key { get; set; }

        /// <summary>
        /// Raw key code, e.g., from CGEvent
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("keyCode")]
        public long? KeyCode { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("metaKey")]
        public bool? MetaKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("shiftKey")]
        public bool? ShiftKey { get; set; }
    }

    public partial class FlagsChangedEvent
    {
        [JsonPropertyName("payload")]
        public FlagsChangedEventPayload Payload { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("timestamp")]
        public DateTimeOffset? Timestamp { get; set; }

        [JsonPropertyName("type")]
        public FlagsChangedEventType Type { get; set; }
    }

    public partial class FlagsChangedEventPayload
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("altKey")]
        public bool? AltKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("code")]
        public string Code { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("ctrlKey")]
        public bool? CtrlKey { get; set; }

        /// <summary>
        /// State of the Fn key.
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("fnKeyPressed")]
        public bool? FnKeyPressed { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("key")]
        public string Key { get; set; }

        /// <summary>
        /// Raw key code, e.g., from CGEvent
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("keyCode")]
        public long? KeyCode { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("metaKey")]
        public bool? MetaKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("shiftKey")]
        public bool? ShiftKey { get; set; }
    }

    public partial class HelperEvent
    {
        [JsonPropertyName("payload")]
        public HelperEventPayload Payload { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("timestamp")]
        public DateTimeOffset? Timestamp { get; set; }

        [JsonPropertyName("type")]
        public HelperEventType Type { get; set; }
    }

    public partial class HelperEventPayload
    {
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("altKey")]
        public bool? AltKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("code")]
        public string Code { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("ctrlKey")]
        public bool? CtrlKey { get; set; }

        /// <summary>
        /// State of the Fn key.
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("fnKeyPressed")]
        public bool? FnKeyPressed { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("key")]
        public string Key { get; set; }

        /// <summary>
        /// Raw key code, e.g., from CGEvent
        /// </summary>
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("keyCode")]
        public long? KeyCode { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("metaKey")]
        public bool? MetaKey { get; set; }

        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        [JsonPropertyName("shiftKey")]
        public bool? ShiftKey { get; set; }
    }

    public enum Method { GetAccessibilityContext, GetAccessibilityTreeDetails, MuteSystemAudio, PasteText, RestoreSystemAudio, SetShortcuts };

    public enum KeyDownEventType { KeyDown };

    public enum KeyUpEventType { KeyUp };

    public enum FlagsChangedEventType { FlagsChanged };

    public enum HelperEventType { FlagsChanged, KeyDown, KeyUp };

    public partial class RpcRequest
    {
        public static RpcRequest FromJson(string json) => JsonSerializer.Deserialize<RpcRequest>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class RpcResponse
    {
        public static RpcResponse FromJson(string json) => JsonSerializer.Deserialize<RpcResponse>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class GetAccessibilityTreeDetailsParams
    {
        public static GetAccessibilityTreeDetailsParams FromJson(string json) => JsonSerializer.Deserialize<GetAccessibilityTreeDetailsParams>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class GetAccessibilityTreeDetailsResult
    {
        public static GetAccessibilityTreeDetailsResult FromJson(string json) => JsonSerializer.Deserialize<GetAccessibilityTreeDetailsResult>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class GetAccessibilityContextParams
    {
        public static GetAccessibilityContextParams FromJson(string json) => JsonSerializer.Deserialize<GetAccessibilityContextParams>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class GetAccessibilityContextResult
    {
        public static GetAccessibilityContextResult FromJson(string json) => JsonSerializer.Deserialize<GetAccessibilityContextResult>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class PasteTextParams
    {
        public static PasteTextParams FromJson(string json) => JsonSerializer.Deserialize<PasteTextParams>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class PasteTextResult
    {
        public static PasteTextResult FromJson(string json) => JsonSerializer.Deserialize<PasteTextResult>(json, WindowsHelper.Models.Converter.Settings);
    }

    public class MuteSystemAudioParams
    {
        public static object FromJson(string json) => JsonSerializer.Deserialize<object>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class MuteSystemAudioResult
    {
        public static MuteSystemAudioResult FromJson(string json) => JsonSerializer.Deserialize<MuteSystemAudioResult>(json, WindowsHelper.Models.Converter.Settings);
    }

    public class RestoreSystemAudioParams
    {
        public static object FromJson(string json) => JsonSerializer.Deserialize<object>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class RestoreSystemAudioResult
    {
        public static RestoreSystemAudioResult FromJson(string json) => JsonSerializer.Deserialize<RestoreSystemAudioResult>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class SetShortcutsParams
    {
        public static SetShortcutsParams FromJson(string json) => JsonSerializer.Deserialize<SetShortcutsParams>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class SetShortcutsResult
    {
        public static SetShortcutsResult FromJson(string json) => JsonSerializer.Deserialize<SetShortcutsResult>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class KeyDownEvent
    {
        public static KeyDownEvent FromJson(string json) => JsonSerializer.Deserialize<KeyDownEvent>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class KeyUpEvent
    {
        public static KeyUpEvent FromJson(string json) => JsonSerializer.Deserialize<KeyUpEvent>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class FlagsChangedEvent
    {
        public static FlagsChangedEvent FromJson(string json) => JsonSerializer.Deserialize<FlagsChangedEvent>(json, WindowsHelper.Models.Converter.Settings);
    }

    public partial class HelperEvent
    {
        public static HelperEvent FromJson(string json) => JsonSerializer.Deserialize<HelperEvent>(json, WindowsHelper.Models.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this RpcRequest self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this RpcResponse self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this GetAccessibilityTreeDetailsParams self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this GetAccessibilityTreeDetailsResult self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this GetAccessibilityContextParams self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this GetAccessibilityContextResult self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this PasteTextParams self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this PasteTextResult self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this object self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this MuteSystemAudioResult self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this RestoreSystemAudioResult self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this SetShortcutsParams self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this SetShortcutsResult self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this KeyDownEvent self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this KeyUpEvent self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this FlagsChangedEvent self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
        public static string ToJson(this HelperEvent self) => JsonSerializer.Serialize(self, WindowsHelper.Models.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)
        {
            Converters =
            {
                MethodConverter.Singleton,
                KeyDownEventTypeConverter.Singleton,
                KeyUpEventTypeConverter.Singleton,
                FlagsChangedEventTypeConverter.Singleton,
                HelperEventTypeConverter.Singleton,
                new DateOnlyConverter(),
                new TimeOnlyConverter(),
                IsoDateTimeOffsetConverter.Singleton
            },
        };
    }

    internal class MethodConverter : JsonConverter<Method>
    {
        public override bool CanConvert(Type t) => t == typeof(Method);

        public override Method Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value = reader.GetString();
            switch (value)
            {
                case "getAccessibilityContext":
                    return Method.GetAccessibilityContext;
                case "getAccessibilityTreeDetails":
                    return Method.GetAccessibilityTreeDetails;
                case "muteSystemAudio":
                    return Method.MuteSystemAudio;
                case "pasteText":
                    return Method.PasteText;
                case "restoreSystemAudio":
                    return Method.RestoreSystemAudio;
                case "setShortcuts":
                    return Method.SetShortcuts;
            }
            throw new Exception("Cannot unmarshal type Method");
        }

        public override void Write(Utf8JsonWriter writer, Method value, JsonSerializerOptions options)
        {
            switch (value)
            {
                case Method.GetAccessibilityContext:
                    JsonSerializer.Serialize(writer, "getAccessibilityContext", options);
                    return;
                case Method.GetAccessibilityTreeDetails:
                    JsonSerializer.Serialize(writer, "getAccessibilityTreeDetails", options);
                    return;
                case Method.MuteSystemAudio:
                    JsonSerializer.Serialize(writer, "muteSystemAudio", options);
                    return;
                case Method.PasteText:
                    JsonSerializer.Serialize(writer, "pasteText", options);
                    return;
                case Method.RestoreSystemAudio:
                    JsonSerializer.Serialize(writer, "restoreSystemAudio", options);
                    return;
                case Method.SetShortcuts:
                    JsonSerializer.Serialize(writer, "setShortcuts", options);
                    return;
            }
            throw new Exception("Cannot marshal type Method");
        }

        public static readonly MethodConverter Singleton = new MethodConverter();
    }

    internal class KeyDownEventTypeConverter : JsonConverter<KeyDownEventType>
    {
        public override bool CanConvert(Type t) => t == typeof(KeyDownEventType);

        public override KeyDownEventType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value = reader.GetString();
            if (value == "keyDown")
            {
                return KeyDownEventType.KeyDown;
            }
            throw new Exception("Cannot unmarshal type KeyDownEventType");
        }

        public override void Write(Utf8JsonWriter writer, KeyDownEventType value, JsonSerializerOptions options)
        {
            if (value == KeyDownEventType.KeyDown)
            {
                JsonSerializer.Serialize(writer, "keyDown", options);
                return;
            }
            throw new Exception("Cannot marshal type KeyDownEventType");
        }

        public static readonly KeyDownEventTypeConverter Singleton = new KeyDownEventTypeConverter();
    }

    internal class KeyUpEventTypeConverter : JsonConverter<KeyUpEventType>
    {
        public override bool CanConvert(Type t) => t == typeof(KeyUpEventType);

        public override KeyUpEventType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value = reader.GetString();
            if (value == "keyUp")
            {
                return KeyUpEventType.KeyUp;
            }
            throw new Exception("Cannot unmarshal type KeyUpEventType");
        }

        public override void Write(Utf8JsonWriter writer, KeyUpEventType value, JsonSerializerOptions options)
        {
            if (value == KeyUpEventType.KeyUp)
            {
                JsonSerializer.Serialize(writer, "keyUp", options);
                return;
            }
            throw new Exception("Cannot marshal type KeyUpEventType");
        }

        public static readonly KeyUpEventTypeConverter Singleton = new KeyUpEventTypeConverter();
    }

    internal class FlagsChangedEventTypeConverter : JsonConverter<FlagsChangedEventType>
    {
        public override bool CanConvert(Type t) => t == typeof(FlagsChangedEventType);

        public override FlagsChangedEventType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value = reader.GetString();
            if (value == "flagsChanged")
            {
                return FlagsChangedEventType.FlagsChanged;
            }
            throw new Exception("Cannot unmarshal type FlagsChangedEventType");
        }

        public override void Write(Utf8JsonWriter writer, FlagsChangedEventType value, JsonSerializerOptions options)
        {
            if (value == FlagsChangedEventType.FlagsChanged)
            {
                JsonSerializer.Serialize(writer, "flagsChanged", options);
                return;
            }
            throw new Exception("Cannot marshal type FlagsChangedEventType");
        }

        public static readonly FlagsChangedEventTypeConverter Singleton = new FlagsChangedEventTypeConverter();
    }

    internal class HelperEventTypeConverter : JsonConverter<HelperEventType>
    {
        public override bool CanConvert(Type t) => t == typeof(HelperEventType);

        public override HelperEventType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value = reader.GetString();
            switch (value)
            {
                case "flagsChanged":
                    return HelperEventType.FlagsChanged;
                case "keyDown":
                    return HelperEventType.KeyDown;
                case "keyUp":
                    return HelperEventType.KeyUp;
            }
            throw new Exception("Cannot unmarshal type HelperEventType");
        }

        public override void Write(Utf8JsonWriter writer, HelperEventType value, JsonSerializerOptions options)
        {
            switch (value)
            {
                case HelperEventType.FlagsChanged:
                    JsonSerializer.Serialize(writer, "flagsChanged", options);
                    return;
                case HelperEventType.KeyDown:
                    JsonSerializer.Serialize(writer, "keyDown", options);
                    return;
                case HelperEventType.KeyUp:
                    JsonSerializer.Serialize(writer, "keyUp", options);
                    return;
            }
            throw new Exception("Cannot marshal type HelperEventType");
        }

        public static readonly HelperEventTypeConverter Singleton = new HelperEventTypeConverter();
    }
    
    public class DateOnlyConverter : JsonConverter<DateOnly>
    {
        private readonly string serializationFormat;
        public DateOnlyConverter() : this(null) { }

        public DateOnlyConverter(string? serializationFormat)
        {
                this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
        }

        public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
                var value = reader.GetString();
                return DateOnly.Parse(value!);
        }

        public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
                => writer.WriteStringValue(value.ToString(serializationFormat));
    }

    public class TimeOnlyConverter : JsonConverter<TimeOnly>
    {
        private readonly string serializationFormat;

        public TimeOnlyConverter() : this(null) { }

        public TimeOnlyConverter(string? serializationFormat)
        {
                this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
        }

        public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
                var value = reader.GetString();
                return TimeOnly.Parse(value!);
        }

        public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
                => writer.WriteStringValue(value.ToString(serializationFormat));
    }

    internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
    {
        public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);

        private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

        private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
        private string? _dateTimeFormat;
        private CultureInfo? _culture;

        public DateTimeStyles DateTimeStyles
        {
                get => _dateTimeStyles;
                set => _dateTimeStyles = value;
        }

        public string? DateTimeFormat
        {
                get => _dateTimeFormat ?? string.Empty;
                set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
        }

        public CultureInfo Culture
        {
                get => _culture ?? CultureInfo.CurrentCulture;
                set => _culture = value;
        }

        public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
        {
                string text;


                if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
                        || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
                {
                        value = value.ToUniversalTime();
                }

                text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);

                writer.WriteStringValue(text);
        }

        public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
                string? dateText = reader.GetString();

                if (string.IsNullOrEmpty(dateText) == false)
                {
                        if (!string.IsNullOrEmpty(_dateTimeFormat))
                        {
                                return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
                        }
                        else
                        {
                                return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
                        }
                }
                else
                {
                        return default(DateTimeOffset);
                }
        }


        public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
    }
}
#pragma warning restore CS8618
#pragma warning restore CS8601
#pragma warning restore CS8603
