pub struct Printf {
pub format: String,
pub parsed: ParsedFormat,
/* private fields */
}Expand description
Printf-style N→1 formatting node. Variadic: accepts 0..N wire inputs.
Signature: printf(format: String, in_0, in_1, ...) -> (String)
Format string uses Rust-style {} placeholders with optional specifiers:
{:05} (zero-pad), {:.2} (precision), {:x} (hex), {:X} (HEX),
{:b} (binary), {:o} (octal). Inputs are matched positionally.
Use for constructing complex formatted strings from multiple Polydat wires:
printf("user-{:05}-score-{:.1}", id, score) → “user-00042-score-98.6”
All Value types are accepted at eval time regardless of declared port
types (the variadic slots advertise PortType::Str but the body
dispatches on Value variants). The format specifier determines how
each value renders.
SRD-73 follow-up: None propagation through string interpolation.
If any REFERENCED input is Value::None, the whole result is
Value::None. The body itself doesn’t materialise this —
the Polydat kernel’s SRD-74 Rule 1 guard (engines.rs) emits
Value::None on every output for any node whose inputs
include Value::None and which doesn’t opt into
accepts_none_inputs. Printf doesn’t opt in, so the kernel
guard fires before this body is invoked at production time.
Rationale: Value::None is the canonical “absent” sentinel.
The Polydat Kernel’s lookup / get_constant already treat
None-valued outputs as “not present in this scope” and fall
through to the parent scope. String interpolation is the
surface where that discipline was being silently broken — an
unresolved {X} in a source-level string literal compiles
to a printf call with the unresolved name’s slot, and when
that slot evaluates to None the printf result should likewise
be None so the binding doesn’t shadow upstream defaults. The
canonical end-to-end coverage for this lives in
tests/scope_composition.rs::const_with_unbound_interpolation_*.
Fields§
§format: StringThe format argument, as given at construction.
parsed: ParsedFormatThe parsed value, computed once at construction.
Implementations§
Trait Implementations§
Source§impl PolydatNode for Printf
impl PolydatNode for Printf
Source§fn compiled_slot(&self, wire_types: &[PortType]) -> Option<CompiledSlotKit>
fn compiled_slot(&self, wire_types: &[PortType]) -> Option<CompiledSlotKit>
(ptr, len) slot
pairs; vector outputs write into kernel-owned scratch.
Checked by the compiled-kernel builders AFTER
Self::compiled_u64 — pure-scalar nodes never need it.
Default None: the node stays on typed eval.Source§fn scratch_layout(&self) -> Vec<ScratchElem>
fn scratch_layout(&self) -> Vec<ScratchElem>
Self::eval_in. Empty for a node that evaluates over
Values alone, which is every node but a native cone.Source§fn eval_in(
&self,
scratch: &mut [ScratchBuf],
inputs: &[Value],
outputs: &mut [Value],
)
fn eval_in( &self, scratch: &mut [ScratchBuf], inputs: &[Value], outputs: &mut [Value], )
Self::eval with the node’s scratch, which the evaluating
state owns and hands in: storage belongs to the state, never to
the node, which is shared by every state of the program.Source§fn commutativity(&self) -> Commutativity
fn commutativity(&self) -> Commutativity
Source§fn accepts_none_inputs(&self) -> bool
fn accepts_none_inputs(&self) -> bool
Value::None inputs
directly rather than have the kernel propagate None through
it. Default: false — most nodes follow SRD-74 Rule 1
(None in → None out, no eval invocation). Read moreSource§fn compiled_u64(&self) -> Option<CompiledU64Op>
fn compiled_u64(&self) -> Option<CompiledU64Op>
Source§fn jit_constants(&self) -> Vec<u64>
fn jit_constants(&self) -> Vec<u64>
Source§fn purity(&self) -> Purity
fn purity(&self) -> Purity
runtime_model.md’s D2 axiom. Default:
Purity::Pure. Override to declare an observable
side channel (Purity::SideChannel) or
eval-call-spanning state (Purity::Nondeterministic). Read moreSource§fn simd_variant(&self) -> Option<SimdVariant>
fn simd_variant(&self) -> Option<SimdVariant>
Source§fn fusion_subgraph(&self) -> Option<FusionSubgraph<'_>>
fn fusion_subgraph(&self) -> Option<FusionSubgraph<'_>>
PolydatProgram::canonical_hash) walks THROUGH fusion
nodes into this subgraph, so identity is invariant to the
engine mix: jit=off and jit=auto compiles of the same
source hash identically, and resume-skip matching survives
mode changes. Default None: ordinary nodes hash as
themselves.Auto Trait Implementations§
impl Freeze for Printf
impl RefUnwindSafe for Printf
impl Send for Printf
impl Sync for Printf
impl Unpin for Printf
impl UnsafeUnpin for Printf
impl UnwindSafe for Printf
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more