Skip to content

feat(stdlib): add ard/base64 encoding module#81

Merged
akonwi merged 5 commits intomainfrom
feat/stdlib-base64
Apr 5, 2026
Merged

feat(stdlib): add ard/base64 encoding module#81
akonwi merged 5 commits intomainfrom
feat/stdlib-base64

Conversation

@akonwi
Copy link
Copy Markdown
Owner

@akonwi akonwi commented Apr 5, 2026

Summary

Adds base64 encoding/decoding to the standard library with all three common variants.

use ard/base64

// Standard base64 (with padding)
base64::encode("hello")              // "aGVsbG8="
base64::decode("aGVsbG8=")           // ok("hello")

// base64url (URL-safe alphabet)
base64::encode_url("subjects?")       // "c3ViamVjdHM_"
base64::decode_url(encoded)

// base64url without '=' padding
base64::encode_url_no_pad("f")        // "Zg"
base64::decode_url_no_pad(encoded)

Motivation

The no-pad URL-safe variant is required by:

  • PKCE (OAuth 2.1)base64url(sha256(verifier)) with no padding
  • JWT — headers and payloads

This blocks implementing Oauth for MCP servers.

Mapping

Ard Go
encode / decode base64.StdEncoding
encode_url / decode_url base64.URLEncoding
encode_url_no_pad / decode_url_no_pad base64.RawURLEncoding

Decode functions return Str!Str, so invalid input produces a recoverable Result::err with the underlying Go error message.

Notes

  • Module path is ard/base64 (flat, matching existing stdlib layout) rather than ard/encoding/base64. Nested stdlib paths aren't currently supported by std_lib/embed.go; can be revisited later if more encoding modules are added.

Tests

  • compiler/bytecode/vm/base64_test.go: 11 VM tests covering encode/decode round-trips, all three variants, padding behavior, and error handling.
  • compiler/std_lib/base64.ard: 13 inline test fn cases (run via ard test std_lib).
  • All existing tests pass.

Adds base64 encoding/decoding to the standard library with three variants:

- encode/decode: standard base64 with padding
- encode_url/decode_url: base64url with padding
- encode_url_no_pad/decode_url_no_pad: base64url without '=' padding

These map 1:1 to Go's encoding/base64 StdEncoding, URLEncoding, and
RawURLEncoding.

Motivation: the no-pad url-safe variant is required by PKCE (OAuth 2.1)
for base64url(sha256(verifier)), and by JWT headers/payloads.

Notes:
- Module path is 'ard/base64' (flat, matching existing stdlib layout)
  rather than 'ard/encoding/base64' — nested stdlib paths aren't
  currently supported by std_lib/embed.go.
- Decode functions return Str!Str so invalid input produces a recoverable
  Result::err with the underlying Go error message.
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ard-lang-dev Ready Ready Preview, Comment Apr 5, 2026 7:53pm

The stdlib test functions in std_lib/base64.ard already cover all the
cases from base64_test.go. Both run against the same bytecode VM, so
keeping both was pure duplication.
Collapse encode_url_no_pad/decode_url_no_pad into encode_url/decode_url
with an optional Bool? parameter to opt out of padding:

  base64::encode_url("f")          // "Zg==" (padded, default)
  base64::encode_url("f", true)    // "Zg" (no padding, for JWT/PKCE)

Also fixes a runtime inconsistency: AsBool and AsFloat now unwrap raw
values like AsInt and AsString, so FFI functions with nullable Bool?/
Float? parameters work correctly with the checker's automatic wrapping
of non-nullable arguments.
Both standard and URL-safe variants now accept the same optional no_pad
parameter, matching Go's base64 API which exposes RawStdEncoding and
RawURLEncoding symmetrically.
@akonwi akonwi merged commit cf3a763 into main Apr 5, 2026
4 checks passed
@akonwi akonwi deleted the feat/stdlib-base64 branch April 5, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant