Skip to content

Commit

Permalink
feat(PrePost): filter with execution scope
Browse files Browse the repository at this point in the history
Add the possibility to only execute PrePost decorator during the reading
or writing phase or both.
  • Loading branch information
tperale committed Dec 8, 2024
1 parent 998d541 commit c2a11dd
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 10 deletions.
14 changes: 11 additions & 3 deletions src/decorators/prepost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
*/
import { ClassMetaDescriptor, type PropertyMetaDescriptor, createClassMetaDescriptor, createPropertyMetaDescriptor, recursiveGet } from './common'
import { relationExistsOrThrow } from '../error'
import { type ClassAndPropertyDecoratorType, type ClassAndPropertyDecoratorContext } from '../types'
import { ExecutionScope, type ClassAndPropertyDecoratorType, type ClassAndPropertyDecoratorContext } from '../types'
import { type Cursor, type BinaryCursorEndianness, BinaryCursor } from '../cursor'
import Meta from '../metadatas'

Expand All @@ -73,11 +73,17 @@ export interface PrePostOptions {
* Removes the decorator from metadata after its function is executed.
*/
once: boolean
/**
* Specifies whether the prepost function should be executed during
* the read phase, the write phase, or both.
*/
scope: ExecutionScope
}

export const PrePostOptionsDefault = {
primitiveCheck: true,
once: false,
scope: ExecutionScope.OnBoth,
}

/**
Expand Down Expand Up @@ -632,8 +638,10 @@ export function Endian<This> (endianness: BinaryCursorEndianness | ((instance: T
*
* @category Advanced Use
*/
export function usePrePost<This> (prepost: Array<PrePost<This>> | Array<PrePostClass<This>>, targetInstance: This, cursor: Cursor): void {
export function usePrePost<This> (prepost: Array<PrePost<This>> | Array<PrePostClass<This>>, targetInstance: This, cursor: Cursor, scope = ExecutionScope.OnBoth): void {
prepost.forEach((x) => {
x.func(targetInstance, cursor)
if ((x.options.scope & scope) > 0) {
x.func(targetInstance, cursor)
}
})
}
10 changes: 5 additions & 5 deletions src/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
isUnknownProperty,
type PropertyType,
} from './decorators/primitive'
import { EOF, type InstantiableObject } from './types'
import { EOF, ExecutionScope, type InstantiableObject } from './types'
import { useController, type ControllerReader } from './decorators/controller'
import { useTransformer } from './decorators/transformer'
import { useValidators } from './decorators/validator'
Expand Down Expand Up @@ -100,10 +100,10 @@ export function binread<Target> (content: Cursor, ObjectDefinition: Instantiable
return useBitField(bitfields, instance, content)
}

usePrePost(Meta.getClassPre(metadata), instance, content)
usePrePost(Meta.getClassPre(metadata), instance, content, ExecutionScope.OnRead)

Meta.getFields<Target>(metadata).forEach((field) => {
usePrePost(Meta.getPre(metadata, field.propertyName), instance, content)
usePrePost(Meta.getPre(metadata, field.propertyName), instance, content, ExecutionScope.OnRead)

// TODO [Cursor] Pass the field name information to add to the namespace
const finalRelationField = isUnknownProperty(field) ? useConditions(Meta.getConditions(field.metadata, field.propertyName), instance) : field
Expand All @@ -128,10 +128,10 @@ export function binread<Target> (content: Cursor, ObjectDefinition: Instantiable

instance[field.propertyName] = transformedValue
}
usePrePost(Meta.getPost(metadata, field.propertyName), instance, content)
usePrePost(Meta.getPost(metadata, field.propertyName), instance, content, ExecutionScope.OnRead)
})

usePrePost(Meta.getClassPost(metadata), instance, content)
usePrePost(Meta.getClassPost(metadata), instance, content, ExecutionScope.OnRead)

return instance
}
8 changes: 6 additions & 2 deletions src/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ export function binwrite<Target> (cursor: BinaryWriter, ObjectDefinition: Instan
return cursor
}

usePrePost(Meta.getClassPre(metadata), instance, cursor, ExecutionScope.OnWrite)

Meta.getFields<Target>(metadata).forEach((field) => {
usePrePost(Meta.getPre(metadata, field.propertyName), instance, cursor)
usePrePost(Meta.getPre(metadata, field.propertyName), instance, cursor, ExecutionScope.OnWrite)

const finalRelationField = isUnknownProperty(field) ? useConditions(Meta.getConditions(field.metadata, field.propertyName), instance) : field
if (finalRelationField !== undefined) {
Expand All @@ -80,9 +82,11 @@ export function binwrite<Target> (cursor: BinaryWriter, ObjectDefinition: Instan
// NullString should add back the \0
// targetType sin
}
usePrePost(Meta.getPost(metadata, field.propertyName), instance, cursor)
usePrePost(Meta.getPost(metadata, field.propertyName), instance, cursor, ExecutionScope.OnWrite)
})

usePrePost(Meta.getClassPost(metadata), instance, cursor, ExecutionScope.OnWrite)

return cursor
}

Expand Down

0 comments on commit c2a11dd

Please sign in to comment.