V14 / fad4e1a110e5
WorkspaceRequestExtensions.cs
Lilith/Core/Workspace/Extensions/WorkspaceRequestExtensions.cs
Unchanged from the preceding versionCS
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 "project_update":
if (!Directory.Exists(path)) throw new IOException("Project update requires an existing project.");
request.ReadProjectUpdate(options);
break;
case "project_create":
if (File.Exists(path) || Directory.Exists(path)) throw new IOException("Project target already exists. V11 creates new projects only.");
RequireParent(path);
request.ReadProjectBundle(options);
break;
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();
}
}