// Preserves Values.

import type { Bytes } from './bytes';
import type { DoubleFloat, SingleFloat } from './float';
import type { Annotated } from './annotated';
import type { Set, Dictionary } from './dictionary';
import type { Embedded, GenericEmbedded } from './embedded';

export type Value<T = GenericEmbedded> =
    | Atom
    | Compound<T>
    | Embedded<T>
    | Annotated<T>;
export type Atom =
    | boolean
    | SingleFloat
    | DoubleFloat
    | number
    | string
    | Bytes
    | symbol;
export type Compound<T = GenericEmbedded> =
    | (Array<Value<T>> | [Value<T>]) & { label: Value<T> }
      // ^ expanded from definition of Record<> in record.ts,
      // because if we use Record<Value<T>, Tuple<Value<T>>, T>,
      // TypeScript currently complains about circular use of Value<T>,
      // and if we use Record<any, any, T>, it accepts it but collapses
      // Value<T> to any.
    | Array<Value<T>>
    | Set<T>
    | Dictionary<T>;
