github.com/primecitizens/pcz/std@v0.2.1/ffi/js/array.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  
     4  package js
     5  
     6  import (
     7  	"github.com/primecitizens/pcz/std/core/assert"
     8  	"github.com/primecitizens/pcz/std/core/math"
     9  	"github.com/primecitizens/pcz/std/core/num"
    10  	"github.com/primecitizens/pcz/std/ffi/js/array"
    11  	"github.com/primecitizens/pcz/std/ffi/js/bindings"
    12  )
    13  
    14  func NewArray[T any](sz int) Array[T] {
    15  	if sz < 0 {
    16  		assert.Throw("invalid", "negative", "capacity")
    17  	}
    18  
    19  	if uint64(sz) > uint64(math.MaxUint32) {
    20  		assert.Throw("array", "size", "too", "large")
    21  	}
    22  
    23  	return Array[T]{
    24  		ref: array.New(SizeU(sz), 0, 0, 0),
    25  	}
    26  }
    27  
    28  func NewArrayOf[T any](take bool, elems ...Ref) Array[T] {
    29  	return NewArray[T](len(elems)).MustFill(0, take, elems...)
    30  }
    31  
    32  type Array[T any] struct {
    33  	ref bindings.Ref
    34  }
    35  
    36  func (a Array[T]) FromRef(ref Ref) Array[T] {
    37  	return Array[T]{
    38  		ref: bindings.Ref(ref),
    39  	}
    40  }
    41  
    42  func (a Array[T]) Ref() Ref {
    43  	return Ref(a.ref)
    44  }
    45  
    46  func (a Array[T]) Once() Array[T] {
    47  	bindings.Once(a.ref)
    48  	return a
    49  }
    50  
    51  func (a Array[T]) Length() int {
    52  	return int(array.Length(a.ref))
    53  }
    54  
    55  func (a Array[T]) Slice(start, end int) Array[T] {
    56  	return Array[T]{
    57  		ref: array.Slice(a.ref, SizeU(start), SizeU(end)),
    58  	}
    59  }
    60  
    61  func (a Array[T]) SliceFrom(start int) Array[T] {
    62  	return Array[T]{
    63  		ref: array.Slice(a.ref, SizeU(start), 0),
    64  	}
    65  }
    66  
    67  func (a Array[T]) Fill(start int, take bool, elems ...Ref) int {
    68  	return int(
    69  		array.Append(
    70  			a.ref,
    71  			bindings.Ref(Bool(take)),
    72  			0,                   // elemSz (for typed array only)
    73  			bindings.Ref(False), // signed (for typed array only)
    74  			bindings.Ref(False), // float (for typed array only)
    75  			SizeU(start),        // offset
    76  			SliceData(elems),
    77  			SizeU(len(elems)),
    78  		),
    79  	)
    80  }
    81  
    82  func (a Array[T]) MustFill(start int, take bool, elems ...Ref) Array[T] {
    83  	if len(elems) != a.Fill(start, take, elems...) {
    84  		assert.Throw("not", "all", "elements", "inserted")
    85  	}
    86  
    87  	return a
    88  }
    89  
    90  func (a Array[T]) Copy(start int, outBuf []Ref) int {
    91  	return int(
    92  		array.Copy(
    93  			a.ref,
    94  			0,                   // elemSz (for typed array only)
    95  			bindings.Ref(False), // signed (for typed array only)
    96  			bindings.Ref(False), // float (for typed array only)
    97  			SizeU(start),
    98  			SliceData(outBuf),
    99  			SizeU(len(outBuf)),
   100  		),
   101  	)
   102  }
   103  
   104  func (a Array[T]) Nth(i int) (Ref, bool) {
   105  	var ret Ref
   106  	if bindings.Ref(True) == array.Nth(
   107  		a.ref,
   108  		0,                   // elemSz (for typed array only)
   109  		bindings.Ref(False), // signed (for typed array only)
   110  		bindings.Ref(False), // float (for typed array only)
   111  		SizeU(i),
   112  		Pointer(&ret),
   113  	) {
   114  		return ret, true
   115  	}
   116  
   117  	return Undefined, false
   118  }
   119  
   120  func (a Array[T]) NthNum(i int) (float64, bool) {
   121  	var ret float64
   122  	if bindings.Ref(True) == array.NthNum(
   123  		a.ref,
   124  		SizeU(i),
   125  		Pointer(&ret),
   126  	) {
   127  		return ret, true
   128  	}
   129  
   130  	return 0, false
   131  }
   132  
   133  func (a Array[T]) NthBool(i int) (bool, bool) {
   134  	var ret bool
   135  	if bindings.Ref(True) == array.NthBool(
   136  		a.ref,
   137  		SizeU(i),
   138  		Pointer(&ret),
   139  	) {
   140  		return ret, true
   141  	}
   142  
   143  	return false, false
   144  }
   145  
   146  func (a Array[T]) SetNth(i int, take bool, val Ref) bool {
   147  	return bindings.Ref(True) == array.SetNth(
   148  		a.ref,
   149  		0,                   // elemSz (for typed array only)
   150  		bindings.Ref(False), // signed (for typed array only)
   151  		bindings.Ref(False), // float (for typed array only)
   152  		SizeU(i),
   153  		bindings.Ref(Bool(take)),
   154  		Pointer(&val),
   155  	)
   156  }
   157  
   158  func (a Array[T]) SetNthNum(i int, val float64) bool {
   159  	return bindings.Ref(True) == array.SetNthNum(
   160  		a.ref,
   161  		SizeU(i),
   162  		val,
   163  	)
   164  }
   165  
   166  func (a Array[T]) SetNthBool(i int, val bool) bool {
   167  	return bindings.Ref(True) == array.SetNthBool(
   168  		a.ref,
   169  		SizeU(i),
   170  		bindings.Ref(Bool(val)),
   171  	)
   172  }
   173  
   174  func (a Array[T]) SetNthString(i int, s string) bool {
   175  	return bindings.Ref(True) == array.SetNthString(
   176  		a.ref,
   177  		SizeU(i),
   178  		StringData(s),
   179  		SizeU(len(s)),
   180  	)
   181  }
   182  
   183  func (a Array[T]) Free() {
   184  	bindings.Free(a.ref)
   185  }
   186  
   187  // TODO
   188  type FrozenArray[T any] struct {
   189  	ref bindings.Ref
   190  }
   191  
   192  func (a FrozenArray[T]) Ref() Ref {
   193  	return Ref(a.ref)
   194  }
   195  
   196  func (a FrozenArray[T]) FromRef(ref Ref) FrozenArray[T] {
   197  	return FrozenArray[T]{
   198  		ref: bindings.Ref(ref),
   199  	}
   200  }
   201  
   202  // TODO
   203  type ObservableArray[T any] struct {
   204  	ref bindings.Ref
   205  }
   206  
   207  func (a ObservableArray[T]) Ref() Ref {
   208  	return Ref(a.ref)
   209  }
   210  
   211  func (a ObservableArray[T]) FromRef(ref Ref) ObservableArray[T] {
   212  	return ObservableArray[T]{
   213  		ref: bindings.Ref(ref),
   214  	}
   215  }
   216  
   217  // TODO
   218  type DataView struct {
   219  	ref bindings.Ref
   220  }
   221  
   222  func (v DataView) Ref() Ref {
   223  	return Ref(v.ref)
   224  }
   225  
   226  func (v DataView) FromRef(ref Ref) DataView {
   227  	return DataView{
   228  		ref: bindings.Ref(ref),
   229  	}
   230  }
   231  
   232  // TODO
   233  type ArrayBuffer struct {
   234  	ref bindings.Ref
   235  }
   236  
   237  func (buf ArrayBuffer) FromRef(ref Ref) ArrayBuffer {
   238  	return ArrayBuffer{
   239  		ref: bindings.Ref(ref),
   240  	}
   241  }
   242  
   243  func (buf ArrayBuffer) Ref() Ref {
   244  	return Ref(buf.ref)
   245  }
   246  
   247  func (buf ArrayBuffer) Once() ArrayBuffer {
   248  	bindings.Once(buf.ref)
   249  	return buf
   250  }
   251  
   252  func (buf ArrayBuffer) Free() {
   253  	bindings.Free(buf.ref)
   254  	return
   255  }
   256  
   257  // TODO
   258  type SharedArrayBuffer struct {
   259  	ref bindings.Ref
   260  }
   261  
   262  func (buf SharedArrayBuffer) FromRef(ref Ref) SharedArrayBuffer {
   263  	return SharedArrayBuffer{
   264  		ref: bindings.Ref(ref),
   265  	}
   266  }
   267  
   268  func (buf SharedArrayBuffer) Ref() Ref {
   269  	return Ref(buf.ref)
   270  }
   271  
   272  func (buf SharedArrayBuffer) Once() SharedArrayBuffer {
   273  	bindings.Once(buf.ref)
   274  	return buf
   275  }
   276  
   277  func (buf SharedArrayBuffer) Free() {
   278  	bindings.Free(buf.ref)
   279  	return
   280  }
   281  
   282  // TODO
   283  type ArrayBufferView struct {
   284  	ref bindings.Ref
   285  }
   286  
   287  func (v ArrayBufferView) FromRef(ref Ref) ArrayBufferView {
   288  	return ArrayBufferView{
   289  		ref: bindings.Ref(ref),
   290  	}
   291  }
   292  
   293  func (v ArrayBufferView) Ref() Ref {
   294  	return Ref(v.ref)
   295  }
   296  
   297  func (v ArrayBufferView) Once() ArrayBufferView {
   298  	bindings.Once(v.ref)
   299  	return v
   300  }
   301  
   302  func (v ArrayBufferView) Free() {
   303  	bindings.Free(v.ref)
   304  	return
   305  }
   306  
   307  type (
   308  	Int8Array         = TypedArray[int8]
   309  	Int16Array        = TypedArray[int16]
   310  	Int32Array        = TypedArray[int32]
   311  	Uint8Array        = TypedArray[uint8]
   312  	Uint8ClampedArray = TypedArray[uint8]
   313  	Uint16Array       = TypedArray[uint16]
   314  	Uint32Array       = TypedArray[uint32]
   315  	Float32Array      = TypedArray[float32]
   316  	Float64Array      = TypedArray[float64]
   317  	BigInt64Array     = TypedArray[int64]
   318  	BigUint64Array    = TypedArray[uint64]
   319  )
   320  
   321  type elem interface {
   322  	~uint8 | ~uint16 | ~uint32 | ~uint64 |
   323  		~int8 | ~int16 | ~int32 | ~int64 |
   324  		~float32 | ~float64
   325  }
   326  
   327  func NewTypedArray[T elem](sz int) TypedArray[T] {
   328  	if sz < 0 {
   329  		assert.Throw("invalid", "negative", "capacity")
   330  	}
   331  
   332  	if uint64(sz) > uint64(math.MaxUint32) {
   333  		assert.Throw("array", "size", "too", "large")
   334  	}
   335  
   336  	elemSz, signed, float := num.CheckType[T]()
   337  	return TypedArray[T]{
   338  		ref: array.New(
   339  			SizeU(sz),
   340  			SizeU(elemSz),
   341  			bindings.Ref(Bool(signed)),
   342  			bindings.Ref(Bool(float)),
   343  		),
   344  	}
   345  }
   346  
   347  func NewTypedArrayOf[T elem](elems ...T) TypedArray[T] {
   348  	return NewTypedArray[T](len(elems)).MustFill(0, elems...)
   349  }
   350  
   351  type TypedArray[T elem] struct {
   352  	ref bindings.Ref
   353  }
   354  
   355  func (a TypedArray[T]) FromRef(ref Ref) TypedArray[T] {
   356  	return TypedArray[T]{
   357  		ref: bindings.Ref(ref),
   358  	}
   359  }
   360  
   361  func (a TypedArray[T]) Ref() Ref {
   362  	return Ref(a.ref)
   363  }
   364  
   365  func (a TypedArray[T]) Once() TypedArray[T] {
   366  	a.Ref().Once()
   367  	return a
   368  }
   369  
   370  func (a TypedArray[T]) Free() {
   371  	bindings.Free(a.ref)
   372  }
   373  
   374  func (a TypedArray[T]) FromArrayBuffer(take bool, buf ArrayBuffer) TypedArray[T] {
   375  	elemSz, signed, float := num.CheckType[T]()
   376  	return TypedArray[T]{
   377  		ref: array.FromBuffer(
   378  			bindings.Ref(Bool(take)),
   379  			buf.ref,
   380  			SizeU(elemSz),
   381  			bindings.Ref(Bool(signed)),
   382  			bindings.Ref(Bool(float)),
   383  		),
   384  	}
   385  }
   386  
   387  func (a TypedArray[T]) FromSharedArrayBuffer(take bool, buf SharedArrayBuffer) TypedArray[T] {
   388  	elemSz, signed, float := num.CheckType[T]()
   389  	return TypedArray[T]{
   390  		ref: array.FromBuffer(
   391  			bindings.Ref(Bool(take)),
   392  			buf.ref,
   393  			SizeU(elemSz),
   394  			bindings.Ref(Bool(signed)),
   395  			bindings.Ref(Bool(float)),
   396  		),
   397  	}
   398  }
   399  
   400  func (a TypedArray[T]) Buffer(take bool) Ref {
   401  	return Ref(array.Buffer(bindings.Ref(Bool(take)), a.ref))
   402  }
   403  
   404  func (a TypedArray[T]) ByteOffset() int {
   405  	return int(array.ByteOffset(a.ref))
   406  }
   407  
   408  func (a TypedArray[T]) ByteLength() int {
   409  	return int(array.ByteLength(a.ref))
   410  }
   411  
   412  func (a TypedArray[T]) Length() int {
   413  	return int(array.Length(a.ref))
   414  }
   415  
   416  func (a TypedArray[T]) Slice(start, end int) TypedArray[T] {
   417  	return TypedArray[T]{
   418  		ref: array.Slice(
   419  			a.ref, SizeU(start), SizeU(end),
   420  		),
   421  	}
   422  }
   423  
   424  func (a TypedArray[T]) SliceFrom(start int) TypedArray[T] {
   425  	return TypedArray[T]{
   426  		ref: array.Slice(
   427  			a.ref, SizeU(start), 0,
   428  		),
   429  	}
   430  }
   431  
   432  func (a TypedArray[T]) Nth(i int) (T, bool) {
   433  	var out T
   434  	elemSz, signed, float := num.CheckType[T]()
   435  	if bindings.Ref(True) == array.Nth(
   436  		a.ref,
   437  		SizeU(elemSz),
   438  		bindings.Ref(Bool(signed)),
   439  		bindings.Ref(Bool(float)),
   440  		SizeU(i),
   441  		Pointer(&out),
   442  	) {
   443  		return 0, false
   444  	}
   445  
   446  	return out, true
   447  }
   448  
   449  func (a TypedArray[T]) SetNth(i int, val T) bool {
   450  	elemSz, signed, float := num.CheckType[T]()
   451  	return bindings.Ref(True) == array.SetNth(
   452  		a.ref,
   453  		SizeU(elemSz),
   454  		bindings.Ref(Bool(signed)),
   455  		bindings.Ref(Bool(float)),
   456  		SizeU(i),
   457  		bindings.Ref(False),
   458  		Pointer(&val),
   459  	)
   460  }
   461  
   462  func (a TypedArray[T]) Fill(start int, elems ...T) int {
   463  	elemSz, signed, float := num.CheckType[T]()
   464  	return int(
   465  		array.Append(
   466  			a.ref,
   467  			bindings.Ref(False), // take (nop for typed array)
   468  			SizeU(elemSz),
   469  			bindings.Ref(Bool(signed)),
   470  			bindings.Ref(Bool(float)),
   471  			SizeU(start),
   472  			SliceData(elems),
   473  			SizeU(len(elems)),
   474  		),
   475  	)
   476  }
   477  
   478  func (a TypedArray[T]) MustFill(start int, elems ...T) TypedArray[T] {
   479  	if len(elems) != a.Fill(start, elems...) {
   480  		assert.Throw("not", "all", "elements", "inserted")
   481  	}
   482  
   483  	return a
   484  }
   485  
   486  func (a TypedArray[T]) Set(other TypedArray[T]) TypedArray[T] {
   487  	array.Set(a.ref, other.ref)
   488  	return a
   489  }
   490  
   491  func (a TypedArray[T]) Copy(start int, outBuf []T) int {
   492  	elemSz, signed, float := num.CheckType[T]()
   493  	return int(
   494  		array.Copy(
   495  			a.ref,
   496  			SizeU(elemSz),
   497  			bindings.Ref(Bool(signed)),
   498  			bindings.Ref(Bool(float)),
   499  			SizeU(start),
   500  			SliceData(outBuf),
   501  			SizeU(len(outBuf)),
   502  		),
   503  	)
   504  }