Skip to content

Commit

Permalink
fix primitive.
Browse files Browse the repository at this point in the history
  • Loading branch information
dojyorin committed Jan 21, 2024
1 parent 1142c52 commit 7973e09
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 99 deletions.
95 changes: 32 additions & 63 deletions src/primitive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,88 +12,57 @@ export type TypeStrict<T extends unknown, U extends boolean> = U extends true ?
* Map of primitive types and string that specify them.
*/
export interface PrimitiveMap{
"s": string;
"n": number;
"b": boolean;
"string": string;
"number": number;
"boolean": boolean;
}

function undef(strict?:boolean){
if(strict){
throw new Error();
}

return undefined;
}

/**
* Convert from dirty text to specified type.
* Enabling `strict` flag will throw exception if parsing is not possible.
* @example
* ```ts
* const value = typeDecode("123", "n", true);
* const value = typeDecode("123", "number", true);
* ```
*/
export function typeDecode<T extends keyof PrimitiveMap, U extends boolean>(text:MaybeString, type:T, strict?:U):TypeStrict<PrimitiveMap[T], U>{
switch(type){
case "s": return <PrimitiveMap[T]>typeS(text, strict);
case "n": return <PrimitiveMap[T]>typeN(text, strict);
case "b": return <PrimitiveMap[T]>typeB(text, strict);
default: throw new Error();
}
}
case "string": {
const v = String(text);

/**
* Convert from dirty text to string.
* Enabling `strict` flag will throw exception if parsing is not possible.
* @example
* ```ts
* const value = typeS("foo", true);
* ```
*/
export function typeS<T extends boolean>(text:MaybeString, strict?:T):TypeStrict<string, T>{
if(text === undefined || text === null){
if(strict){
throw new Error();
}
if(text === undefined || text === null){
return <TypeStrict<PrimitiveMap[T], U>>undef(strict);
}

return <TypeStrict<string, T>>undefined;
}
return <TypeStrict<PrimitiveMap[T], U>>v;
}

return String(text);
}
case "number": {
const v = Number(text);

/**
* Convert from dirty text to number.
* Enabling `strict` flag will throw exception if parsing is not possible.
* @example
* ```ts
* const value = typeN("123", true);
* ```
*/
export function typeN<T extends boolean>(text:MaybeString, strict?:T):TypeStrict<number, T>{
const n = Number(text);
if(text === undefined || text === null || isNaN(v)){
return <TypeStrict<PrimitiveMap[T], U>>undef(strict);
}

if(text === undefined || text === null || isNaN(n)){
if(strict){
throw new Error();
return <TypeStrict<PrimitiveMap[T], U>>v;
}

return <TypeStrict<number, T>>undefined;
}

return n;
}

/**
* Convert from dirty text to boolean.
* Enabling `strict` flag will throw exception if parsing is not possible.
* @example
* ```ts
* const value = typeB("true", true);
* ```
*/
export function typeB<T extends boolean>(text:MaybeString, strict?:T):TypeStrict<boolean, T>{
switch(text){
case "true": return true;
case "false": return false;
default: {
if(strict){
throw new Error();
case "boolean": {
switch(text){
case "true": return <TypeStrict<PrimitiveMap[T], U>>true;
case "false": return <TypeStrict<PrimitiveMap[T], U>>false;
default: return <TypeStrict<PrimitiveMap[T], U>>undef(strict);
}

return <TypeStrict<boolean, T>>undefined;
}

default: throw new Error();
}
}
47 changes: 11 additions & 36 deletions test/primitive.test.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,21 @@
import {assertEquals} from "../deps.test.ts";
import {typeDecode, typeS, typeN, typeB} from "../src/primitive.ts";
import {typeDecode} from "../src/primitive.ts";

Deno.test({
name: "Type: Decode",
fn(){
const result1 = typeDecode("foo", "s", true);
const result2 = typeDecode(null, "s");
const result1 = typeDecode("foo", "string", true);
const result2 = typeDecode(null, "string");
const result3 = typeDecode("12345", "number", true);
const result4 = typeDecode("foo", "number");
const result5 = typeDecode("true", "boolean", true);
const result6 = typeDecode("foo", "boolean");

assertEquals(result1, "foo");
assertEquals(result2, undefined);
}
});

Deno.test({
name: "Type: Parse String",
fn(){
const result1 = typeS("foo", true);
const result2 = typeN(null);

assertEquals(result1, "foo");
assertEquals(result2, undefined);
}
});

Deno.test({
name: "Type: Parse Number",
fn(){
const result1 = typeN("12345", true);
const result2 = typeN("foo");

assertEquals(result1, 12345);
assertEquals(result2, undefined);
}
});

Deno.test({
name: "Type: Parse Boolean",
fn(){
const result1 = typeB("true", true);
const result2 = typeN("foo");

assertEquals(result1, true);
assertEquals(result2, undefined);
assertEquals(result3, 12345);
assertEquals(result4, undefined);
assertEquals(result5, true);
assertEquals(result6, undefined);
}
});

0 comments on commit 7973e09

Please sign in to comment.