tools/code/common/ProductApi.cs (138 lines of code) (raw):

using Azure.Core.Pipeline; using Flurl; using LanguageExt; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace common; public sealed record ProductApisUri : ResourceUri { public required ProductUri Parent { get; init; } private static string PathSegment { get; } = "apis"; protected override Uri Value => Parent.ToUri().AppendPathSegment(PathSegment).ToUri(); public static ProductApisUri From(ProductName name, ManagementServiceUri serviceUri) => new() { Parent = ProductUri.From(name, serviceUri) }; } public sealed record ProductApiUri : ResourceUri { public required ProductApisUri Parent { get; init; } public required ApiName Name { get; init; } protected override Uri Value => Parent.ToUri().AppendPathSegment(Name.ToString()).ToUri(); public static ProductApiUri From(ApiName name, ProductName productName, ManagementServiceUri serviceUri) => new() { Parent = ProductApisUri.From(productName, serviceUri), Name = name }; } public sealed record ProductApisDirectory : ResourceDirectory { public required ProductDirectory Parent { get; init; } private static string Name { get; } = "apis"; protected override DirectoryInfo Value => Parent.ToDirectoryInfo().GetChildDirectory(Name); public static ProductApisDirectory From(ProductName name, ManagementServiceDirectory serviceDirectory) => new() { Parent = ProductDirectory.From(name, serviceDirectory) }; public static Option<ProductApisDirectory> TryParse(DirectoryInfo? directory, ManagementServiceDirectory serviceDirectory) => IsDirectoryNameValid(directory) ? from parent in ProductDirectory.TryParse(directory.Parent, serviceDirectory) select new ProductApisDirectory { Parent = parent } : Option<ProductApisDirectory>.None; internal static bool IsDirectoryNameValid([NotNullWhen(true)] DirectoryInfo? directory) => directory?.Name == Name; } public sealed record ProductApiDirectory : ResourceDirectory { public required ProductApisDirectory Parent { get; init; } public required ApiName Name { get; init; } protected override DirectoryInfo Value => Parent.ToDirectoryInfo().GetChildDirectory(Name.ToString()); public static ProductApiDirectory From(ApiName name, ProductName productName, ManagementServiceDirectory serviceDirectory) => new() { Parent = ProductApisDirectory.From(productName, serviceDirectory), Name = name }; public static Option<ProductApiDirectory> TryParse(DirectoryInfo? directory, ManagementServiceDirectory serviceDirectory) => from name in TryParseProductApiName(directory) from parent in ProductApisDirectory.TryParse(directory?.Parent, serviceDirectory) select new ProductApiDirectory { Parent = parent, Name = name }; internal static Option<ApiName> TryParseProductApiName(DirectoryInfo? directory) => string.IsNullOrWhiteSpace(directory?.Name) ? Option<ApiName>.None : ApiName.From(directory.Name); } public sealed record ProductApiInformationFile : ResourceFile { public required ProductApiDirectory Parent { get; init; } private static string Name { get; } = "productApiInformation.json"; protected override FileInfo Value => Parent.ToDirectoryInfo().GetChildFile(Name); public static ProductApiInformationFile From(ApiName name, ProductName productName, ManagementServiceDirectory serviceDirectory) => new() { Parent = ProductApiDirectory.From(name, productName, serviceDirectory) }; public static Option<ProductApiInformationFile> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory) => IsFileNameValid(file) ? from parent in ProductApiDirectory.TryParse(file.Directory, serviceDirectory) select new ProductApiInformationFile { Parent = parent } : Option<ProductApiInformationFile>.None; internal static bool IsFileNameValid([NotNullWhen(true)] FileInfo? file) => file?.Name == Name; } public sealed record ProductApiDto { public static ProductApiDto Instance { get; } = new(); } public static class ProductApiModule { public static IAsyncEnumerable<ApiName> ListNames(this ProductApisUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) => pipeline.ListJsonObjects(uri.ToUri(), cancellationToken) .Select(jsonObject => jsonObject.GetStringProperty("name")) .Select(ApiName.From) .Where(ApiName.IsNotRevisioned); public static IAsyncEnumerable<(ApiName Name, ProductApiDto Dto)> List(this ProductApisUri productApisUri, HttpPipeline pipeline, CancellationToken cancellationToken) => productApisUri.ListNames(pipeline, cancellationToken) .Select(name => (name, ProductApiDto.Instance)); public static async ValueTask Delete(this ProductApiUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) => await pipeline.DeleteResource(uri.ToUri(), waitForCompletion: true, cancellationToken); public static async ValueTask PutDto(this ProductApiUri uri, ProductApiDto dto, HttpPipeline pipeline, CancellationToken cancellationToken) { var content = BinaryData.FromObjectAsJson(dto); await pipeline.PutContent(uri.ToUri(), content, cancellationToken); } public static IEnumerable<ProductApiInformationFile> ListInformationFiles(ProductName productName, ManagementServiceDirectory serviceDirectory) => ListProductApisDirectories(productName, serviceDirectory) .SelectMany(ListProductApiDirectories) .Select(directory => ProductApiInformationFile.From(directory.Name, productName, serviceDirectory)); private static IEnumerable<ProductApisDirectory> ListProductApisDirectories(ProductName productName, ManagementServiceDirectory serviceDirectory) => ProductDirectory.From(productName, serviceDirectory) .ToDirectoryInfo() .ListDirectories("*") .Where(ProductApisDirectory.IsDirectoryNameValid) .Select(_ => ProductApisDirectory.From(productName, serviceDirectory)); private static IEnumerable<ProductApiDirectory> ListProductApiDirectories(ProductApisDirectory productApisDirectory) => productApisDirectory.ToDirectoryInfo() .ListDirectories("*") .Choose(directory => from name in ProductApiDirectory.TryParseProductApiName(directory) select new ProductApiDirectory { Name = name, Parent = productApisDirectory }); public static async ValueTask WriteDto(this ProductApiInformationFile file, ProductApiDto dto, CancellationToken cancellationToken) { var content = BinaryData.FromObjectAsJson(dto, JsonObjectExtensions.SerializerOptions); await file.ToFileInfo().OverwriteWithBinaryData(content, cancellationToken); } public static async ValueTask<ProductApiDto> ReadDto(this ProductApiInformationFile file, CancellationToken cancellationToken) { var content = await file.ToFileInfo().ReadAsBinaryData(cancellationToken); return content.ToObjectFromJson<ProductApiDto>(); } }