|
|
|
@ -1,246 +1,259 @@ |
|
|
|
// <auto-generated />
|
|
|
|
// <auto-generated />
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
|
|
|
|
// To parse this JSON data, add NuGet 'System.Text.Json' then do:
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// using ErsatzTV.Core.Next.Config;
|
|
|
|
// using ErsatzTV.Core.Next.Config;
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// var channelConfig = ChannelConfig.FromJson(jsonString);
|
|
|
|
// var channelConfig = ChannelConfig.FromJson(jsonString);
|
|
|
|
|
|
|
|
#nullable enable |
|
|
|
|
|
|
|
#pragma warning disable CS8618
|
|
|
|
|
|
|
|
#pragma warning disable CS8601
|
|
|
|
|
|
|
|
#pragma warning disable CS8602
|
|
|
|
|
|
|
|
#pragma warning disable CS8603
|
|
|
|
|
|
|
|
|
|
|
|
namespace ErsatzTV.Core.Next.Config |
|
|
|
namespace ErsatzTV.Core.Next.Config |
|
|
|
{ |
|
|
|
{ |
|
|
|
using System; |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using System.Text.Json; |
|
|
|
|
|
|
|
using System.Text.Json.Serialization; |
|
|
|
using System.Globalization; |
|
|
|
using System.Globalization; |
|
|
|
using Newtonsoft.Json; |
|
|
|
|
|
|
|
using Newtonsoft.Json.Converters; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public partial class ChannelConfig |
|
|
|
public partial class ChannelConfig |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("ffmpeg")] |
|
|
|
[JsonPropertyName("ffmpeg")] |
|
|
|
public Ffmpeg Ffmpeg { get; set; } |
|
|
|
public Ffmpeg Ffmpeg { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("normalization")] |
|
|
|
[JsonPropertyName("normalization")] |
|
|
|
public Normalization Normalization { get; set; } |
|
|
|
public Normalization Normalization { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("playout")] |
|
|
|
[JsonPropertyName("playout")] |
|
|
|
public Playout Playout { get; set; } |
|
|
|
public Playout Playout { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class Ffmpeg |
|
|
|
public partial class Ffmpeg |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("disabled_filters", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
public List<string> DisabledFilters { get; set; } |
|
|
|
[JsonPropertyName("disabled_filters")] |
|
|
|
|
|
|
|
public List<string>? DisabledFilters { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("ffmpeg_path")] |
|
|
|
[JsonPropertyName("ffmpeg_path")] |
|
|
|
public string FfmpegPath { get; set; } |
|
|
|
public string? FfmpegPath { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("ffprobe_path")] |
|
|
|
[JsonPropertyName("ffprobe_path")] |
|
|
|
public string FfprobePath { get; set; } |
|
|
|
public string? FfprobePath { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("preferred_filters", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
public List<string> PreferredFilters { get; set; } |
|
|
|
[JsonPropertyName("preferred_filters")] |
|
|
|
|
|
|
|
public List<string>? PreferredFilters { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("reports_folder")] |
|
|
|
[JsonPropertyName("reports_folder")] |
|
|
|
public string ReportsFolder { get; set; } |
|
|
|
public string? ReportsFolder { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class Normalization |
|
|
|
public partial class Normalization |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("audio")] |
|
|
|
[JsonPropertyName("audio")] |
|
|
|
public Audio Audio { get; set; } |
|
|
|
public Audio Audio { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("subtitle", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
public Subtitle Subtitle { get; set; } |
|
|
|
[JsonPropertyName("subtitle")] |
|
|
|
|
|
|
|
public Subtitle? Subtitle { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("video")] |
|
|
|
[JsonPropertyName("video")] |
|
|
|
public Video Video { get; set; } |
|
|
|
public Video Video { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class Audio |
|
|
|
public partial class Audio |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("bitrate_kbps")] |
|
|
|
[JsonPropertyName("bitrate_kbps")] |
|
|
|
public long? BitrateKbps { get; set; } |
|
|
|
public long? BitrateKbps { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("buffer_kbps")] |
|
|
|
[JsonPropertyName("buffer_kbps")] |
|
|
|
public long? BufferKbps { get; set; } |
|
|
|
public long? BufferKbps { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("channels")] |
|
|
|
[JsonPropertyName("channels")] |
|
|
|
public long? Channels { get; set; } |
|
|
|
public long? Channels { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("format")] |
|
|
|
[JsonPropertyName("format")] |
|
|
|
public AudioFormat? Format { get; set; } |
|
|
|
public AudioFormat? Format { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("loudness")] |
|
|
|
[JsonPropertyName("loudness")] |
|
|
|
public LoudnessClass Loudness { get; set; } |
|
|
|
public LoudnessClass? Loudness { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("normalize_loudness", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
|
|
|
|
[JsonPropertyName("normalize_loudness")] |
|
|
|
public bool? NormalizeLoudness { get; set; } |
|
|
|
public bool? NormalizeLoudness { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("sample_rate_hz")] |
|
|
|
[JsonPropertyName("sample_rate_hz")] |
|
|
|
public long? SampleRateHz { get; set; } |
|
|
|
public long? SampleRateHz { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class LoudnessClass |
|
|
|
public partial class LoudnessClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("integrated_target")] |
|
|
|
[JsonPropertyName("integrated_target")] |
|
|
|
public double? IntegratedTarget { get; set; } |
|
|
|
public double? IntegratedTarget { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("range_target")] |
|
|
|
[JsonPropertyName("range_target")] |
|
|
|
public double? RangeTarget { get; set; } |
|
|
|
public double? RangeTarget { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("true_peak")] |
|
|
|
[JsonPropertyName("true_peak")] |
|
|
|
public double? TruePeak { get; set; } |
|
|
|
public double? TruePeak { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class Subtitle |
|
|
|
public partial class Subtitle |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
|
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public Mode? Mode { get; set; } |
|
|
|
public Mode? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class Video |
|
|
|
public partial class Video |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("accel")] |
|
|
|
[JsonPropertyName("accel")] |
|
|
|
public AccelEnum? Accel { get; set; } |
|
|
|
public AccelEnum? Accel { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("bit_depth")] |
|
|
|
[JsonPropertyName("bit_depth")] |
|
|
|
public long? BitDepth { get; set; } |
|
|
|
public long? BitDepth { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("bitrate_kbps")] |
|
|
|
[JsonPropertyName("bitrate_kbps")] |
|
|
|
public long? BitrateKbps { get; set; } |
|
|
|
public long? BitrateKbps { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("buffer_kbps")] |
|
|
|
[JsonPropertyName("buffer_kbps")] |
|
|
|
public long? BufferKbps { get; set; } |
|
|
|
public long? BufferKbps { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("deinterlace", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
|
|
|
|
[JsonPropertyName("deinterlace")] |
|
|
|
public bool? Deinterlace { get; set; } |
|
|
|
public bool? Deinterlace { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("filters", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
public Filters Filters { get; set; } |
|
|
|
[JsonPropertyName("filters")] |
|
|
|
|
|
|
|
public Filters? Filters { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("format")] |
|
|
|
[JsonPropertyName("format")] |
|
|
|
public VideoFormat? Format { get; set; } |
|
|
|
public VideoFormat? Format { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("height")] |
|
|
|
[JsonPropertyName("height")] |
|
|
|
public long? Height { get; set; } |
|
|
|
public long? Height { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("scaling_mode", NullValueHandling = NullValueHandling.Ignore)] |
|
|
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] |
|
|
|
|
|
|
|
[JsonPropertyName("scaling_mode")] |
|
|
|
public ScalingMode? ScalingMode { get; set; } |
|
|
|
public ScalingMode? ScalingMode { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("vaapi_device")] |
|
|
|
[JsonPropertyName("vaapi_device")] |
|
|
|
public string VaapiDevice { get; set; } |
|
|
|
public string? VaapiDevice { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("vaapi_driver")] |
|
|
|
[JsonPropertyName("vaapi_driver")] |
|
|
|
public VaapiDriverEnum? VaapiDriver { get; set; } |
|
|
|
public VaapiDriverEnum? VaapiDriver { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("width")] |
|
|
|
[JsonPropertyName("width")] |
|
|
|
public long? Width { get; set; } |
|
|
|
public long? Width { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class Filters |
|
|
|
public partial class Filters |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("bwdif")] |
|
|
|
[JsonPropertyName("bwdif")] |
|
|
|
public BwdifClass Bwdif { get; set; } |
|
|
|
public BwdifClass? Bwdif { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("bwdif_cuda")] |
|
|
|
[JsonPropertyName("bwdif_cuda")] |
|
|
|
public BwdifCudaClass BwdifCuda { get; set; } |
|
|
|
public BwdifCudaClass? BwdifCuda { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("deinterlace_qsv")] |
|
|
|
[JsonPropertyName("deinterlace_qsv")] |
|
|
|
public DeinterlaceQsvClass DeinterlaceQsv { get; set; } |
|
|
|
public DeinterlaceQsvClass? DeinterlaceQsv { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("deinterlace_vaapi")] |
|
|
|
[JsonPropertyName("deinterlace_vaapi")] |
|
|
|
public DeinterlaceVaapiClass DeinterlaceVaapi { get; set; } |
|
|
|
public DeinterlaceVaapiClass? DeinterlaceVaapi { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("libplacebo")] |
|
|
|
[JsonPropertyName("libplacebo")] |
|
|
|
public LibplaceboClass Libplacebo { get; set; } |
|
|
|
public LibplaceboClass? Libplacebo { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("tonemap")] |
|
|
|
[JsonPropertyName("tonemap")] |
|
|
|
public TonemapClass Tonemap { get; set; } |
|
|
|
public TonemapClass? Tonemap { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("tonemap_opencl")] |
|
|
|
[JsonPropertyName("tonemap_opencl")] |
|
|
|
public TonemapOpenclClass TonemapOpencl { get; set; } |
|
|
|
public TonemapOpenclClass? TonemapOpencl { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("w3fdif")] |
|
|
|
[JsonPropertyName("w3fdif")] |
|
|
|
public W3FdifClass W3Fdif { get; set; } |
|
|
|
public W3FdifClass? W3Fdif { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("yadif")] |
|
|
|
[JsonPropertyName("yadif")] |
|
|
|
public YadifClass Yadif { get; set; } |
|
|
|
public YadifClass? Yadif { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty("yadif_cuda")] |
|
|
|
[JsonPropertyName("yadif_cuda")] |
|
|
|
public YadifCudaClass YadifCuda { get; set; } |
|
|
|
public YadifCudaClass? YadifCuda { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class BwdifClass |
|
|
|
public partial class BwdifClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode")] |
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public string Mode { get; set; } |
|
|
|
public string? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class BwdifCudaClass |
|
|
|
public partial class BwdifCudaClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode")] |
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public string Mode { get; set; } |
|
|
|
public string? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class DeinterlaceQsvClass |
|
|
|
public partial class DeinterlaceQsvClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode")] |
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public string Mode { get; set; } |
|
|
|
public string? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class DeinterlaceVaapiClass |
|
|
|
public partial class DeinterlaceVaapiClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode")] |
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public string Mode { get; set; } |
|
|
|
public string? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class LibplaceboClass |
|
|
|
public partial class LibplaceboClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("tonemapping")] |
|
|
|
[JsonPropertyName("tonemapping")] |
|
|
|
public string Tonemapping { get; set; } |
|
|
|
public string? Tonemapping { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class TonemapClass |
|
|
|
public partial class TonemapClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("tonemap")] |
|
|
|
[JsonPropertyName("tonemap")] |
|
|
|
public string Tonemap { get; set; } |
|
|
|
public string? Tonemap { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class TonemapOpenclClass |
|
|
|
public partial class TonemapOpenclClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("tonemap")] |
|
|
|
[JsonPropertyName("tonemap")] |
|
|
|
public string Tonemap { get; set; } |
|
|
|
public string? Tonemap { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class W3FdifClass |
|
|
|
public partial class W3FdifClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode")] |
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public string Mode { get; set; } |
|
|
|
public string? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class YadifClass |
|
|
|
public partial class YadifClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode")] |
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public string Mode { get; set; } |
|
|
|
public string? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class YadifCudaClass |
|
|
|
public partial class YadifCudaClass |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("mode")] |
|
|
|
[JsonPropertyName("mode")] |
|
|
|
public string Mode { get; set; } |
|
|
|
public string? Mode { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public partial class Playout |
|
|
|
public partial class Playout |
|
|
|
{ |
|
|
|
{ |
|
|
|
[JsonProperty("folder")] |
|
|
|
[JsonPropertyName("folder")] |
|
|
|
public string Folder { get; set; } |
|
|
|
public string Folder { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// RFC3339 formatted date/time, e.g. 2026-04-13T00:24:21.527-05:00
|
|
|
|
/// RFC3339 formatted date/time, e.g. 2026-04-13T00:24:21.527-05:00
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
[JsonProperty("virtual_start")] |
|
|
|
[JsonPropertyName("virtual_start")] |
|
|
|
public string VirtualStart { get; set; } |
|
|
|
public string? VirtualStart { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public enum AudioFormat { Aac, Ac3 }; |
|
|
|
public enum AudioFormat { Aac, Ac3 }; |
|
|
|
@ -257,21 +270,19 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
|
|
|
|
|
|
|
|
public partial class ChannelConfig |
|
|
|
public partial class ChannelConfig |
|
|
|
{ |
|
|
|
{ |
|
|
|
public static ChannelConfig FromJson(string json) => JsonConvert.DeserializeObject<ChannelConfig>(json, ErsatzTV.Core.Next.Config.Converter.Settings); |
|
|
|
public static ChannelConfig FromJson(string json) => JsonSerializer.Deserialize<ChannelConfig>(json, ErsatzTV.Core.Next.Config.Converter.Settings); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static class Serialize |
|
|
|
public static class Serialize |
|
|
|
{ |
|
|
|
{ |
|
|
|
public static string ToJson(this ChannelConfig self) => JsonConvert.SerializeObject(self, ErsatzTV.Core.Next.Config.Converter.Settings); |
|
|
|
public static string ToJson(this ChannelConfig self) => JsonSerializer.Serialize(self, ErsatzTV.Core.Next.Config.Converter.Settings); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal static class Converter |
|
|
|
internal static class Converter |
|
|
|
{ |
|
|
|
{ |
|
|
|
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings |
|
|
|
public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General) |
|
|
|
{ |
|
|
|
{ |
|
|
|
NullValueHandling = NullValueHandling.Ignore, |
|
|
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, |
|
|
|
MetadataPropertyHandling = MetadataPropertyHandling.Ignore, |
|
|
|
|
|
|
|
DateParseHandling = DateParseHandling.None, |
|
|
|
|
|
|
|
Converters = |
|
|
|
Converters = |
|
|
|
{ |
|
|
|
{ |
|
|
|
AudioFormatConverter.Singleton, |
|
|
|
AudioFormatConverter.Singleton, |
|
|
|
@ -280,19 +291,20 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
VideoFormatConverter.Singleton, |
|
|
|
VideoFormatConverter.Singleton, |
|
|
|
ScalingModeConverter.Singleton, |
|
|
|
ScalingModeConverter.Singleton, |
|
|
|
VaapiDriverEnumConverter.Singleton, |
|
|
|
VaapiDriverEnumConverter.Singleton, |
|
|
|
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } |
|
|
|
new DateOnlyConverter(), |
|
|
|
|
|
|
|
new TimeOnlyConverter(), |
|
|
|
|
|
|
|
IsoDateTimeOffsetConverter.Singleton |
|
|
|
}, |
|
|
|
}, |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal class AudioFormatConverter : JsonConverter |
|
|
|
internal class AudioFormatConverter : JsonConverter<AudioFormat> |
|
|
|
{ |
|
|
|
{ |
|
|
|
public override bool CanConvert(Type t) => t == typeof(AudioFormat) || t == typeof(AudioFormat?); |
|
|
|
public override bool CanConvert(Type t) => t == typeof(AudioFormat); |
|
|
|
|
|
|
|
|
|
|
|
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) |
|
|
|
public override AudioFormat Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (reader.TokenType == JsonToken.Null) return null; |
|
|
|
var value = reader.GetString(); |
|
|
|
var value = serializer.Deserialize<string>(reader); |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case "aac": |
|
|
|
case "aac": |
|
|
|
@ -303,21 +315,15 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
throw new Exception("Cannot unmarshal type AudioFormat"); |
|
|
|
throw new Exception("Cannot unmarshal type AudioFormat"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) |
|
|
|
public override void Write(Utf8JsonWriter writer, AudioFormat value, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (untypedValue == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
serializer.Serialize(writer, null); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var value = (AudioFormat)untypedValue; |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case AudioFormat.Aac: |
|
|
|
case AudioFormat.Aac: |
|
|
|
serializer.Serialize(writer, "aac"); |
|
|
|
JsonSerializer.Serialize(writer, "aac", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case AudioFormat.Ac3: |
|
|
|
case AudioFormat.Ac3: |
|
|
|
serializer.Serialize(writer, "ac3"); |
|
|
|
JsonSerializer.Serialize(writer, "ac3", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
throw new Exception("Cannot marshal type AudioFormat"); |
|
|
|
throw new Exception("Cannot marshal type AudioFormat"); |
|
|
|
@ -326,14 +332,13 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
public static readonly AudioFormatConverter Singleton = new AudioFormatConverter(); |
|
|
|
public static readonly AudioFormatConverter Singleton = new AudioFormatConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal class ModeConverter : JsonConverter |
|
|
|
internal class ModeConverter : JsonConverter<Mode> |
|
|
|
{ |
|
|
|
{ |
|
|
|
public override bool CanConvert(Type t) => t == typeof(Mode) || t == typeof(Mode?); |
|
|
|
public override bool CanConvert(Type t) => t == typeof(Mode); |
|
|
|
|
|
|
|
|
|
|
|
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) |
|
|
|
public override Mode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (reader.TokenType == JsonToken.Null) return null; |
|
|
|
var value = reader.GetString(); |
|
|
|
var value = serializer.Deserialize<string>(reader); |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case "burn": |
|
|
|
case "burn": |
|
|
|
@ -344,21 +349,15 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
throw new Exception("Cannot unmarshal type Mode"); |
|
|
|
throw new Exception("Cannot unmarshal type Mode"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) |
|
|
|
public override void Write(Utf8JsonWriter writer, Mode value, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (untypedValue == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
serializer.Serialize(writer, null); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var value = (Mode)untypedValue; |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case Mode.Burn: |
|
|
|
case Mode.Burn: |
|
|
|
serializer.Serialize(writer, "burn"); |
|
|
|
JsonSerializer.Serialize(writer, "burn", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case Mode.Convert: |
|
|
|
case Mode.Convert: |
|
|
|
serializer.Serialize(writer, "convert"); |
|
|
|
JsonSerializer.Serialize(writer, "convert", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
throw new Exception("Cannot marshal type Mode"); |
|
|
|
throw new Exception("Cannot marshal type Mode"); |
|
|
|
@ -367,14 +366,13 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
public static readonly ModeConverter Singleton = new ModeConverter(); |
|
|
|
public static readonly ModeConverter Singleton = new ModeConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal class AccelEnumConverter : JsonConverter |
|
|
|
internal class AccelEnumConverter : JsonConverter<AccelEnum> |
|
|
|
{ |
|
|
|
{ |
|
|
|
public override bool CanConvert(Type t) => t == typeof(AccelEnum) || t == typeof(AccelEnum?); |
|
|
|
public override bool CanConvert(Type t) => t == typeof(AccelEnum); |
|
|
|
|
|
|
|
|
|
|
|
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) |
|
|
|
public override AccelEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (reader.TokenType == JsonToken.Null) return null; |
|
|
|
var value = reader.GetString(); |
|
|
|
var value = serializer.Deserialize<string>(reader); |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case "amf": |
|
|
|
case "amf": |
|
|
|
@ -395,36 +393,30 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
throw new Exception("Cannot unmarshal type AccelEnum"); |
|
|
|
throw new Exception("Cannot unmarshal type AccelEnum"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) |
|
|
|
public override void Write(Utf8JsonWriter writer, AccelEnum value, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (untypedValue == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
serializer.Serialize(writer, null); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var value = (AccelEnum)untypedValue; |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case AccelEnum.Amf: |
|
|
|
case AccelEnum.Amf: |
|
|
|
serializer.Serialize(writer, "amf"); |
|
|
|
JsonSerializer.Serialize(writer, "amf", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case AccelEnum.Cuda: |
|
|
|
case AccelEnum.Cuda: |
|
|
|
serializer.Serialize(writer, "cuda"); |
|
|
|
JsonSerializer.Serialize(writer, "cuda", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case AccelEnum.Qsv: |
|
|
|
case AccelEnum.Qsv: |
|
|
|
serializer.Serialize(writer, "qsv"); |
|
|
|
JsonSerializer.Serialize(writer, "qsv", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case AccelEnum.Rkmpp: |
|
|
|
case AccelEnum.Rkmpp: |
|
|
|
serializer.Serialize(writer, "rkmpp"); |
|
|
|
JsonSerializer.Serialize(writer, "rkmpp", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case AccelEnum.Vaapi: |
|
|
|
case AccelEnum.Vaapi: |
|
|
|
serializer.Serialize(writer, "vaapi"); |
|
|
|
JsonSerializer.Serialize(writer, "vaapi", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case AccelEnum.Videotoolbox: |
|
|
|
case AccelEnum.Videotoolbox: |
|
|
|
serializer.Serialize(writer, "videotoolbox"); |
|
|
|
JsonSerializer.Serialize(writer, "videotoolbox", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case AccelEnum.Vulkan: |
|
|
|
case AccelEnum.Vulkan: |
|
|
|
serializer.Serialize(writer, "vulkan"); |
|
|
|
JsonSerializer.Serialize(writer, "vulkan", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
throw new Exception("Cannot marshal type AccelEnum"); |
|
|
|
throw new Exception("Cannot marshal type AccelEnum"); |
|
|
|
@ -433,14 +425,13 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
public static readonly AccelEnumConverter Singleton = new AccelEnumConverter(); |
|
|
|
public static readonly AccelEnumConverter Singleton = new AccelEnumConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal class VideoFormatConverter : JsonConverter |
|
|
|
internal class VideoFormatConverter : JsonConverter<VideoFormat> |
|
|
|
{ |
|
|
|
{ |
|
|
|
public override bool CanConvert(Type t) => t == typeof(VideoFormat) || t == typeof(VideoFormat?); |
|
|
|
public override bool CanConvert(Type t) => t == typeof(VideoFormat); |
|
|
|
|
|
|
|
|
|
|
|
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) |
|
|
|
public override VideoFormat Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (reader.TokenType == JsonToken.Null) return null; |
|
|
|
var value = reader.GetString(); |
|
|
|
var value = serializer.Deserialize<string>(reader); |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case "h264": |
|
|
|
case "h264": |
|
|
|
@ -451,21 +442,15 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
throw new Exception("Cannot unmarshal type VideoFormat"); |
|
|
|
throw new Exception("Cannot unmarshal type VideoFormat"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) |
|
|
|
public override void Write(Utf8JsonWriter writer, VideoFormat value, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (untypedValue == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
serializer.Serialize(writer, null); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var value = (VideoFormat)untypedValue; |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case VideoFormat.H264: |
|
|
|
case VideoFormat.H264: |
|
|
|
serializer.Serialize(writer, "h264"); |
|
|
|
JsonSerializer.Serialize(writer, "h264", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case VideoFormat.Hevc: |
|
|
|
case VideoFormat.Hevc: |
|
|
|
serializer.Serialize(writer, "hevc"); |
|
|
|
JsonSerializer.Serialize(writer, "hevc", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
throw new Exception("Cannot marshal type VideoFormat"); |
|
|
|
throw new Exception("Cannot marshal type VideoFormat"); |
|
|
|
@ -474,14 +459,13 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
public static readonly VideoFormatConverter Singleton = new VideoFormatConverter(); |
|
|
|
public static readonly VideoFormatConverter Singleton = new VideoFormatConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal class ScalingModeConverter : JsonConverter |
|
|
|
internal class ScalingModeConverter : JsonConverter<ScalingMode> |
|
|
|
{ |
|
|
|
{ |
|
|
|
public override bool CanConvert(Type t) => t == typeof(ScalingMode) || t == typeof(ScalingMode?); |
|
|
|
public override bool CanConvert(Type t) => t == typeof(ScalingMode); |
|
|
|
|
|
|
|
|
|
|
|
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) |
|
|
|
public override ScalingMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (reader.TokenType == JsonToken.Null) return null; |
|
|
|
var value = reader.GetString(); |
|
|
|
var value = serializer.Deserialize<string>(reader); |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case "crop": |
|
|
|
case "crop": |
|
|
|
@ -494,24 +478,18 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
throw new Exception("Cannot unmarshal type ScalingMode"); |
|
|
|
throw new Exception("Cannot unmarshal type ScalingMode"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) |
|
|
|
public override void Write(Utf8JsonWriter writer, ScalingMode value, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (untypedValue == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
serializer.Serialize(writer, null); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var value = (ScalingMode)untypedValue; |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case ScalingMode.Crop: |
|
|
|
case ScalingMode.Crop: |
|
|
|
serializer.Serialize(writer, "crop"); |
|
|
|
JsonSerializer.Serialize(writer, "crop", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case ScalingMode.ScaleAndPad: |
|
|
|
case ScalingMode.ScaleAndPad: |
|
|
|
serializer.Serialize(writer, "scale_and_pad"); |
|
|
|
JsonSerializer.Serialize(writer, "scale_and_pad", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case ScalingMode.Stretch: |
|
|
|
case ScalingMode.Stretch: |
|
|
|
serializer.Serialize(writer, "stretch"); |
|
|
|
JsonSerializer.Serialize(writer, "stretch", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
throw new Exception("Cannot marshal type ScalingMode"); |
|
|
|
throw new Exception("Cannot marshal type ScalingMode"); |
|
|
|
@ -520,14 +498,13 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
public static readonly ScalingModeConverter Singleton = new ScalingModeConverter(); |
|
|
|
public static readonly ScalingModeConverter Singleton = new ScalingModeConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal class VaapiDriverEnumConverter : JsonConverter |
|
|
|
internal class VaapiDriverEnumConverter : JsonConverter<VaapiDriverEnum> |
|
|
|
{ |
|
|
|
{ |
|
|
|
public override bool CanConvert(Type t) => t == typeof(VaapiDriverEnum) || t == typeof(VaapiDriverEnum?); |
|
|
|
public override bool CanConvert(Type t) => t == typeof(VaapiDriverEnum); |
|
|
|
|
|
|
|
|
|
|
|
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) |
|
|
|
public override VaapiDriverEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (reader.TokenType == JsonToken.Null) return null; |
|
|
|
var value = reader.GetString(); |
|
|
|
var value = serializer.Deserialize<string>(reader); |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case "i965": |
|
|
|
case "i965": |
|
|
|
@ -540,24 +517,18 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
throw new Exception("Cannot unmarshal type VaapiDriverEnum"); |
|
|
|
throw new Exception("Cannot unmarshal type VaapiDriverEnum"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) |
|
|
|
public override void Write(Utf8JsonWriter writer, VaapiDriverEnum value, JsonSerializerOptions options) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (untypedValue == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
serializer.Serialize(writer, null); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var value = (VaapiDriverEnum)untypedValue; |
|
|
|
|
|
|
|
switch (value) |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case VaapiDriverEnum.I965: |
|
|
|
case VaapiDriverEnum.I965: |
|
|
|
serializer.Serialize(writer, "i965"); |
|
|
|
JsonSerializer.Serialize(writer, "i965", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case VaapiDriverEnum.Ihd: |
|
|
|
case VaapiDriverEnum.Ihd: |
|
|
|
serializer.Serialize(writer, "ihd"); |
|
|
|
JsonSerializer.Serialize(writer, "ihd", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
case VaapiDriverEnum.Radeonsi: |
|
|
|
case VaapiDriverEnum.Radeonsi: |
|
|
|
serializer.Serialize(writer, "radeonsi"); |
|
|
|
JsonSerializer.Serialize(writer, "radeonsi", options); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
throw new Exception("Cannot marshal type VaapiDriverEnum"); |
|
|
|
throw new Exception("Cannot marshal type VaapiDriverEnum"); |
|
|
|
@ -565,4 +536,118 @@ namespace ErsatzTV.Core.Next.Config |
|
|
|
|
|
|
|
|
|
|
|
public static readonly VaapiDriverEnumConverter Singleton = new VaapiDriverEnumConverter(); |
|
|
|
public static readonly VaapiDriverEnumConverter Singleton = new VaapiDriverEnumConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 CS8602
|
|
|
|
|
|
|
|
#pragma warning restore CS8603
|
|
|
|
|