< 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_18869653307
Line coverage
92%
Covered lines: 73
Uncovered lines: 6
Coverable lines: 79
Total lines: 145
Line coverage: 92.4%
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.88%
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.Engine.Exceptions;
 3using System.Globalization;
 4using System.Text.Json;
 5using System.Text.Json.Serialization;
 6
 7namespace pva.SuperV.Engine.JsonConverters
 8{
 9    /// <summary>
 10    /// Json converter for an instance.
 11    /// </summary>
 12    /// <seealso cref="JsonConverter&lt;IInstance&gt;" />
 13    public class InstanceJsonConverter : JsonConverter<IInstance>
 14    {
 15        /// <summary>
 16        /// The iso8601 UTC date format used to save/load date times.
 17        /// </summary>
 18        private const string Iso8601UtcDateFormat = "yyyy-MM-ddTHH:mm:ss.sssZ";
 19
 20        /// <summary>
 21        /// The field converters
 22        /// </summary>
 223        private static readonly Dictionary<Type, dynamic> FieldConverters = [];
 24
 25        /// <summary>
 26        /// Gets or sets the loaded project. Set before deserializing.
 27        /// </summary>
 28        /// <value>
 29        /// The loaded project.
 30        /// </value>
 4331        public static RunnableProject LoadedProject { get; set; } = null!;
 32
 33        /// <summary>
 34        /// Reads and converts the JSON to type.
 35        /// </summary>
 36        /// <param name="reader">The reader.</param>
 37        /// <param name="typeToConvert">The type to convert.</param>
 38        /// <param name="options">An object that specifies serialization options to use.</param>
 39        /// <returns>
 40        /// The converted value.
 41        /// </returns>
 42        /// <exception cref="JsonException"></exception>
 43        /// <exception cref="InstanceCreationException"></exception>
 44        public override IInstance? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
 1445        {
 1446            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.StartObject, false);
 1447            string? instanceClass = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Class");
 1448            string? instanceName = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Name");
 1449            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.PropertyName);
 50            try
 1451            {
 1452                IInstance? instance = LoadedProject.CreateInstance(instanceClass!, instanceName!);
 1453                DeserializeFields(ref reader, options, instance!);
 1454                return instance;
 55            }
 056            catch (Exception ex)
 057            {
 058                throw new InstanceCreationException(instanceName!, instanceClass!, ex);
 59            }
 1460        }
 61
 62        private static void DeserializeFields(ref Utf8JsonReader reader, JsonSerializerOptions options, IInstance instan
 1463        {
 1464            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.StartArray);
 3465            while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
 2066            {
 2067                reader = DeserializeField(reader, options, instance);
 2068            }
 1469            JsonHelpers.ReadTokenType(ref reader, JsonTokenType.EndObject);
 1470        }
 71
 72        private static Utf8JsonReader DeserializeField(Utf8JsonReader reader, JsonSerializerOptions options, IInstance i
 2073        {
 2074            if (reader.TokenType == JsonTokenType.StartObject)
 2075            {
 2076                string? fieldTypeString = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Type");
 2077                string? fieldName = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Name");
 78
 2079                reader.Read();
 2080                string? readPropertyName = reader.GetString();
 2081                if (readPropertyName == "Value")
 2082                {
 2083                    Type? fieldType = Type.GetType(fieldTypeString!);
 2084                    dynamic? fieldValue = JsonSerializer.Deserialize(ref reader, fieldType!, options);
 2085                    string? valueTimestampStr = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Timestamp");
 2086                    _ = DateTime.TryParseExact(valueTimestampStr, Iso8601UtcDateFormat, CultureInfo.InvariantCulture, Da
 2087                        out DateTime valueTimestamp);
 2088                    string? valueQualityStr = JsonHelpers.GetStringPropertyFromUtfReader(ref reader, "Quality");
 2089                    _ = Enum.TryParse(valueQualityStr, out QualityLevel valueQuality);
 90
 2091                    IField? field = (instance as Instance)?.GetField(fieldName!);
 2092                    dynamic? dynamicField = field;
 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}