use serde_json::{Map, Value};
use super::Verb;
use crate::envelope;
pub const LINEAGES: Verb = Verb {
word: "lineages",
params: &["workspace"],
flags: &[],
summary: "this workspace's config lineages, and the files each one holds",
detail: "The policy branches a conversation is born on, each with its tip \
commit and every file that commit holds. It is the listing a \
config read then indexes into: pick a lineage, pick a path, read \
the bytes. A workspace whose repository cannot be read says so \
outright rather than answering no lineages at all.",
};
pub const CONFIG: &str = "config";
const TARGET_FILE: &str = "file";
const TARGET_NAME: &str = "name";
const TARGET_LINEAGE: &str = "lineage";
const TARGET_PATH: &str = "path";
const TARGET_ORIGIN: &str = "origin";
const TEXT: &str = "text";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Where {
Brazen { workspace: String },
LitanyModels,
LitanyWorkflow { name: String },
Cadence,
Branch {
workspace: String,
lineage: String,
path: String,
},
}
impl Where {
pub fn target(&self) -> Value {
let mut map = Map::new();
let mut put = |key: &str, value: &str| {
map.insert(key.to_owned(), Value::String(value.to_owned()));
};
match self {
Self::Brazen { workspace } => {
put(TARGET_FILE, "brazen");
put(envelope::WORKSPACE, workspace);
}
Self::LitanyModels => put(TARGET_FILE, "litany-models"),
Self::LitanyWorkflow { name } => {
put(TARGET_FILE, "litany-workflow");
put(TARGET_NAME, name);
}
Self::Cadence => put(TARGET_FILE, "cadence"),
Self::Branch {
workspace,
lineage,
path,
} => {
put(TARGET_FILE, "branch");
put(envelope::WORKSPACE, workspace);
put(TARGET_LINEAGE, lineage);
put(TARGET_PATH, path);
put(TARGET_ORIGIN, "advance");
}
}
Value::Object(map)
}
pub fn label(&self) -> String {
match self {
Self::Brazen { .. } => "brazen".to_owned(),
Self::LitanyModels => "litany models".to_owned(),
Self::LitanyWorkflow { name } => format!("workflow {name}"),
Self::Cadence => "cadence".to_owned(),
Self::Branch { lineage, path, .. } => format!("{lineage}: {path}"),
}
}
pub fn addresses_a_workspace(&self) -> bool {
matches!(self, Self::Brazen { .. } | Self::Branch { .. })
}
}
pub fn lineages(workspace: String) -> Value {
LINEAGES.built(vec![workspace], &[])
}
pub fn config(at: &Where) -> Value {
addressed(at, None)
}
pub fn write(at: &Where, text: String) -> Value {
addressed(at, Some(text))
}
fn addressed(at: &Where, text: Option<String>) -> Value {
let mut map = Map::new();
map.insert(envelope::OP.to_owned(), Value::String(CONFIG.to_owned()));
map.insert(envelope::TARGET.to_owned(), at.target());
if let Some(text) = text {
map.insert(TEXT.to_owned(), Value::String(text));
}
Value::Object(map)
}
#[cfg(test)]
mod tests;