192 lines
4.7 KiB
TypeScript
192 lines
4.7 KiB
TypeScript
import _ from "lodash"
|
|
import { Option, Some, None, Result, Ok, Err } from "ts-results-es";
|
|
import { z } from "zod";
|
|
|
|
export function UNUSED(_: unknown): void { }
|
|
|
|
export namespace type {
|
|
|
|
const NUMBER_MAX_LENGTH = 32
|
|
|
|
|
|
export const ErrorTypeSchema = z.union([
|
|
z.literal("Not Integer"),
|
|
z.literal("Not Unsigned Integer"),
|
|
z.literal("Not 32Bits Integer")
|
|
])
|
|
|
|
export type ErrorType = z.infer<typeof ErrorTypeSchema>
|
|
|
|
export const Integer = z.number().int()
|
|
export const UInteger = z.number().int().nonnegative()
|
|
|
|
export const UInt8 = UInteger.lt(Math.pow(2, 8))
|
|
export const UInt16 = UInteger.lt(Math.pow(2, 16))
|
|
export const UInt32 = UInteger.lt(Math.pow(2, 32))
|
|
|
|
export const Int8 = Integer.lt(Math.pow(2, 7)).gte(-Math.pow(2, 8))
|
|
export const Int16 = Integer.lt(Math.pow(2, 15)).gte(-Math.pow(2, 16))
|
|
export const Int32 = Integer.lt(Math.pow(2, 31)).gte(-Math.pow(2, 32))
|
|
|
|
export function numberToBytes(num: number, bytesLength: number, isRightHigh: boolean = false)
|
|
: Result<Uint8Array, ErrorType> {
|
|
// Check Integer
|
|
if (!Int32.safeParse(num).success && !UInt32.lte(32).safeParse(bytesLength).success) {
|
|
console.error(`Number : ${num}, 2 ^ 31 = ${2 ^ 31}`)
|
|
console.error(Int32.safeParse(num).error?.message)
|
|
return new Err("Not 32Bits Integer")
|
|
}
|
|
|
|
var array = new Uint8Array(bytesLength)
|
|
|
|
if (isRightHigh) {
|
|
for (let i = 0; i < bytesLength; i++) {
|
|
array[bytesLength - 1 - i] = ((num >> (i << 3)) & 0xFF)
|
|
}
|
|
} else {
|
|
for (let i = 0; i < bytesLength; i++) {
|
|
array[i] = ((num >> (i << 3)) & 0xFF)
|
|
}
|
|
}
|
|
|
|
return new Ok(array)
|
|
}
|
|
|
|
export function bytesToNumber(bytes: Uint8Array, isRightHigh: boolean = false): number {
|
|
let num = 0
|
|
const len = bytes.length
|
|
if (isRightHigh) {
|
|
for (let i = 0; i < len; i++) {
|
|
num += bytes[len - 1 - i] << (i << 3)
|
|
}
|
|
} else {
|
|
for (let i = 0; i < len; i++) {
|
|
num += bytes[i] << (i << 3)
|
|
}
|
|
}
|
|
return num
|
|
}
|
|
|
|
|
|
export function numberMatch(
|
|
srcNum: number,
|
|
destNum: number
|
|
): boolean;
|
|
|
|
export function numberMatch<T>(
|
|
srcNum: number,
|
|
destNum: number,
|
|
True: T,
|
|
False: T
|
|
): T;
|
|
|
|
export function numberMatch<T>(
|
|
srcNum: number,
|
|
destNum: number,
|
|
True: T = true as T,
|
|
False: T = false as T
|
|
): T {
|
|
const ret = (srcNum & destNum) === destNum;
|
|
return ret ? True : False;
|
|
}
|
|
|
|
export function numberMatchEnum() {
|
|
|
|
}
|
|
|
|
export function numberSetBit(num: number, loc: number): number {
|
|
return num | (1 << (loc - 1))
|
|
}
|
|
|
|
export function numberUnsetBit(num: number, loc: number): number {
|
|
return num & ~(1 << (loc - 1))
|
|
}
|
|
|
|
export function numberToggleBit(num: number, loc: number): number {
|
|
return num ^ (1 << (loc - 1))
|
|
}
|
|
|
|
export function numberBit(num: number, loc: number): number {
|
|
return (num >> (loc - 1)) & 1
|
|
}
|
|
|
|
export function numberHighBitsNum(num: number, maxLen: number = NUMBER_MAX_LENGTH): Result<number, ErrorType> {
|
|
if (!Int32.safeParse(num).success && maxLen > 32) {
|
|
return new Err("Not 32Bits Integer")
|
|
}
|
|
|
|
let cnt = 0
|
|
for (let i = 0; i < maxLen; i++) {
|
|
if (num & (1 << i)) {
|
|
cnt++
|
|
}
|
|
}
|
|
return new Ok(cnt)
|
|
}
|
|
|
|
export function numberLowBitsNum(num: number, maxLen: number): Result<number, ErrorType> {
|
|
if (!Int32.safeParse(num).success && maxLen > 32) {
|
|
return new Err("Not 32Bits Integer")
|
|
}
|
|
|
|
let cnt = 0
|
|
for (let i = 0; i < maxLen; i++) {
|
|
if (!(num & (1 << i))) {
|
|
cnt++
|
|
}
|
|
}
|
|
return new Ok(cnt)
|
|
}
|
|
|
|
export function isStringArray(obj: any): obj is Array<string> {
|
|
return z.string().array().safeParse(obj).success
|
|
}
|
|
|
|
export function isNumberArray(obj: any): obj is Array<number> {
|
|
return z.number().array().safeParse(obj).success
|
|
}
|
|
}
|
|
|
|
export namespace fun {
|
|
|
|
export function randomFromArray(array: Array<any>) {
|
|
return array[_.random(0, array.length - 1, false)]
|
|
}
|
|
|
|
export function sqlConditionFromArray(
|
|
columnName: string,
|
|
array: Array<string>,
|
|
type: "AND" | "OR"
|
|
): Option<string> {
|
|
let condition: string = ""
|
|
const len = array.length
|
|
if (len == 0) {
|
|
return None
|
|
}
|
|
for (let i = 0; i < len; i++) {
|
|
condition.concat(`${columnName}=${array[i]}`)
|
|
if (i != len - 1) {
|
|
condition.concat(` ${type} `)
|
|
}
|
|
}
|
|
|
|
return new Some(condition)
|
|
}
|
|
|
|
export function sqlConditionFromString(
|
|
columnName: string,
|
|
str: string,
|
|
type: "AND" | "OR",
|
|
delimiter: string = " "
|
|
): Option<string> {
|
|
if (str.length == 0) {
|
|
return None
|
|
}
|
|
|
|
const array = str.split(delimiter)
|
|
return sqlConditionFromArray(columnName, array, type)
|
|
}
|
|
}
|
|
|
|
|