Browse Source

Naming things

David Sehnal 7 years ago
parent
commit
b30ebceeef
3 changed files with 29 additions and 22 deletions
  1. 3 1
      src/data/data.ts
  2. 25 20
      src/data/schema.ts
  3. 1 1
      src/data/spec/schema.spec.ts

+ 3 - 1
src/data/data.ts

@@ -55,7 +55,9 @@ export interface Field {
     str(row: number): string | null,
     int(row: number): number,
     float(row: number): number,
-    bin(row: number): Uint8Array | null,
+
+    /** The 'intrinsic value' of the field, e.g., array, binary data, ... */
+    value(row: number): any,
 
     presence(row: number): ValuePresence,
 

+ 25 - 20
src/data/schema.ts

@@ -20,14 +20,11 @@ import * as Data from './data'
  *
  * const mmCIF = { atom_site };
  */
-export type BlockDefinition = { [category: string]: CategoryDefinition }
-export type CategoryDefinition = { '@alias'?: string } & { [field: string]: Field.Schema<any> }
 
-export type BlockInstance<Definition extends BlockDefinition> = Block<{ [C in keyof Definition]: CategoryInstance<Definition[C]> }>
-export type CategoryInstance<Definition extends CategoryDefinition> = Category<{ [F in keyof Definition]: Field<Definition[F]['type']> }>
+//////////////////////////////////////////////
 
-export function apply<Definition extends BlockDefinition>(schema: Definition, block: Data.Block): BlockInstance<Definition> {
-    return createBlock(schema, block) as BlockInstance<Definition>;
+export function apply<Schema extends Block.Schema>(schema: Schema, block: Data.Block): Block.Instance<Schema> {
+    return createBlock(schema, block) as Block.Instance<Schema>;
 }
 
 export type Block<Categories> = Categories & {
@@ -36,12 +33,22 @@ export type Block<Categories> = Categories & {
     _getCategory(name: string): Data.Category | undefined
 }
 
+export namespace Block {
+    export type Schema = { [category: string]: Category.Schema }
+    export type Instance<T extends Schema> = Block<{ [C in keyof T]: Category.Instance<T[C]> }>
+}
+
 export type Category<Fields> = Fields & {
     readonly _rowCount: number,
     /** For accessing 'non-standard' fields */
     _getField(name: string): Data.Field | undefined
 }
 
+export namespace Category {
+    export type Schema = { '@alias'?: string } & { [field: string]: Field.Schema<any> }
+    export type Instance<T extends Schema> = Category<{ [F in keyof T]: Field<T[F]['type']> }>
+}
+
 export interface Field<T> {
     readonly isDefined: boolean,
     value(row: number): T,
@@ -53,6 +60,13 @@ export interface Field<T> {
 }
 
 export namespace Field {
+    export interface Schema<T> { type: T, ctor: (field: Data.Field) => Field<T>, undefinedField: Data.Field, alias?: string };
+    export interface Spec { undefinedField?: Data.Field, alias?: string }
+
+    export function str(spec?: Spec) { return createSchema(spec, Str); }
+    export function int(spec?: Spec) { return createSchema(spec, Int); }
+    export function float(spec?: Spec) { return createSchema(spec, Float); }
+
     function create<T>(field: Data.Field, value: (row: number) => T, toArray: Field<T>['toArray']): Field<T> {
         return { isDefined: field.isDefined, value, presence: field.presence, areValuesEqual: field.areValuesEqual, stringEquals: field.stringEquals, toArray };
     }
@@ -60,14 +74,13 @@ export namespace Field {
     function Str(field: Data.Field) { return create(field, field.str, field.toStringArray); }
     function Int(field: Data.Field) { return create(field, field.int, field.toNumberArray); }
     function Float(field: Data.Field) { return create(field, field.float, field.toNumberArray); }
-    function Bin(field: Data.Field) { return create(field, field.bin, (s, e, ctor) => void 0); }
 
     const DefaultUndefined: Data.Field = {
         isDefined: false,
         str: row => null,
         int: row => 0,
         float: row => 0,
-        bin: row => null,
+        value: row => null,
 
         presence: row => Data.ValuePresence.NotSpecified,
         areValuesEqual: (rowA, rowB) => true,
@@ -82,23 +95,15 @@ export namespace Field {
         toNumberArray: (startRow, endRowExclusive, ctor) => new Uint8Array(endRowExclusive - startRow) as any
     };
 
-    export interface Schema<T> { type: T, ctor: (field: Data.Field) => Field<T>, undefinedField: Data.Field, alias?: string };
-    export interface Spec { undefinedField?: Data.Field, alias?: string }
-
     function createSchema<T>(spec: Spec | undefined, ctor: (field: Data.Field) => Field<T>): Schema<T> {
         return { type: 0 as any, ctor, undefinedField: (spec && spec.undefinedField) || DefaultUndefined, alias: spec && spec.alias };
     }
-
-    export function str(spec?: Spec) { return createSchema(spec, Str); }
-    export function int(spec?: Spec) { return createSchema(spec, Int); }
-    export function float(spec?: Spec) { return createSchema(spec, Float); }
-    export function bin(spec?: Spec) { return createSchema(spec, Bin); }
 }
 
 class _Block implements Block<any> { // tslint:disable-line:class-name
     header = this._block.header;
     getCategory(name: string) { return this._block.categories[name]; }
-    constructor(private _block: Data.Block, schema: BlockDefinition) {
+    constructor(private _block: Data.Block, schema: Block.Schema) {
         for (const k of Object.keys(schema)) {
             Object.defineProperty(this, k, { value: createCategory(k, schema[k], _block), enumerable: true, writable: false, configurable: false });
         }
@@ -108,7 +113,7 @@ class _Block implements Block<any> { // tslint:disable-line:class-name
 class _Category implements Category<any> { // tslint:disable-line:class-name
     _rowCount = this._category.rowCount;
     _getField(name: string) { return this._category.getField(name); }
-    constructor(private _category: Data.Category, schema: CategoryDefinition) {
+    constructor(private _category: Data.Category, schema: Category.Schema) {
         const fieldKeys = Object.keys(schema).filter(k => k !== '@alias');
         const cache = Object.create(null);
         for (const k of fieldKeys) {
@@ -127,11 +132,11 @@ class _Category implements Category<any> { // tslint:disable-line:class-name
     }
 }
 
-function createBlock(schema: BlockDefinition, block: Data.Block): any {
+function createBlock(schema: Block.Schema, block: Data.Block): any {
     return new _Block(block, schema);
 }
 
-function createCategory(key: string, schema: CategoryDefinition, block: Data.Block) {
+function createCategory(key: string, schema: Category.Schema, block: Data.Block) {
     const cat = block.categories[schema['@alias'] || key] || Data.Category.Empty;
     return new _Category(cat, schema);
 }

+ 1 - 1
src/data/spec/schema.spec.ts

@@ -13,7 +13,7 @@ function Field(values: any[]): Data.Field {
         str: row => '' + values[row],
         int: row => +values[row] || 0,
         float: row => +values[row] || 0,
-        bin: row => null,
+        value: row => values[row],
 
         presence: row => Data.ValuePresence.Present,
         areValuesEqual: (rowA, rowB) => values[rowA] === values[rowB],