85 lines
2.5 KiB
C#
85 lines
2.5 KiB
C#
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace EorzeaVotes.Model;
|
|
|
|
[JsonConverter(typeof(QuestionConverter))]
|
|
internal interface IQuestion {
|
|
/// <summary>
|
|
/// The question's unique ID.
|
|
/// </summary>
|
|
public Guid Id { get; init; }
|
|
|
|
/// <summary>
|
|
/// The date at which the question was published.
|
|
/// </summary>
|
|
public string Date { get; init; }
|
|
|
|
/// <summary>
|
|
/// If the question is currently the active question for voting.
|
|
/// </summary>
|
|
public bool Active { get; init; }
|
|
|
|
/// <summary>
|
|
/// The body text of the question.
|
|
/// </summary>
|
|
public string Text { get; init; }
|
|
|
|
/// <summary>
|
|
/// A list of possible answers to the question.
|
|
/// </summary>
|
|
public string[] Answers { get; init; }
|
|
|
|
/// <summary>
|
|
/// The name given by the person who suggested this question.
|
|
/// </summary>
|
|
public string? Suggester { get; init; }
|
|
}
|
|
|
|
internal class QuestionConverter : JsonConverter {
|
|
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) {
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) {
|
|
if (reader.TokenType == JsonToken.Null) {
|
|
return null;
|
|
}
|
|
|
|
// load as object
|
|
var obj = JObject.Load(reader);
|
|
|
|
// get the type key from the object
|
|
var typeToken = obj.GetValue("type");
|
|
if (typeToken == null) {
|
|
throw new Exception("missing type key");
|
|
}
|
|
|
|
// parse as a string
|
|
var type = typeToken.Value<string>();
|
|
|
|
// determine the type to deserialise
|
|
var actualType = type switch {
|
|
"basic" => typeof(BasicQuestion),
|
|
"full" => typeof(FullQuestion),
|
|
_ => throw new Exception("invalid question type"),
|
|
};
|
|
|
|
// resolve the contract and create a default question
|
|
var contract = serializer.ContractResolver.ResolveContract(actualType);
|
|
var question = existingValue ?? contract.DefaultCreator!();
|
|
|
|
// populate the default question
|
|
using var subReader = obj.CreateReader();
|
|
serializer.Populate(subReader, question);
|
|
|
|
return question;
|
|
}
|
|
|
|
public override bool CanConvert(Type objectType) {
|
|
return objectType == typeof(IQuestion)
|
|
|| objectType == typeof(BasicQuestion)
|
|
|| objectType == typeof(FullQuestion);
|
|
}
|
|
}
|