///|
/// A UTF-8 text file. Paths are portable, workspace-relative paths.
pub(all) struct File {
path : String
content : String
} derive(Eq, Debug, ToJson, FromJson)
///|
/// Opaque files and symlinks appear in blocked; directories in folders.
pub(all) struct Snapshot {
files : Array[File]
folders : Array[String]
blocked : Array[String]
} derive(Eq, Debug, ToJson, FromJson)
///|
/// Supported kinds: create, write, move and trash (recoverable removal).
pub(all) struct Operation {
kind : String
path : String
to : String?
content : String?
} derive(Eq, Debug)
///|
pub(all) struct Issue {
code : String
path : String
message : String
} derive(Eq, Debug, ToJson, FromJson)
///|
/// A net path change; None means that the file is absent.
pub(all) struct Change {
path : String
before : String?
after : String?
} derive(Eq, Debug)
///|
/// An immutable-by-convention plan. Hosts must recompile untrusted plans.
pub(all) struct Plan {
schema : Int32
title : String
baseline : Snapshot
result : Snapshot
operations : Array[Operation]
changes : Array[Change]
issues : Array[Issue]
} derive(Eq, Debug, ToJson, FromJson)
///|
pub fn empty_snapshot() -> Snapshot {
{ files: [], folders: [], blocked: [], }
}
///|
pub fn Plan::ready(self : Plan) -> Bool {
self.issues.is_empty() && !self.changes.is_empty()
}
///|
fn file_map(snapshot : Snapshot) -> Map[String, String] {
let result = Map([])
for file in snapshot.files {
result[file.path] = file.content
}
result
}
///|
fn issue(code : String, path : String, message : String) -> Issue {
{ code, path, message, }
}
///|
fn copy_snapshot(snapshot : Snapshot) -> Snapshot {
{
files: snapshot.files.copy(),
folders: snapshot.folders.copy(),
blocked: snapshot.blocked.copy(),
}
}