diff --git a/crates/doc/src/styles.rs b/crates/doc/src/styles.rs index a66a0935..e7d104b9 100644 --- a/crates/doc/src/styles.rs +++ b/crates/doc/src/styles.rs @@ -140,17 +140,21 @@ impl VariableValue { } } + /// The type this value has on its own, which a typed literal needs. None for references + /// (aliases and colour calculations): what they read may be missing or loop, so only + /// resolving them gives a type, and an expression can't take one as a literal. pub fn type_of(&self) -> Option { match self { VariableValue::Color(_) => Some(VariableType::Color), VariableValue::Number(_) => Some(VariableType::Number), VariableValue::String(_) => Some(VariableType::String), VariableValue::Boolean(_) => Some(VariableType::Boolean), - // References have no type of their own: what they read may be missing or loop, so an - // expression can't take one as a typed literal. VariableValue::Alias(_) | VariableValue::ColorAlpha { .. } | VariableValue::ColorMix { .. } => None, } } + /// The value on one line, as the panel shows it: `→ id` for an alias, `α 50% · id` and + /// `from + to @ 40%` for colour calculations, variables by id ([`Self::display_with`] names + /// them). pub fn display(&self) -> String { self.display_with(&|id| id.to_string()) } @@ -406,6 +410,9 @@ impl Variables { var.values.get(mode).or_else(|| var.values.values().next()) } + /// [`Self::resolve`] with `done` shared by every variable one call reads: each is resolved once + /// and its outcome kept, one met again while still in flight is a cycle (None), and the call + /// reads at most [`Self::RESOLVE_LIMIT`] variables. fn resolve_memo( &self, id: &str, diff --git a/crates/engine/src/cmd/styles.rs b/crates/engine/src/cmd/styles.rs index ee7506da..7253cf33 100644 --- a/crates/engine/src/cmd/styles.rs +++ b/crates/engine/src/cmd/styles.rs @@ -902,6 +902,10 @@ fn var_value(cmd: &str, vars: &Variables, kind: VariableType, for_id: Option<&Va }) } +/// `variable.create`: a variable with a value for every mode of its collection (`values` by mode, +/// then `value` for the modes left, then its type's default). Every value is checked before the +/// variable exists (alias targets, calculation operands, the 32-variable limit), so a refused one +/// leaves nothing behind. fn var_create(s: &mut Session, p: &Value) -> Result { let cmd = "variable.create"; let c = req_string(cmd, p, "collection")?; @@ -966,6 +970,10 @@ fn var_create(s: &mut Session, p: &Value) -> Result { Ok(json!({"id": id})) } +/// `variable.set`: one mode's value (the default mode when none is named), checked against the +/// variable as it stands before anything changes: an alias or calculation may not lead back to it, +/// and a calculation must fit the 32-variable limit. On a variable an extended collection inherits, +/// the value becomes that mode's override. pub fn var_set(s: &mut Session, p: &Value) -> Result { let cmd = "variable.set"; let v = req_string(cmd, p, "variable")?;