2021-04-25 08:42:21 +00:00
|
|
|
import type { DecoderState } from "./decoder";
|
2022-01-26 13:15:35 +00:00
|
|
|
import type { EncoderState } from "./encoder";
|
2021-03-17 09:21:48 +00:00
|
|
|
import type { Value } from "./values";
|
2021-06-01 14:46:23 +00:00
|
|
|
import { ReaderStateOptions } from "./reader";
|
2021-03-17 09:21:48 +00:00
|
|
|
|
2021-05-17 12:54:06 +00:00
|
|
|
export type EmbeddedTypeEncode<T> = {
|
2021-04-24 19:59:52 +00:00
|
|
|
encode(s: EncoderState, v: T): void;
|
2021-04-25 08:42:21 +00:00
|
|
|
}
|
2021-04-24 19:59:52 +00:00
|
|
|
|
2021-05-17 12:54:06 +00:00
|
|
|
export type EmbeddedTypeDecode<T> = {
|
2021-04-25 08:42:21 +00:00
|
|
|
decode(s: DecoderState): T;
|
2021-06-01 14:46:23 +00:00
|
|
|
fromValue(v: Value<GenericEmbedded>, options: ReaderStateOptions): T;
|
2021-04-24 19:59:52 +00:00
|
|
|
}
|
2021-03-17 09:21:48 +00:00
|
|
|
|
2021-05-17 12:54:06 +00:00
|
|
|
export type EmbeddedType<T> = EmbeddedTypeEncode<T> & EmbeddedTypeDecode<T>;
|
2021-04-25 08:42:21 +00:00
|
|
|
|
2021-05-17 12:54:06 +00:00
|
|
|
export class Embedded<T> {
|
2021-04-24 19:59:52 +00:00
|
|
|
embeddedValue: T;
|
|
|
|
|
|
|
|
constructor(embeddedValue: T) {
|
|
|
|
this.embeddedValue = embeddedValue;
|
2021-03-17 09:21:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
equals(other: any, is: (a: any, b: any) => boolean) {
|
2021-05-17 12:54:06 +00:00
|
|
|
return isEmbedded<T>(other) && is(this.embeddedValue, other.embeddedValue);
|
2021-03-17 09:21:48 +00:00
|
|
|
}
|
|
|
|
|
2022-01-26 13:15:35 +00:00
|
|
|
toString(): string {
|
2024-02-05 21:38:49 +00:00
|
|
|
return '#:' + (this.embeddedValue as any).toString();
|
2021-03-17 09:21:48 +00:00
|
|
|
}
|
2022-01-22 22:38:02 +00:00
|
|
|
|
|
|
|
__as_preserve__<R>(): T extends R ? Value<R> : never {
|
|
|
|
return this as any;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __from_preserve__<T>(v: Value<T>): undefined | Embedded<T> {
|
|
|
|
return isEmbedded<T>(v) ? v : void 0;
|
|
|
|
}
|
2021-03-17 09:21:48 +00:00
|
|
|
}
|
|
|
|
|
2021-05-17 12:54:06 +00:00
|
|
|
export function embed<T>(embeddedValue: T): Embedded<T> {
|
|
|
|
return new Embedded(embeddedValue);
|
2021-04-24 19:59:52 +00:00
|
|
|
}
|
|
|
|
|
2021-05-17 12:54:06 +00:00
|
|
|
export function isEmbedded<T>(v: Value<T>): v is Embedded<T> {
|
2021-04-24 19:59:52 +00:00
|
|
|
return typeof v === 'object' && 'embeddedValue' in v;
|
2021-03-17 09:21:48 +00:00
|
|
|
}
|
|
|
|
|
2021-05-17 12:54:06 +00:00
|
|
|
export class GenericEmbedded {
|
2021-04-24 19:59:52 +00:00
|
|
|
generic: Value;
|
|
|
|
|
|
|
|
constructor(generic: Value) {
|
|
|
|
this.generic = generic;
|
|
|
|
}
|
|
|
|
|
|
|
|
equals(other: any, is: (a: any, b: any) => boolean) {
|
|
|
|
return typeof other === 'object' && 'generic' in other && is(this.generic, other.generic);
|
|
|
|
}
|
|
|
|
|
2022-01-26 13:15:35 +00:00
|
|
|
toString(): string {
|
|
|
|
return this.generic.toString();
|
2021-04-24 19:59:52 +00:00
|
|
|
}
|
2021-03-17 09:21:48 +00:00
|
|
|
}
|