/*
* Copyright (c) 2023 Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see .
*/
using Newtonsoft.Json;
using ProtonVPN.Serialization.Contracts;
using ProtonVPN.Serialization.Contracts.Json;
namespace ProtonVPN.Serialization.Json;
public class ContractDeserializationJsonConverter : JsonConverter
{
private readonly IDictionary _interfaceImplementations;
public ContractDeserializationJsonConverter(IEnumerable jsonContractDeserializers)
{
IEnumerable interfaceImplementations = jsonContractDeserializers.SelectMany(jcd => jcd.Get());
CheckIfEachInterfaceHasOnlyOneImplementation(interfaceImplementations);
_interfaceImplementations = interfaceImplementations.ToDictionary(ii => ii.InterfaceType, ii => ii.ImplementationType);
}
private void CheckIfEachInterfaceHasOnlyOneImplementation(IEnumerable interfaceImplementations)
{
var highestCountInterface = interfaceImplementations
.GroupBy(ii => ii.InterfaceType)
.Select(group => new { InterfaceType = group.Key, Count = group.Count() })
.OrderByDescending(o => o.Count)
.FirstOrDefault();
if (highestCountInterface is not null && highestCountInterface.Count > 1)
{
throw new Exception($"There is more than a single JSON deserialization implementation" +
$"for the contract {highestCountInterface.InterfaceType.FullName}.");
}
}
public override bool CanConvert(Type objectType)
{
return _interfaceImplementations.ContainsKey(objectType);
}
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, Newtonsoft.Json.JsonSerializer serializer)
{
return serializer.Deserialize(reader, _interfaceImplementations[objectType]);
}
public override void WriteJson(JsonWriter writer, object? value, Newtonsoft.Json.JsonSerializer serializer)
{
throw new NotImplementedException("Doesn't need to be implemented.");
}
}