tools/code/common/WorkspaceApiSpecification.cs (168 lines of code) (raw):

using LanguageExt; using System; using System.Collections.Immutable; using System.IO; using System.Threading; using System.Threading.Tasks; namespace common; public abstract record WorkspaceApiSpecificationFile : ResourceFile { public required WorkspaceApiDirectory Parent { get; init; } public abstract ApiSpecification Specification { get; } public static WorkspaceApiSpecificationFile From(ApiSpecification specification, ApiName apiName, WorkspaceName workspaceName, ManagementServiceDirectory serviceDirectory) => specification switch { ApiSpecification.GraphQl => WorkspaceGraphQlSpecificationFile.From(apiName, workspaceName, serviceDirectory), ApiSpecification.Wadl => WorkspaceWadlSpecificationFile.From(apiName, workspaceName, serviceDirectory), ApiSpecification.Wsdl => WorkspaceWsdlSpecificationFile.From(apiName, workspaceName, serviceDirectory), ApiSpecification.OpenApi openApi => WorkspaceOpenApiSpecificationFile.From(openApi, apiName, workspaceName, serviceDirectory), _ => throw new NotImplementedException() }; public static async ValueTask<Option<WorkspaceApiSpecificationFile>> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) => await TryParse(file, getFileContents: async file => await file.ReadAsBinaryData(cancellationToken), serviceDirectory, cancellationToken); public static async ValueTask<Option<WorkspaceApiSpecificationFile>> TryParse(FileInfo? file, Func<FileInfo, ValueTask<BinaryData>> getFileContents, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) { var tryParseGraphQl = () => (from specificationFile in WorkspaceGraphQlSpecificationFile.TryParse(file, serviceDirectory) select specificationFile as WorkspaceApiSpecificationFile).AsTask(); var tryParseWadl = () => (from specificationFile in WorkspaceWadlSpecificationFile.TryParse(file, serviceDirectory) select specificationFile as WorkspaceApiSpecificationFile).AsTask(); var tryParseWsdl = () => (from specificationFile in WorkspaceWsdlSpecificationFile.TryParse(file, serviceDirectory) select specificationFile as WorkspaceApiSpecificationFile).AsTask(); var tryParseOpenApi = async () => from specificationFile in await WorkspaceOpenApiSpecificationFile.TryParse(file, getFileContents, serviceDirectory, cancellationToken) select specificationFile as WorkspaceApiSpecificationFile; return await ImmutableArray.Create(tryParseGraphQl, tryParseWadl, tryParseWsdl, tryParseOpenApi) .Pick(async (f, cancellationToken) => await f(), cancellationToken); } } public sealed record WorkspaceGraphQlSpecificationFile : WorkspaceApiSpecificationFile { public override ApiSpecification Specification { get; } = new ApiSpecification.GraphQl(); public static string Name => "specification.graphql"; protected override FileInfo Value => new(Path.Combine(Parent.ToDirectoryInfo().FullName, Name)); public static WorkspaceGraphQlSpecificationFile From(ApiName apiName, WorkspaceName workspaceName, ManagementServiceDirectory serviceDirectory) => new() { Parent = WorkspaceApiDirectory.From(apiName, workspaceName, serviceDirectory) }; public static Option<WorkspaceGraphQlSpecificationFile> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory) => file is not null && file.Name == Name ? from parent in WorkspaceApiDirectory.TryParse(file.Directory, serviceDirectory) select new WorkspaceGraphQlSpecificationFile { Parent = parent } : Option<WorkspaceGraphQlSpecificationFile>.None; } public sealed record WorkspaceWadlSpecificationFile : WorkspaceApiSpecificationFile { public override ApiSpecification Specification { get; } = new ApiSpecification.Wadl(); public static string Name => "specification.wadl"; protected override FileInfo Value => new(Path.Combine(Parent.ToDirectoryInfo().FullName, Name)); public static WorkspaceWadlSpecificationFile From(ApiName apiName, WorkspaceName workspaceName, ManagementServiceDirectory serviceDirectory) => new() { Parent = WorkspaceApiDirectory.From(apiName, workspaceName, serviceDirectory) }; public static Option<WorkspaceWadlSpecificationFile> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory) => file is not null && file.Name == Name ? from parent in WorkspaceApiDirectory.TryParse(file.Directory, serviceDirectory) select new WorkspaceWadlSpecificationFile { Parent = parent } : Option<WorkspaceWadlSpecificationFile>.None; } public sealed record WorkspaceWsdlSpecificationFile : WorkspaceApiSpecificationFile { public override ApiSpecification Specification { get; } = new ApiSpecification.Wsdl(); public static string Name => "specification.wsdl"; protected override FileInfo Value => new(Path.Combine(Parent.ToDirectoryInfo().FullName, Name)); public static WorkspaceWsdlSpecificationFile From(ApiName apiName, WorkspaceName workspaceName, ManagementServiceDirectory serviceDirectory) => new() { Parent = WorkspaceApiDirectory.From(apiName, workspaceName, serviceDirectory) }; public static Option<WorkspaceWsdlSpecificationFile> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory) => file is not null && file.Name == Name ? from parent in WorkspaceApiDirectory.TryParse(file.Directory, serviceDirectory) select new WorkspaceWsdlSpecificationFile { Parent = parent } : Option<WorkspaceWsdlSpecificationFile>.None; } public abstract record WorkspaceOpenApiSpecificationFile : WorkspaceApiSpecificationFile { public abstract OpenApiFormat Format { get; } public required OpenApiVersion Version { get; init; } public static WorkspaceOpenApiSpecificationFile From(ApiSpecification.OpenApi openApi, ApiName apiName, WorkspaceName workspaceName, ManagementServiceDirectory serviceDirectory) => openApi.Format switch { OpenApiFormat.Json => JsonWorkspaceOpenApiSpecificationFile.From(openApi.Version, apiName, workspaceName, serviceDirectory), OpenApiFormat.Yaml => YamlWorkspaceOpenApiSpecificationFile.From(openApi.Version, apiName, workspaceName, serviceDirectory), _ => throw new NotImplementedException() }; public static new async ValueTask<Option<WorkspaceOpenApiSpecificationFile>> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) => await TryParse(file, getFileContents: async file => await file.ReadAsBinaryData(cancellationToken), serviceDirectory, cancellationToken); public static new async ValueTask<Option<WorkspaceOpenApiSpecificationFile>> TryParse(FileInfo? file, Func<FileInfo, ValueTask<BinaryData>> getFileContents, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) { var tryParseYaml = async () => from yaml in await YamlWorkspaceOpenApiSpecificationFile.TryParse(file, getFileContents, serviceDirectory, cancellationToken) select yaml as WorkspaceOpenApiSpecificationFile; var tryParseJson = async () => from json in await JsonWorkspaceOpenApiSpecificationFile.TryParse(file, getFileContents, serviceDirectory, cancellationToken) select json as WorkspaceOpenApiSpecificationFile; return await ImmutableArray.Create(tryParseYaml, tryParseJson) .Pick(async (f, cancellationToken) => await f(), cancellationToken); } } public sealed record YamlWorkspaceOpenApiSpecificationFile : WorkspaceOpenApiSpecificationFile { public override OpenApiFormat Format { get; } = new OpenApiFormat.Yaml(); public override ApiSpecification Specification => new ApiSpecification.OpenApi { Format = Format, Version = Version }; public static string Name { get; } = "specification.yaml"; protected override FileInfo Value => new(Path.Combine(Parent.ToDirectoryInfo().FullName, Name)); public static YamlWorkspaceOpenApiSpecificationFile From(OpenApiVersion version, ApiName apiName, WorkspaceName workspaceName, ManagementServiceDirectory serviceDirectory) => new() { Parent = WorkspaceApiDirectory.From(apiName, workspaceName, serviceDirectory), Version = version }; public static new async ValueTask<Option<YamlWorkspaceOpenApiSpecificationFile>> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) => await TryParse(file, getFileContents: async file => await file.ReadAsBinaryData(cancellationToken), serviceDirectory, cancellationToken); public static new async ValueTask<Option<YamlWorkspaceOpenApiSpecificationFile>> TryParse(FileInfo? file, Func<FileInfo, ValueTask<BinaryData>> getFileContents, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) => file is not null && file.Name == Name ? await WorkspaceApiDirectory.TryParse(file.Directory, serviceDirectory) .BindTask(async parent => from version in await OpenApiVersion.TryParse(await getFileContents(file), cancellationToken) select new YamlWorkspaceOpenApiSpecificationFile { Parent = parent, Version = version }) : Option<YamlWorkspaceOpenApiSpecificationFile>.None; } public sealed record JsonWorkspaceOpenApiSpecificationFile : WorkspaceOpenApiSpecificationFile { public override OpenApiFormat Format { get; } = new OpenApiFormat.Json(); public override ApiSpecification Specification => new ApiSpecification.OpenApi { Format = Format, Version = Version }; public static string Name { get; } = "specification.json"; protected override FileInfo Value => new(Path.Combine(Parent.ToDirectoryInfo().FullName, Name)); public static JsonWorkspaceOpenApiSpecificationFile From(OpenApiVersion version, ApiName apiName, WorkspaceName workspaceName, ManagementServiceDirectory serviceDirectory) => new() { Parent = WorkspaceApiDirectory.From(apiName, workspaceName, serviceDirectory), Version = version }; public static new async ValueTask<Option<JsonWorkspaceOpenApiSpecificationFile>> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) => await TryParse(file, getFileContents: async file => await file.ReadAsBinaryData(cancellationToken), serviceDirectory, cancellationToken); public static new async ValueTask<Option<JsonWorkspaceOpenApiSpecificationFile>> TryParse(FileInfo? file, Func<FileInfo, ValueTask<BinaryData>> getFileContents, ManagementServiceDirectory serviceDirectory, CancellationToken cancellationToken) => file is not null && file.Name == Name ? await WorkspaceApiDirectory.TryParse(file.Directory, serviceDirectory) .BindTask(async parent => from version in await OpenApiVersion.TryParse(await getFileContents(file), cancellationToken) select new JsonWorkspaceOpenApiSpecificationFile { Parent = parent, Version = version }) : Option<JsonWorkspaceOpenApiSpecificationFile>.None; }