diff --git a/.gitignore b/.gitignore index 25eac54..4e00445 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,4 @@ dist # Editor settings .idea +.vscode diff --git a/src/scalar/text.test.ts b/src/scalar/text.test.ts new file mode 100644 index 0000000..dee83d9 --- /dev/null +++ b/src/scalar/text.test.ts @@ -0,0 +1,33 @@ +import { DataType } from '@apache-arrow/esnext-esm'; +import test from 'ava'; + +import { Text } from './text.js'; + +// eslint-disable-next-line unicorn/no-null +[null, undefined].forEach((v) => { + test(`should set values to empty string when ${v} is passed`, (t) => { + const s = new Text(v); + t.is(s.value, ''); + t.is(s.valid, false); + t.true(DataType.isUtf8(s.dataType)); + }); +}); + +[ + { value: '', expected: '' }, + { value: 'test string', expected: 'test string' }, + { value: String('new string object'), expected: 'new string object' }, + { value: new Text('new text object'), expected: 'new text object' }, + { value: new TextEncoder().encode('test'), expected: 'test' }, +].forEach(({ value, expected }, index) => { + test(`valid strings: '${value}' (${index})`, (t) => { + const s = new Text(value); + t.is(s.valid, true); + t.is(s.value, expected); + t.true(DataType.isUtf8(s.dataType)); + }); +}); + +test('should throw when unable to set value', (t) => { + t.throws(() => new Text({ value: {} }), { message: "Unable to set '[object Object]' as Text" }); +}); diff --git a/src/scalar/text.ts b/src/scalar/text.ts new file mode 100644 index 0000000..deb4e41 --- /dev/null +++ b/src/scalar/text.ts @@ -0,0 +1,61 @@ +import { Utf8 as ArrowString } from '@apache-arrow/esnext-esm'; + +import { Scalar } from './scalar.js'; +import { isInvalid, NULL_VALUE } from './util.js'; + +export class Text implements Scalar { + private _valid = false; + private _value = ''; + + public constructor(v: unknown) { + this.value = v; + return this; + } + + public get dataType() { + return new ArrowString(); + } + + public get valid(): boolean { + return this._valid; + } + + public get value(): string { + return this._value; + } + + public set value(value: unknown) { + if (isInvalid(value)) { + this._valid = false; + return; + } + + if (typeof value === 'string') { + this._value = value; + this._valid = true; + return; + } + + if (value instanceof Uint8Array) { + this._value = new TextDecoder().decode(value); + this._valid = true; + return; + } + + if (typeof value!.toString === 'function' && value!.toString !== Object.prototype.toString) { + this._value = value!.toString(); + this._valid = true; + return; + } + + throw new Error(`Unable to set '${value}' as Text`); + } + + public toString() { + if (this._valid) { + return this._value.toString(); + } + + return NULL_VALUE; + } +}