< Summary - pva.SuperV

Information
Class: pva.SuperV.Engine.JsonConverters.InstanceJsonConverter
Assembly: pva.SuperV.Engine
File(s): /home/runner/work/pva.SuperV/pva.SuperV/pva.SuperV.Engine/JsonConverters/InstanceJsonConverter.cs
Tag: dotnet-ubuntu_22190969454
Line coverage
92%
Covered lines: 72
Uncovered lines: 6
Coverable lines: 78
Total lines: 145
Line coverage: 92.3%
Branch coverage
73%
Covered branches: 19
Total branches: 26
Branch coverage: 73%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
get_LoadedProject()100%11100%
Read(...)100%1176.92%
DeserializeFields(...)75%44100%
DeserializeField(...)60%101088.46%
Write(...)100%11100%
SerializeFields(...)83.33%1212100%

File(s)

/home/runner/work/pva.SuperV/pva.SuperV/pva.SuperV.Engine/JsonConverters/InstanceJsonConverter.cs

#LineLine coverage
 1using pva.Helpers.Extensions;
 2using pva.SuperV.Common;
 3using pva.SuperV.Engine.Exceptions;
 4using System.Globalization;
 5using System.Text.Json;
 6using System.Text.Json.Serialization;
 7
 8namespace pva.SuperV.Engine.JsonConverters
 9{
 10    /// <summary>
 11    /// Json converter for an instance.
 12    /// </summary>
 13    /// <seealso cref="JsonConverter&lt;IInstance&gt;" />
 14    public class InstanceJsonConverter : JsonConverter<IInstance>
 15    {
 16        /// <summary>
 17        /// The iso8601 UTC date format used to save/load date times.
 18        /// </summary>
 19        private const string Iso8601UtcDateFormat = "yyyy-MM-ddTHH:mm:ss.sssZ";
 20
 21        /// <summary>
 22        /// The field converters
 23        /// </summary>
 224        private static readonly Dictionary<Type, dynamic> FieldConverters = [];
 25
 26        /// <summary>
 27        /// Gets or sets the loaded project. Set before deserializing.
 28        /// </summary>
 29        /// <value>
 30        /// The loaded project.
 31        /// </value>
 4332        public static RunnableProject LoadedProject { get; set; } = null!;
 33
 34        /// <summary>
 35        /// Reads and converts the JSON to type.
 36        /// </summary>
 37        /// <param name="reader">The reader.</param>
 38        /// <param name="typeToConvert">The type to convert.</param>
 39        /// <param name="options">An object that specifies serialization options to use.</param>
 40        /// <returns>
 41        /// The converted value.
 42        /// </returns>
 43        /// <exception cref="JsonException"></exception>
 44        /// <exception cref="InstanceCreationException"></exception>
 45        public override IInstance? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
 1446        {
 1447            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.StartObject, false);
 1448            string? instanceClass = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Class");
 1449            string? instanceName = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Name");
 1450            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.PropertyName);
 51            try
 1452            {
 1453                IInstance? instance = LoadedProject.CreateInstance(instanceClass!, instanceName!);
 1454                DeserializeFields(ref reader, options, instance!);
 1455                return instance;
 56            }
 057            catch (Exception ex)
 058            {
 059                throw new InstanceCreationException(instanceName!, instanceClass!, ex);
 60            }
 1461        }
 62
 63        private static void DeserializeFields(ref Utf8JsonReader reader, JsonSerializerOptions options, IInstance instan
 1464        {
 1465            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.StartArray);
 3466            while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
 2067            {
 2068                reader = DeserializeField(reader, options, instance);
 2069            }
 1470            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.EndObject);
 1471        }
 72
 73        private static Utf8JsonReader DeserializeField(Utf8JsonReader reader, JsonSerializerOptions options, IInstance i
 2074        {
 2075            if (reader.TokenType == JsonTokenType.StartObject)
 2076            {
 2077                string? fieldTypeString = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Type");
 2078                string? fieldName = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Name");
 79
 2080                reader.Read();
 2081                string? readPropertyName = reader.GetString();
 2082                if (readPropertyName == "Value")
 2083                {
 2084                    Type? fieldType = Type.GetType(fieldTypeString!);
 2085                    dynamic? fieldValue = JsonSerializer.Deserialize(ref reader, fieldType!, options);
 2086                    string? valueTimestampStr = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Timestamp");
 2087                    _ = DateTime.TryParseExact(valueTimestampStr, Iso8601UtcDateFormat, CultureInfo.InvariantCulture, Da
 2088                        out DateTime valueTimestamp);
 2089                    string? valueQualityStr = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Quality");
 2090                    _ = Enum.TryParse(valueQualityStr, out QualityLevel valueQuality);
 91
 2092                    dynamic? dynamicField = (instance as Instance)?.GetField(fieldName!);
 2093                    dynamicField!.SetValueInternal(fieldValue, valueTimestamp, valueQuality);
 94
 2095                    reader.Read();
 2096                    if (reader.TokenType == JsonTokenType.EndObject)
 2097                    {
 2098                        return reader;
 99                    }
 0100                }
 0101            }
 0102            throw new JsonException();
 20103        }
 104
 105        /// <summary>
 106        /// Writes a specified value as JSON.
 107        /// </summary>
 108        /// <param name="writer">The writer to write to.</param>
 109        /// <param name="value">The value to convert to JSON.</param>
 110        /// <param name="options">An object that specifies serialization options to use.</param>
 111        public override void Write(Utf8JsonWriter writer, IInstance value, JsonSerializerOptions options)
 13112        {
 13113            Instance instance = (Instance)value;
 13114            writer.WriteStartObject();
 115
 13116            writer.WriteString("Class", instance.Class.Name);
 13117            writer.WriteString("Name", instance.Name);
 13118            SerializeFields(writer, options, instance);
 13119            writer.WriteEndObject();
 13120        }
 121
 122        private static void SerializeFields(Utf8JsonWriter writer, JsonSerializerOptions options, Instance instance)
 13123        {
 13124            writer.WriteStartArray("Fields");
 13125            instance.Fields.ForEach((k, v) =>
 19126            {
 19127                writer.WriteStartObject();
 19128                Type fieldType = v.Type;
 19129                writer.WriteString("Type", fieldType.ToString());
 19130                writer.WriteString("Name", k);
 19131                writer.WritePropertyName("Value");
 19132                if (!FieldConverters.TryGetValue(fieldType!, out dynamic? fieldConverter))
 12133                {
 12134                    fieldConverter = JsonSerializerOptions.Default.GetConverter(fieldType);
 12135                    FieldConverters.Add(fieldType, fieldConverter);
 12136                }
 19137                fieldConverter.Write(writer, ((dynamic)v).Value, options);
 19138                writer.WriteString("Timestamp", v.Timestamp?.ToUniversalTime().ToString(Iso8601UtcDateFormat));
 19139                writer.WriteString("Quality", v.Quality?.ToString());
 19140                writer.WriteEndObject();
 32141            });
 13142            writer.WriteEndArray();
 13143        }
 144    }
 145}