Skip to content
Snippets Groups Projects
Commit b30ebcee authored by David Sehnal's avatar David Sehnal
Browse files

Naming things

parent ac40a2b8
No related branches found
No related tags found
No related merge requests found
......@@ -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,
......
......@@ -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);
}
\ No newline at end of file
......@@ -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],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment