char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
dea05b4
main
1import { 2Error , 3ObjectCreate , 4ObjectDefineProperty as define , 5ObjectFreeze as freeze , 6ReflectConstruct as construct , 7WeakMap , 8WeakMapPrototypeGet as get , 9WeakMapPrototypeSet as set , 10} from "ext:core/primordials" ; 11 12export type FileReply < T > = 13| [ value :T , error :null ] 14| [ value :null , error :[ kind :string , message :string ]]; 15 16type FileErrorName = 17| "NotFound" 18| "PermissionDenied" 19| "AlreadyExists" 20| "NotEmpty" 21| "CrossDevice" 22| "NotADirectory" 23| "IsADirectory" 24| "InvalidInput" 25| "BadResource" 26| "Busy" 27| "BrokenPipe" 28| "NotSupported" 29| "IoError" ; 30type FileErrorConstructor = new ( message ?:string ) => Error ; 31const errors = ObjectCreate ( null ) as Readonly < Record < 32FileErrorName , 33FileErrorConstructor 34>>; 35const codes = new WeakMap < object , string >(); 36export function errorCode ( error :unknown ) :string | undefined { 37return get ( codes , error as object ); 38} 39for ( 40const name of [ 41"NotFound" , 42"PermissionDenied" , 43"AlreadyExists" , 44"NotEmpty" , 45"CrossDevice" , 46"NotADirectory" , 47"IsADirectory" , 48"InvalidInput" , 49"BadResource" , 50"Busy" , 51"BrokenPipe" , 52"NotSupported" , 53"IoError" , 54] 55) { 56const ctor = class extends Error { 57// @ts-expect-error Reflect.construct avoids a guest-replaceable superclass constructor. 58constructor ( message = "" ) { 59const self = construct ( Error , [ message ], new . target ) as Error ; 60define ( self , "name" , { value :name , writable :true , configurable :true }); 61return self ; 62} 63}; 64define ( ctor , "name" , { value :name , configurable :true }); 65define ( errors , name , { value :ctor , enumerable :true }); 66} 67freeze ( errors ); 68export { errors }; 69export function failure ( name :string , message :string ) :Error { 70const result = construct ( 71Error , 72[ message ], 73( errors as Record < string , FileErrorConstructor >)[ name ] || errors . IoError , 74) as Error ; 75const descriptor :{ 76value :string ; 77writable :boolean ; 78configurable :boolean ; 79} = ObjectCreate ( null ); 80descriptor . value = name ; 81descriptor . writable = true ; 82descriptor . configurable = true ; 83define ( result , "name" , descriptor ); 84set ( codes , result , name ); 85return result ; 86} 87export function result < T > ( reply :FileReply < T >) :T { 88if ( reply [ 1 ] !== null ) throw failure ( reply [ 1 ][ 0 ], reply [ 1 ][ 1 ]); 89return reply [ 0 ]; 90}