← All source files

V9 / fa079a940f8f

WorkspaceRequestExtensions.cs

Lilith/Core/Workspace/Extensions/WorkspaceRequestExtensions.cs

Unchanged from the preceding version
CS

namespace Lilith.Core.Workspace.Extensions;

internal static class WorkspaceRequestExtensions
{
    internal static string Snapshot(this WorkspaceRequest request, WorkspaceOptions options) => request.Operation switch
    {
        "move" => options.ResolvePath(request.Path).ComputeSignature() + "|" + options.ResolvePath(request.Destination).ComputeSignature(),
        "restore" => Path.Combine(options.GetMetadataPath("bin", request.BinId), "item").ComputeSignature() + "|" + options.ResolvePath(options.GetOriginalBinPath(request.BinId)).ComputeSignature(),
        _ => WorkspaceFileSystemExtensions.ComputeSignature(options.ResolvePath(request.Path))
    };

    internal static void ValidateMutation(this WorkspaceRequest request, WorkspaceOptions options)
    {
        string path = request.Operation == "restore" ? options.ResolvePath(options.GetOriginalBinPath(request.BinId)) : options.ResolvePath(request.Path);
        switch (request.Operation)
        {
            case "save":
                if (!path.IsTextFile()) throw new ArgumentException("Save creates UTF-8 text documents: .md, .txt, .json, .csv, .xml or .html.");
                if (request.Content.Length > 20000 || Directory.Exists(path)) throw new ArgumentException("Save supports at most 20000 text characters and cannot replace a folder.");
                RequireParent(path);
                break;
            case "mkdir":
                if (File.Exists(path) || Directory.Exists(path)) throw new IOException("Folder target already exists.");
                RequireParent(path);
                break;
            case "move":
                RequireSource(path);
                string destination = options.ResolvePath(request.Destination);
                if (File.Exists(destination) || Directory.Exists(destination) || !Directory.Exists(Path.GetDirectoryName(destination)) ||
                    destination.StartsWith(path + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
                    throw new IOException("Move destination is occupied, inside the source, or has no parent folder.");
                break;
            case "bin":
                RequireSource(path);
                break;
            case "restore":
                if (File.Exists(path) || Directory.Exists(path) || !Directory.Exists(Path.GetDirectoryName(path)))
                    throw new IOException("Restore destination is occupied or its parent folder is missing.");
                break;
            default:
                throw new ArgumentException("Unknown workspace operation.");
        }
    }

    private static void RequireParent(string path)
    {
        if (!Directory.Exists(Path.GetDirectoryName(path))) throw new IOException("Create the parent folder first.");
    }

    private static void RequireSource(string path)
    {
        if (!File.Exists(path) && !Directory.Exists(path)) throw new IOException("Source not found.");
        _ = path.ComputeSignature();
    }
}