MetaforceInstaller/MetaforceInstaller.Cloud/Implementations/MailRu/DTO/CloudObjectResponse.cs

181 lines
No EOL
4.8 KiB
C#

using System.Text.Json;
using System.Text.Json.Serialization;
namespace MetaforceInstaller.Cloud.Implementations.MailRu.DTO;
public sealed class CloudObjectsResponse
{
[JsonPropertyName("count")]
public CountInfo? Count { get; init; }
[JsonPropertyName("name")]
public string? Name { get; init; }
[JsonPropertyName("weblink")]
public string? WebLink { get; init; }
[JsonPropertyName("size")]
public long? Size { get; init; }
[JsonPropertyName("rev")]
public long? Rev { get; init; }
[JsonPropertyName("kind")]
public string? Kind { get; init; }
[JsonPropertyName("type")]
public string? Type { get; init; }
[JsonPropertyName("public")]
public PublicInfo? Public { get; init; }
[JsonPropertyName("list")]
public List<CloudObjectBase>? List { get; init; }
[JsonPropertyName("owner")]
public OwnerInfo? Owner { get; init; }
}
public sealed class CountInfo
{
[JsonPropertyName("folders")]
public int? Folders { get; init; }
[JsonPropertyName("files")]
public int? Files { get; init; }
}
public sealed class PublicInfo
{
[JsonPropertyName("type")]
public string? Type { get; init; }
[JsonPropertyName("name")]
public string? Name { get; init; }
[JsonPropertyName("id")]
public string? Id { get; init; }
[JsonPropertyName("ctime")]
public long? CTime { get; init; }
[JsonPropertyName("views")]
public long? Views { get; init; }
[JsonPropertyName("downloads")]
public long? Downloads { get; init; }
}
public sealed class OwnerInfo
{
[JsonPropertyName("email")]
public string? Email { get; init; }
[JsonPropertyName("user_flags")]
public UserFlags? UserFlags { get; init; }
}
public sealed class UserFlags
{
[JsonPropertyName("PAID_ACCOUNT")]
public bool? PaidAccount { get; init; }
}
/// <summary>
/// Базовый тип элемента из "list". Конкретный тип выбирается по полю "type".
/// </summary>
[JsonConverter(typeof(CloudObjectJsonConverter))]
public abstract class CloudObjectBase
{
[JsonPropertyName("name")]
public string? Name { get; init; }
[JsonPropertyName("weblink")]
public string? WebLink { get; init; }
[JsonPropertyName("size")]
public long? Size { get; init; }
[JsonPropertyName("kind")]
public string? Kind { get; init; }
[JsonPropertyName("type")]
public string? Type { get; init; }
}
public sealed class CloudFolderObject : CloudObjectBase
{
[JsonPropertyName("count")]
public CountInfo? Count { get; init; }
[JsonPropertyName("rev")]
public long? Rev { get; init; }
}
public sealed class CloudFileObject : CloudObjectBase
{
[JsonPropertyName("mtime")]
public long? MTime { get; init; }
[JsonPropertyName("hash")]
public string? Hash { get; init; }
}
public sealed class ZipWebLinkRequest
{
[JsonPropertyName("x-email")]
public string XEmail { get; init; }
[JsonPropertyName("weblink_list")]
public IReadOnlyList<string> WeblinkList { get; init; }
[JsonPropertyName("name")]
public string Name { get; init; }
}
public sealed class ZipWebLinkResponse
{
[JsonPropertyName("key")]
public string Key { get; init; }
}
/// <summary>
/// Конвертер, который смотрит на поле "type" и десериализует в CloudFolderObject или CloudFileObject.
/// </summary>
public sealed class CloudObjectJsonConverter : JsonConverter<CloudObjectBase>
{
public override CloudObjectBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var doc = JsonDocument.ParseValue(ref reader);
var root = doc.RootElement;
if (!root.TryGetProperty("type", out var typeProp))
throw new JsonException("Missing required property 'type' for cloud object.");
var type = typeProp.GetString();
return type switch
{
"folder" => root.Deserialize<CloudFolderObject>(options)
?? throw new JsonException("Failed to deserialize folder object."),
"file" => root.Deserialize<CloudFileObject>(options)
?? throw new JsonException("Failed to deserialize file object."),
_ => throw new JsonException($"Unknown cloud object type '{type}'.")
};
}
public override void Write(Utf8JsonWriter writer, CloudObjectBase value, JsonSerializerOptions options)
{
switch (value)
{
case CloudFolderObject folder:
JsonSerializer.Serialize(writer, folder, options);
break;
case CloudFileObject file:
JsonSerializer.Serialize(writer, file, options);
break;
default:
throw new JsonException($"Unknown runtime type '{value.GetType().Name}'.");
}
}
}