mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-29 12:46:53 -06:00
Engine: an empty ids names nothing; states.create and conveyor.collect honour id
named_targets reads ids/id as targets() does, so {ids: [], id} can't
pass the gate and then run on nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7e69c82b89
commit
f1767a84fd
@@ -117,7 +117,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
ok()
|
||||
}),
|
||||
cmd!(noundo "conveyor.collect", "Collect", [], None, "{ids? (default: the selection)} — each object onto the Content Collector conveyor → {count}", has_selection, |s, p| {
|
||||
let ids = super::ids_param(p, "ids").unwrap_or_else(|| s.active().map(|d| d.selection.items.clone()).unwrap_or_default());
|
||||
let ids = super::targets(s, p)?;
|
||||
let keep = s.active().map(|d| d.selection.clone());
|
||||
for id in ids {
|
||||
let name = s.doc()?.doc.item(id).map(|it| it.default_label().trim_matches(|c| c == '<' || c == '>').to_string()).unwrap_or_default();
|
||||
|
||||
@@ -269,8 +269,9 @@ pub(crate) fn named_targets(spec: &CommandSpec, p: &Value) -> Option<Vec<ItemId>
|
||||
if !spec.params.split(|c: char| !c.is_ascii_alphanumeric()).any(|w| w == "ids") {
|
||||
return None;
|
||||
}
|
||||
if let Some(ids) = ids_param(p, "ids").filter(|v| !v.is_empty()) {
|
||||
return Some(ids);
|
||||
// As `targets` reads them: `ids`, when given, wins over `id` (an empty list names nothing).
|
||||
if let Some(ids) = ids_param(p, "ids") {
|
||||
return (!ids.is_empty()).then_some(ids);
|
||||
}
|
||||
id_param(p, "id").map(|i| vec![i])
|
||||
}
|
||||
|
||||
@@ -2413,5 +2413,11 @@ mod named_target_tests {
|
||||
let e = s.execute("object.textFrameOptions", &json!({"ids": [99999], "columns": 1})).unwrap_err().to_string();
|
||||
assert!(e.contains("no object with id 99999"), "{e}");
|
||||
assert_eq!(columns(&s), Some(2));
|
||||
// An empty `ids` names nothing (as `targets` reads it), even beside an `id`.
|
||||
let e = s.execute("object.textFrameOptions", &json!({"ids": [], "id": r["id"], "columns": 3})).unwrap_err().to_string();
|
||||
assert!(e.contains("nothing selected"), "{e}");
|
||||
assert_eq!(columns(&s), Some(2));
|
||||
// Commands documented with `ids` honour `id` too.
|
||||
assert_eq!(s.execute("conveyor.collect", &json!({"id": r["id"]})).unwrap()["count"], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use designcraft_doc::{ItemId, Shape};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use super::{CommandSpec, bad, cmd, has_selection, ids_param};
|
||||
use super::{CommandSpec, bad, cmd, has_selection};
|
||||
use crate::{Result, Session};
|
||||
|
||||
fn target(s: &Session, p: &Value) -> Result<ItemId> {
|
||||
@@ -24,7 +24,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"{ids? (default: the selection; one group's objects or several objects become states)} → {id, states}",
|
||||
has_selection,
|
||||
|s, p| {
|
||||
let ids = ids_param(p, "ids").unwrap_or_else(|| s.active().map(|d| d.selection.items.clone()).unwrap_or_default());
|
||||
let ids = super::targets(s, p)?;
|
||||
let single_group = ids.len() == 1 && s.doc()?.doc.item(ids[0]).is_some_and(|it| it.shape == Shape::Group && it.children().len() > 1);
|
||||
let gid = if single_group {
|
||||
ids[0]
|
||||
|
||||
Reference in New Issue
Block a user