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 }