diff --git a/codecs/documented.ts b/codecs/documented.ts new file mode 100644 index 0000000..724a0b6 --- /dev/null +++ b/codecs/documented.ts @@ -0,0 +1,8 @@ +import { Codec, metadata, withMetadata } from "../common/mod.ts" + +export function documented(docs: string, inner: Codec): Codec { + return withMetadata( + metadata("$.documented", documented, docs, inner) as never, + inner, + ) +} diff --git a/codecs/mod.ts b/codecs/mod.ts index 3b73b07..575b816 100644 --- a/codecs/mod.ts +++ b/codecs/mod.ts @@ -7,6 +7,7 @@ export * from "./collections.ts" export * from "./compact.ts" export * from "./constant.ts" export * from "./deferred.ts" +export * from "./documented.ts" export * from "./float.ts" export * from "./hex.ts" export * from "./instance.ts" diff --git a/codecs/object.ts b/codecs/object.ts index 9fda377..36288b1 100644 --- a/codecs/object.ts +++ b/codecs/object.ts @@ -69,13 +69,13 @@ export type OutputObject = Expand< type UnionKeys = T extends T ? keyof T : never export type ObjectMembers = [ ...never extends T ? { - [K in keyof T]: - AnyCodec extends T[K] ? AnyCodec : - & UnionKeys> - & { - [L in keyof T]: K extends L ? never : UnionKeys> - }[number] extends (infer O extends keyof any) - ? [O] extends [never] ? Codec & {}> : Codec<{ [_ in O]?: never }> + [K in keyof T]: AnyCodec extends T[K] ? AnyCodec + : + & UnionKeys> + & { + [L in keyof T]: K extends L ? never : UnionKeys> + }[number] extends (infer O extends keyof any) + ? [O] extends [never] ? Codec & {}> : Codec<{ [_ in O]?: never }> : never } : T, diff --git a/common/codec.ts b/common/codec.ts index 26d2625..13afada 100644 --- a/common/codec.ts +++ b/common/codec.ts @@ -61,20 +61,12 @@ abstract class _Codec { } try { codecInspectCtx.set(this, null) - let content = "" - for (const metadata of this._metadata) { - if (metadata.type === "docs") { - // TODO: print docs in inspect - } else { - if (metadata.type === "atomic") { - content += metadata.name - } else if (metadata.type === "factory") { - content += `${metadata.name}(${inspect(metadata.args).replace(/^\[(?: (.+) |(.+))\]$/s, "$1$2")})` - } - break - } - } - content ||= "?" + const metadata = this._metadata[0] + const content = metadata + ? metadata.type === "atomic" + ? metadata.name + : `${metadata.name}(${inspect(metadata.args).replace(/^\[(?: (.+) |(.+))\]$/s, "$1$2")})` + : "?" id = codecInspectCtx.get(this) return id !== null ? `$${id} = ${content}` : content } finally { diff --git a/common/metadata.ts b/common/metadata.ts index 007e980..5b334c9 100644 --- a/common/metadata.ts +++ b/common/metadata.ts @@ -15,12 +15,6 @@ export type Metadata = Array< factory: (...args: any) => Codec args: any[] } - | { - type: "docs" - docs: string - factory?: never - args?: never - } > /** Metadata for an atomic codec */ @@ -38,7 +32,7 @@ export function metadata( | Metadata[] | [ name: string, - factory?: (...args: any) => Codec<[I, O]>, + factory?: (...args: any) => Codec, ...args: any[], ] ): Metadata { @@ -59,10 +53,6 @@ export function metadata( ] } -export function docs(docs: string): Metadata { - return [{ type: "docs", docs }] -} - export class CodecVisitor { #fallback?: (codec: Codec) => R #visitors = new Map[number] | Function, (codec: Codec, ...args: any[]) => R>()