laatzen/Common/CommonConsole/ConfigurationJson.cs
2023-09-04 12:32:29 +02:00

331 lines
7.8 KiB
C#

namespace CommonConsole
{
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
public class ConfigurationJson : Dictionary<string, Section>
{
public Section this[byte id]
=> this.Values.FirstOrDefault(x => x.Id == id)
?? new Section();
public new Section this[string key]
{
get
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Section name should not be null or white space!");
}
if (!this.TryGetValue(key, out var section))
{
section = new Section();
this[key] = section;
}
return section;
}
set
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Section name should not be null or white space!");
}
this[key] = value;
}
}
[OnDeserialized]
internal void OnDeserialized(StreamingContext _)
{
foreach (var kvp in this)
{
kvp.Value.Name = kvp.Key;
}
}
}
public class Section
{
public byte Id { get; set; }
[JsonIgnore]
public string Name { get; internal set; }
public Version Version { get; set; }
public Registers Registers { get; set; }
public Status Status { get; set; }
public Register this[string key]
{
get
{
if (this.Registers is null)
{
return new Register();
}
return this.Registers[key];
}
set
{
if (this.Registers != null)
{
this.Registers[key] = value;
}
}
}
public Register this[byte id]
=> this.Registers?[id] ?? new Register();
}
public class Version
{
public int? First { get; set; }
public int? Last { get; set; }
public bool InVersion(int version)
{
if (this.First is null && this.Last is null)
{
return false;
}
return (this.First ?? int.MinValue) <= version && (this.First ?? int.MaxValue) >= version;
}
}
public class Registers : Dictionary<string, Register>
{
public Register this[byte id]
=> this.Values.FirstOrDefault(x => x.Id == id)
?? new Register();
public new Register this[string key]
{
get
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Register name should not be null or white space!");
}
if (!this.TryGetValue(key, out var register))
{
register = new Register();
this[key] = register;
}
return register;
}
set
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Register name should not be null or white space!");
}
this[key] = value;
}
}
[OnDeserialized]
internal void OnDeserialized(StreamingContext _)
{
foreach (var kvp in this)
{
kvp.Value.Name = kvp.Key;
}
}
}
public class Register
{
public byte Id { get; set; }
[JsonIgnore]
public string Name { get; internal set; }
public Details Details { get; set; }
public Detail this[int version]
=> this.Details?[version] ?? new Detail();
}
public class Details : List<Detail>
{
public new Detail this[int version]
=> this.FirstOrDefault(x => x.Version?.InVersion(version) ?? false)
?? new Detail();
}
public class Detail
{
public string Type { get; set; }
public string StaticType { get; set; }
public Privilege Privilege { get; set; }
public Version Version { get; set; }
public Values Values { get; set; }
[JsonIgnore]
public Value Value { get; set; }
[JsonIgnore]
public Unit Unit { get; set; }
public object this[string property]
{
get
{
if (property == nameof(Value))
{
return this.Value?.Current;
}
else if (property == nameof(Unit))
{
return this.Unit?.Base;
}
return null;
}
set
{
if (property == nameof(Value) && this.Value != null)
{
this.Value.Current = value;
}
else if (property == nameof(Unit) && this.Unit != null)
{
this.Unit.Base = value;
}
}
}
[OnDeserialized]
internal void OnDeserialized(StreamingContext _)
{
try
{
var valueType = System.Type.GetType(
typeName: $"CommonConsole.{this.Type}",
throwOnError: false,
ignoreCase: true);
var instance = Activator.CreateInstance(valueType);
if (instance is Value value)
{
if (this.Values != null)
{
value.Current = this.Values.Default;
}
this.Value = value;
}
}
catch (Exception e)
{
// TODO: Handle exceptions.
}
}
}
public class Values
{
public object Default { get; set; }
public object Minimum { get; set; }
public object Maximum { get; set; }
}
public class Privilege
{
public Access Lvl1 { get; set; }
public Access Lvl2 { get; set; }
public Access Lvl3 { get; set; }
public Access Lvl4 { get; set; }
public Access Lvl5 { get; set; }
public Access Lvl6 { get; set; }
public Access Lvl7 { get; set; }
public Access Lvl8 { get; set; }
}
public enum Access : byte
{
NS,
NA,
RO,
WO,
RW
}
public class Status : Dictionary<string, StatusInfo>
{
}
public class StatusInfo
{
public byte Id { get; set; }
public string Action { get; set; }
public string Description { get; set; }
}
public class AccessConverter : JsonConverter
{
public override bool CanConvert(Type type)
=> type == typeof(Access)
|| type == typeof(Access?);
public override object ReadJson(JsonReader reader, Type _, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
var value = serializer.Deserialize<string>(reader);
if (Enum.TryParse(value, true, out Access access))
{
return access;
}
return default(Access);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer _1)
{
if (value != null)
{
writer.WriteValue($"{value}");
}
}
}
}