golem icon indicating copy to clipboard operation
golem copied to clipboard

optics fails on struct pointer type

Open fogfish opened this issue 1 year ago • 0 comments

The following example causes the crash for library

package main

import (
	"fmt"

	"github.com/fogfish/golem/optics"
)

type Story struct {
	Text *string
}

func main() {
	l := optics.ForProduct1[*Story, *string]()
	s := &Story{}
	x := "xxx"

	l.Put(&s, &x)

	fmt.Printf("==> %+v\n", s)
	fmt.Printf("==> %v\n", s.Text)
	fmt.Printf("==> %s\n", *s.Text) // <= crash here
}

The reason is lens internals. It assume S is pure structure. As fix, the lens needs to know a metadata about S type.

func (lens *lens[S, A]) Put(s *S, a A) *S {
	*(*A)(unsafe.Pointer(uintptr(unsafe.Pointer(s)) + lens.Offset + lens.RootOffs)) = a
	return s
}

func (lens *lens[S, A]) Get(s *S) A {
	return *(*A)(unsafe.Pointer(uintptr(unsafe.Pointer(s)) + lens.Offset + lens.RootOffs))
}

fogfish avatar Feb 02 '25 17:02 fogfish