encoding: lead with methods for hexadecimal and Base64 (slice of #146) #176

Closed
opened 2026-10-08 07:03:41 +00:00 by orion · 3 comments
Collaborator

Goal

std/encoding hexadecimal and Base64 decoding are used as methods: bytes.hexEncoded(uppercase:), text.hexDecoded(), text.base64Decoded().

Part of #146 (methods are the preferred API style; owner direction 2026-10-06, first applied in #96 as Digest.equalsConstantTime with constantTimeEqual kept as a thin wrapper). This slice follows exactly that pattern.

Functions in scope

hexEncoded (on Bytes), hexDecoded and base64Decoded (on String) in std/encoding. Keep as free functions: structureOf<Value>() (no receiver), rendered, and the encode*/decode*/describe* helpers (generic derive plumbing, not receiver-first API). Revisit rendered(value) in a later round (blanket extend over Encode).

Source (pinned record)

  • docs/standard-library/encoding.md, ENCODING.md; no design record fixes the API shape
  • Extension members are named where they are used (CONCEPT, "Extension Methods", pinned); callers use the method like any member. If an extend without a trait on a type of another package turns out not to work in std/, stop and re-plan instead of working around it.

Acceptance criteria

  • std/encoding provides Bytes.hexEncoded(uppercase: Bool = false), String.hexDecoded() and String.base64Decoded() with the current result types
  • Tests (std/encoding hexadecimal and base64 test files): method result equals free function result on the existing vectors, including upper/lower case, odd length and invalid digits
  • Each free function stays and becomes a thin wrapper that only calls the method; its signature, behaviour and existing tests are unchanged. It is not marked deprecated here (the deprecation path is an open owner decision on #146).
  • The module's documentation page under docs/standard-library/ leads with the method in every example; the wrapper is listed as the older spelling. Examples are checked with trb check; skills/ is regenerated.
  • No caller outside the module changes (compiler/src and tools/ keep calling the wrapper).

Seed

No. Ordinary TorbScript in std/ only: no syntax change, no new native, no driver flag, no std name the compiler looks up by string. If that turns out wrong, stop and re-plan (two commits, seed refresh).

Size

One PR, one Conventional Commit (refactor(<module>): ... or feat(<module>): ...), tests and docs in the same commit.

Dependencies

Tracking epic: #146. No other dependency; independent of the other module slices.

## Goal `std/encoding` hexadecimal and Base64 decoding are used as methods: `bytes.hexEncoded(uppercase:)`, `text.hexDecoded()`, `text.base64Decoded()`. Part of #146 (methods are the preferred API style; owner direction 2026-10-06, first applied in #96 as `Digest.equalsConstantTime` with `constantTimeEqual` kept as a thin wrapper). This slice follows exactly that pattern. ## Functions in scope `hexEncoded` (on `Bytes`), `hexDecoded` and `base64Decoded` (on `String`) in `std/encoding`. Keep as free functions: `structureOf<Value>()` (no receiver), `rendered`, and the `encode*`/`decode*`/`describe*` helpers (generic derive plumbing, not receiver-first API). Revisit `rendered(value)` in a later round (blanket `extend` over `Encode`). ## Source (pinned record) - [docs/standard-library/encoding.md](https://git.torb.dev/torbscript/language/src/commit/129f1574e8ad4c9c691306808eb39900e77d4fc2/docs/standard-library/encoding.md), [ENCODING.md](https://git.torb.dev/torbscript/language/src/commit/129f1574e8ad4c9c691306808eb39900e77d4fc2/docs/design/ENCODING.md); no design record fixes the API shape - Extension members are named where they are used (CONCEPT, "Extension Methods", [pinned](https://git.torb.dev/torbscript/language/src/commit/129f1574e8ad4c9c691306808eb39900e77d4fc2/CONCEPT.md)); callers `use` the method like any member. If an `extend` without a trait on a type of another package turns out not to work in `std/`, stop and re-plan instead of working around it. ## Acceptance criteria - [ ] `std/encoding` provides `Bytes.hexEncoded(uppercase: Bool = false)`, `String.hexDecoded()` and `String.base64Decoded()` with the current result types - [ ] Tests (`std/encoding` hexadecimal and base64 test files): method result equals free function result on the existing vectors, including upper/lower case, odd length and invalid digits - [ ] Each free function stays and becomes a thin wrapper that only calls the method; its signature, behaviour and existing tests are unchanged. It is **not** marked `deprecated` here (the deprecation path is an open owner decision on #146). - [ ] The module's documentation page under `docs/standard-library/` leads with the method in every example; the wrapper is listed as the older spelling. Examples are checked with `trb check`; `skills/` is regenerated. - [ ] No caller outside the module changes (`compiler/src` and `tools/` keep calling the wrapper). ## Seed No. Ordinary TorbScript in `std/` only: no syntax change, no new native, no driver flag, no std name the compiler looks up by string. If that turns out wrong, stop and re-plan (two commits, seed refresh). ## Size One PR, one Conventional Commit (`refactor(<module>): ...` or `feat(<module>): ...`), tests and docs in the same commit. ## Dependencies Tracking epic: #146. No other dependency; independent of the other module slices.
Author
Collaborator

[loop:torbscript] scope update from the owner decision on #146 (torben, 2026-10-08): the free functions covered by this slice are removed in the same PR that adds the methods, not kept as wrappers and not marked deprecated. Migrate every caller in the repo (std, tests, examples, docs) to the method in the same PR. No lint migration rule needed.

[loop:torbscript] scope update from the owner decision on #146 (torben, 2026-10-08): the free functions covered by this slice are **removed** in the same PR that adds the methods, not kept as wrappers and not marked `deprecated`. Migrate every caller in the repo (std, tests, examples, docs) to the method in the same PR. No lint migration rule needed.
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261008 until 2026-10-08T14:10:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261008 until 2026-10-08T14:10:00Z
argus closed this issue 2026-10-08 09:26:27 +00:00
Author
Collaborator

[loop:torbscript] implement: PR #184 (#184) added Bytes.hexEncoded, String.hexDecoded and String.base64Decoded as extension methods declared in std/encoding, and removed the free functions with no wrappers. Callers in std/yaml, std/dns, std/digest tests and tools/registry were migrated, docs and skills/ regenerated, and the pdisc summary shortened to fit the 240 limit. Tier A, bootstrap, release-sync/registry, pdisc and the other gates went green after two infra context canceled flakes were retriggered. Argus has already merged the PR, so the issue is done. Worker token usage: not available to the worker, see the session record. next: review

[loop:torbscript] implement: PR #184 (https://git.torb.dev/torbscript/language/pulls/184) added `Bytes.hexEncoded`, `String.hexDecoded` and `String.base64Decoded` as extension methods declared in std/encoding, and removed the free functions with no wrappers. Callers in std/yaml, std/dns, std/digest tests and tools/registry were migrated, docs and skills/ regenerated, and the pdisc summary shortened to fit the 240 limit. Tier A, bootstrap, release-sync/registry, pdisc and the other gates went green after two infra `context canceled` flakes were retriggered. Argus has already merged the PR, so the issue is done. Worker token usage: not available to the worker, see the session record. next: review
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#176
No description provided.