No matching definitions.

tur/range-bound-string

stdlib/range-bound-string.tur

owned-String rendering for a single Bound endpoint.

bound->str (stdlib/range-bound) returns a cstr that is a fresh malloc for the Inclusive/Exclusive branches (via bound-fmt -> str-concat) but a static "unbounded" literal for the Unbounded branch. That sentinel mixing makes a blind string/adopt-cstr wrapper unsafe: adopting the Unbounded literal would free() static storage (undefined behavior).

Unlike the httpd accessors, absence is NOT semantically meaningful here -- Unbounded has a perfectly good rendering ("unbounded"), it is simply not heap-allocated. So the honest type is a total String, not option<String>. The fix is PER-BRANCH: adopt the malloc'd inclusive/exclusive branches, from-cstr (copy, do not free) the static Unbounded literal.

It is a SEPARATE module so the lean stdlib/range-bound (str-build only, no typeclass/map) keeps its narrow load graph -- loading stdlib/string here would perturb Eq [Bound] resolution the way the module warns against.

Since: v2 (string-owned-builders-and-optional-accessors-plan, Part 2)

defn

bound->str-string

(bound->str-string [b :Bound] :String)

render a single Bound endpoint as a fresh owned String.

The owned sibling of bound->str. Renders "[v" for Inclusive, "(v" for Exclusive, or "unbounded" for Unbounded -- always a valid owned String, and Unbounded never crashes (the per-branch adopt/from-cstr rule, not a blind adopt, is what keeps the static literal from being freed).

ba (Bound int)

A fresh owned String (rc 1); release it or hand it to a container.

(string/to-cstr (bound->str-string (bound-inclusive 3)))  ; => "[3"
(string/to-cstr (bound->str-string (bound-unbounded)))    ; => "unbounded"

Since: v2