Plug-ins: doc comments for the functions the filter changes touch

The docstring check of the review counts the functions a pull request
touches: effect.apply, effect.setParams, plugin.run, the line cap
name, the reader of an output object and seven of the object tests had
no doc comment. Each now says what it does or checks; the join and cap
names get one each.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhvnnnD5fTFupK8WWq35un
This commit is contained in:
Louise Fox
2026-10-22 01:25:51 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent 78105cc695
commit 8bc117eb8b
4 changed files with 27 additions and 1 deletions
+6
View File
@@ -141,6 +141,9 @@ fn check_revolve_count(n: &Node, cmd: &str) -> Result<()> {
pub(crate) const ONE_3D: &str = "An object takes one 3D effect. Edit the existing effect's options, or remove it first.";
/// `effect.apply`: adds effect `effect` (or `id`) with `params`, its defaults filled in, to the
/// targets' active item as one undo step. A 3D effect must fit each target, which takes only one;
/// a Pathfinder effect on loose objects groups them first. → `{ids, index, item}`.
pub(crate) fn apply(s: &mut Session, p: &Value) -> Result<Value> {
const C: &str = "effect.apply";
let id = str_param(p, "effect").or_else(|| str_param(p, "id")).ok_or_else(|| bad(C, "missing `effect` id"))?;
@@ -329,6 +332,9 @@ fn lighting_preset(s: &mut Session, p: &Value) -> Result<Value> {
set_params(s, &options)
}
/// `effect.setParams`: merges `params` into the effect at `index` of the targets' active item, and
/// sets its Warp style (`warpStyle`) or visibility (`visible`), as one undo step. They are checked
/// as `effect.apply` checks them, and a visible 3D effect must still fit. → `{ids}`.
fn set_params(s: &mut Session, p: &Value) -> Result<Value> {
const C: &str = "effect.setParams";
let index = index_param(p, "index", C)?;
+4
View File
@@ -59,6 +59,10 @@ fn plugin_by_id(cmd: &str, p: &Value) -> Result<Arc<Plugin>> {
registry::get(id).ok_or_else(|| err(vectorcraft_plugins::Error::NotFound(id.into())))
}
/// `plugin.run`: runs filter `id` on `ids` (else the selected paths and compound paths) with its
/// parameters and `_context`, and applies its output as one undo step ([`objects::apply_output`];
/// effect records as [`admit_effects`] admits them). → `{plugin, ids}`: what it made or changed,
/// which is then selected.
fn run(s: &mut Session, p: &Value) -> Result<Value> {
const C: &str = "plugin.run";
let plugin = plugin_by_id(C, p)?;
+5 -1
View File
@@ -76,7 +76,7 @@ impl OutStroke {
/// host's to say.
pub type AdmitEffects<'a> = &'a dyn Fn(&[Effect], &Node) -> std::result::Result<Vec<Effect>, String>;
/// The names plug-ins use for line joins and caps, as SVG's.
/// The name plug-ins use for line join `j`, as SVG's `stroke-linejoin`.
fn join_name(j: LineJoin) -> &'static str {
match j {
LineJoin::Miter => "miter",
@@ -85,6 +85,7 @@ fn join_name(j: LineJoin) -> &'static str {
}
}
/// The name plug-ins use for line cap `c`, as SVG's `stroke-linecap`.
fn cap_name(c: LineCap) -> &'static str {
match c {
LineCap::Butt => "butt",
@@ -265,6 +266,9 @@ fn opt<'a>(o: &'a serde_json::Map<String, Value>, key: &str) -> Option<&'a Value
o.get(key).filter(|v| !v.is_null())
}
/// Object `v` of a plug-in's output (`at` names it in errors), its anchors added to `anchors` and
/// held to [`MAX_ANCHORS`]: each key it has checked, numbers clamped into range, as [`decode`] reads
/// them.
fn decode_object(v: &Value, at: &str, anchors: &mut usize) -> Result<OutObject> {
let o = v.as_object().ok_or_else(|| out_err(at, "an object must be a JSON object"))?;
let mut out = OutObject::default();
+12
View File
@@ -46,6 +46,8 @@ fn targets_are_selected_paths_in_paint_order() {
assert_eq!(filter_targets(&d, &[layer]), [ids[0], ids[2]]);
}
/// Objects as plug-ins are given them (type, name, fill rule, fills, strokes, bounds); handed back
/// unchanged, they change nothing, swatch links included.
#[test]
fn objects_round_trip_through_the_json_model() {
let (mut d, ids, _) = doc();
@@ -90,6 +92,8 @@ fn an_unchanged_path_stays_a_live_shape() {
assert!(matches!(&d.node(a).unwrap().kind, NodeKind::Path { live: None, .. }), "moved: a plain path");
}
/// An output updates the input objects it lists, deletes the ones it leaves out, and adds new
/// objects where it lists them.
#[test]
fn outputs_update_add_and_delete_in_place() {
let (mut d, ids, layer) = doc();
@@ -109,6 +113,8 @@ fn outputs_update_add_and_delete_in_place() {
assert!(n1.appearance.stroke().is_none());
}
/// New objects take the place of the input objects they replace, or go on top of the given
/// container when there were none.
#[test]
fn new_objects_take_the_place_of_replaced_inputs_or_go_on_top() {
let (mut d, ids, layer) = doc();
@@ -121,6 +127,8 @@ fn new_objects_take_the_place_of_replaced_inputs_or_go_on_top() {
assert_eq!(names(&d, layer).last().map(String::as_str), Some("X"));
}
/// An output turns a path into a compound path and back and sets its fill rule, strokes (weights
/// clamped), opacity and name.
#[test]
fn geometry_type_and_strokes_change() {
let (mut d, ids, _) = doc();
@@ -143,6 +151,8 @@ fn geometry_type_and_strokes_change() {
assert!(n.appearance.stroke().is_none());
}
/// A paint handed back as it was keeps its swatch link and any other is unlinked; a pattern paint
/// must name a pattern the document has.
#[test]
fn changed_paints_lose_swatch_links_and_patterns_must_exist() {
let (mut d, ids, _) = doc();
@@ -160,6 +170,7 @@ fn changed_paints_lose_swatch_links_and_patterns_must_exist() {
assert!(apply_output(&mut d, &[a], decode_json(pattern).unwrap(), None, &keep).is_ok());
}
/// Output the host can't read as objects is refused, whatever is wrong with it.
#[test]
fn bad_outputs_are_refused() {
let (d, ids, _) = doc();
@@ -234,6 +245,7 @@ fn stroke_styles_and_effect_records_round_trip() {
assert_eq!((e.to_string().contains("objects[0].effects: not an effect"), &d), (true, &before), "{e}");
}
/// Stroke styles and effect records in a form the host doesn't read are refused.
#[test]
fn bad_stroke_styles_and_effect_records_are_refused() {
let a = doc().1[0].0;