Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions x/cm_idiomatic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# cm_idiomatic

Idiomatic Go conversions for WebAssembly Component Model types.

## Overview

This library provides simple functions to convert between Go types and Component Model types:

- **Option** ↔ **Pointer**: Convert between `cm.Option[T]` and `*T`
- **List** ↔ **Slice**: Convert between `cm.List[T]` and `[]T`
- **Map** ↔ **Tuples**: Convert between Go maps and Component Model tuple lists
- **Result** ↔ **Error**: Convert between `cm.Result[T, T, E]` and Go's `(T, error)` pattern

### Option

```go
// Go pointer to Component Model Option
value := 42
opt := cm_idiomatic.FromPtr(&value) // cm.Option[int]

// Component Model Option to Go pointer
ptr := cm_idiomatic.ToPtr(opt) // *int
```

### List

```go
// Go slice to Component Model List
slice := []string{"hello", "world"}
list := cm_idiomatic.FromSlice(slice) // cm.List[string]

// Component Model List to Go slice
result := cm_idiomatic.ToSlice(list) // []string
```

### Map

```go
// Go map to Component Model tuple list
m := map[string]int{"foo": 1, "bar": 2}
tuples := cm_idiomatic.FromMap(m) // cm.List[cm.Tuple[string, int]]

// Component Model tuple list to Go map
result := cm_idiomatic.ToMap(tuples) // map[string]int
```

### Result

```go
// Go (value, error) to Component Model Result
result := cm_idiomatic.FromError[string, error]("success", nil)
// Returns cm.Result[string, string, error]

// Component Model Result to Go (value, error)
value, err := cm_idiomatic.ToError(result) // (string, error)
```

## Installation

```bash
go get go.wasmcloud.dev/x/cm_idiomatic
```

## Usage

```go
import "go.wasmcloud.dev/x/cm_idiomatic"
```
63 changes: 63 additions & 0 deletions x/cm_idiomatic/cm_idiomatic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package cm_idiomatic

import (
"go.bytecodealliance.org/cm"
)

// ToPtr converts a Component Model Option to a Go pointer.
// Returns nil if the Option is None, otherwise returns a pointer to the value.
func ToPtr[T any](opt cm.Option[T]) *T {
return opt.Some()
}

// FromPtr converts a Go pointer to a Component Model Option.
// Returns None if the pointer is nil, otherwise returns Some with the dereferenced value.
func FromPtr[T any](ptr *T) cm.Option[T] {
if ptr == nil {
return cm.None[T]()
}
return cm.Some(*ptr)
}

// ToSlice converts a Component Model List to a Go slice.
func ToSlice[T any](list cm.List[T]) []T {
return list.Slice()
}

// FromSlice converts a Go slice to a Component Model List.
func FromSlice[T any](slice []T) cm.List[T] {
return cm.ToList(slice)
}

// ToMap converts a Component Model List of tuples to a Go map.
func ToMap[K comparable, V any](list cm.List[cm.Tuple[K, V]]) map[K]V {
slice := ToSlice(list)
m := make(map[K]V, len(slice))

for i := 0; i < len(slice); i++ {
tuple := slice[i]
m[tuple.F0] = tuple.F1
}

return m
}

// FromMap converts a Go map to a Component Model List of tuples.
func FromMap[K comparable, V any](m map[K]V) cm.List[cm.Tuple[K, V]] {
tuples := make([]cm.Tuple[K, V], 0, len(m))
for k, v := range m {
tuples = append(tuples, cm.Tuple[K, V]{F0: k, F1: v})
}
return FromSlice(tuples)
}

// FromResult converts Go's (value, error) pattern to a Component Model Result.
// Returns OK(value) if error is nil, otherwise returns Err(error).
func FromResult[R cm.AnyResult[Shape, T, E], Shape, T, E any](value T, err E) R {
var zero E
// Check if err is the zero value (e.g., nil for error interface)
if any(err) == any(zero) {
return cm.OK[R](value)
}
return cm.Err[R](err)
}
5 changes: 5 additions & 0 deletions x/cm_idiomatic/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module go.wasmcloud.dev/x/cm_idiomatic

go 1.24

require go.bytecodealliance.org/cm v0.3.0
2 changes: 2 additions & 0 deletions x/cm_idiomatic/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go.bytecodealliance.org/cm v0.3.0 h1:VhV+4vjZPUGCozCg9+up+FNL3YU6XR+XKghk7kQ0vFc=
go.bytecodealliance.org/cm v0.3.0/go.mod h1:JD5vtVNZv7sBoQQkvBvAAVKJPhR/bqBH7yYXTItMfZI=