import { type ErrorFrame, Failure } from 'sts:failures';
import { type Option, type Result } from 'sts:result';
import { type JsonArray, type JsonObject, type JsonValue } from './json';
export type DecodeMode = 'sync' | 'async';
export type DecodeFormat = 'email' | 'uuid' | 'url' | 'iso-datetime';
export type ObjectKeyPolicy = 'strip' | 'strict' | 'passthrough';
export type DecodeObjectOptions = {
    readonly unknownKeys?: ObjectKeyPolicy;
};
export type DecodePathSegment = string | number;
export type DecodePath = readonly DecodePathSegment[];
export type DecodeIssue = {
    readonly code: string;
    readonly input?: unknown;
    readonly message: string;
    readonly path: DecodePath;
};
export type DecodeRefinementContext = {
    readonly path: DecodePath;
    // #[effects(add: [])]
    issue(code: string, message: string, input?: unknown): DecodeIssue;
};
export type DecodeRefinementResult = boolean | string | DecodeIssue | readonly DecodeIssue[];
export interface UrlLike {
    readonly hash: string;
    readonly host: string;
    readonly hostname: string;
    readonly href: string;
    readonly password: string;
    readonly pathname: string;
    readonly port: string;
    readonly protocol: string;
    readonly search: string;
    readonly username: string;
    // #[effects(add: [], unknown: [direct])]
    toJSON(): string;
    // #[effects(add: [], unknown: [direct])]
    toString(): string;
}
export type DecodeOutput<T, E, M extends DecodeMode = 'sync'> = M extends 'async' ? Promise<Result<T, E>> : Result<T, E>;
type MaybeDecodeOutput<T, E> = Result<T, E> | Promise<Result<T, E>>;
type AsyncModeOf<TReturn> = TReturn extends Promise<unknown> ? 'async' : 'sync';
export declare class DecodeFailure extends Failure {
    readonly path: DecodePath;
    // #[effects(add: [mut])]
    constructor(message?: string, options?: Readonly<{
        cause?: unknown;
        path?: DecodePath;
        trace?: readonly ErrorFrame[];
    }>);
    // #[effects(add: [], unknown: [direct])]
    at(segment: DecodePathSegment): this;
}
export type Decoder<T, E = DecodeFailure, M extends DecodeMode = 'sync'> = {
    // #[effects(add: [suspend.await], unknown: [direct])]
    decode(value: unknown): DecodeOutput<T, E, M>;
    // #[effects(add: [], unknown: [direct])]
    validateDecode(value: unknown): DecodeOutput<T, readonly DecodeIssue[], M>;
};
export type OptionalDecoder<T, E = DecodeFailure, M extends DecodeMode = 'sync'> = Decoder<T | undefined, E, M> & {
    readonly __soundscriptOptional: true;
    readonly inner: Decoder<T, E, M>;
};
type DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown, DecodeMode> ? TValue : never;
type DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E, DecodeMode> ? E : never;
type DecoderModeOf<TDecoder> = TDecoder extends {
    // #[effects(add: [suspend.await], unknown: [direct])]
    decode(value: unknown): infer TOutput;
} ? TOutput extends Promise<Result<unknown, unknown>> ? 'async' : 'sync' : never;
type MergeDecodeModes<M extends DecodeMode> = [
    M
] extends [
    never
] ? 'sync' : 'async' extends M ? 'async' : 'sync';
type ObjectShape = Record<string, Decoder<unknown, unknown, DecodeMode>>;
type TupleShape = readonly Decoder<unknown, unknown, DecodeMode>[];
type OptionalShapeKeys<TShape extends ObjectShape> = {
    readonly [K in keyof TShape]-?: TShape[K] extends OptionalDecoder<unknown, unknown, DecodeMode> ? K : never;
}[keyof TShape];
type RequiredShapeKeys<TShape extends ObjectShape> = Exclude<keyof TShape, OptionalShapeKeys<TShape>>;
type ObjectValueOfShape<TShape extends ObjectShape> = {
    readonly [K in RequiredShapeKeys<TShape>]: DecoderValue<TShape[K]>;
} & {
    readonly [K in OptionalShapeKeys<TShape>]?: Exclude<DecoderValue<TShape[K]>, undefined>;
};
type ShapeDecodeMode<TShape extends ObjectShape> = true extends {
    readonly [K in keyof TShape]: DecoderModeOf<TShape[K]> extends 'async' ? true : false;
}[keyof TShape] ? 'async' : 'sync';
type TupleDecodeMode<TElements extends TupleShape> = true extends {
    readonly [K in keyof TElements]: TElements[K] extends Decoder<unknown, unknown, 'async'> ? true : false;
}[number] ? 'async' : 'sync';
// #[effects(add: [mut], forward: [{ from: decode.some }])]
export declare function fromDecode<T, E, M extends DecodeMode = 'sync'>(decode: (value: unknown) => MaybeDecodeOutput<T, E>, validateDecode?: (value: unknown) => MaybeDecodeOutput<T, readonly DecodeIssue[]>): Decoder<T, E, M>;
export declare const string: Decoder<string>;
export declare const number: Decoder<number>;
export declare const boolean: Decoder<boolean>;
export declare const bigint: Decoder<bigint>;
export declare const undefinedValue: Decoder<undefined>;
export declare const url: Decoder<UrlLike>;
export declare const isoDate: Decoder<Date>;
export declare const jsonValue: Decoder<JsonValue>;
export declare const jsonObject: Decoder<JsonObject>;
export declare const jsonArray: Decoder<JsonArray>;
// #[effects(add: [mut], unknown: [direct])]
export declare function mapError<T, E1, E2, M extends DecodeMode>(decoder: Decoder<T, E1, M>, project: (error: E1) => E2): Decoder<T, E2, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function lazy<const TDecoder extends Decoder<unknown, unknown, DecodeMode>>(getDecoder: () => TDecoder): Decoder<DecoderValue<TDecoder>, DecoderError<TDecoder>, DecoderModeOf<TDecoder>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function optional<const TDecoder extends Decoder<unknown, unknown, DecodeMode>>(decoder: TDecoder): OptionalDecoder<Exclude<DecoderValue<TDecoder>, undefined>, DecoderError<TDecoder>, DecoderModeOf<TDecoder>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function optional<T, E, M extends DecodeMode>(decoder: Decoder<T, E, M>): OptionalDecoder<Exclude<T, undefined>, E, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function undefinedable<T, E, M extends DecodeMode>(decoder: Decoder<T, E, M>): Decoder<T | undefined, E, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function nullable<T, E, M extends DecodeMode>(decoder: Decoder<T, E, M>): Decoder<T | null, E, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function defaulted<TDecoder extends Decoder<unknown, unknown, DecodeMode>, TValue = Exclude<DecoderValue<TDecoder>, undefined>>(decoder: TDecoder & Decoder<TValue | undefined, DecoderError<TDecoder>, DecoderModeOf<TDecoder>>, fallback: TValue): Decoder<TValue, DecoderError<TDecoder>, DecoderModeOf<TDecoder>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function defaulted<TDecoder extends Decoder<unknown, unknown, DecodeMode>, TValue = Exclude<DecoderValue<TDecoder>, undefined>, TFallback extends TValue | Promise<TValue> = TValue | Promise<TValue>>(decoder: TDecoder & Decoder<TValue | undefined, DecoderError<TDecoder>, DecoderModeOf<TDecoder>>, fallback: () => TFallback): Decoder<TValue, DecoderError<TDecoder>, MergeDecodeModes<DecoderModeOf<TDecoder> | AsyncModeOf<TFallback>>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function preprocess<A, E, M extends DecodeMode, TPreprocessed>(decoder: Decoder<A, E, M>, project: (value: unknown) => TPreprocessed): Decoder<A, E, MergeDecodeModes<M | AsyncModeOf<TPreprocessed>>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function literal<const T extends string | number | boolean | null>(value: T): Decoder<T>;
// #[effects(add: [mut], unknown: [direct])]
export declare function min<T extends number | bigint, E, M extends DecodeMode>(decoder: Decoder<T, E, M>, minimum: T): Decoder<T, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function max<T extends number | bigint, E, M extends DecodeMode>(decoder: Decoder<T, E, M>, maximum: T): Decoder<T, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function minLength<T extends string | readonly unknown[], E, M extends DecodeMode>(decoder: Decoder<T, E, M>, minimum: number): Decoder<T, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function maxLength<T extends string | readonly unknown[], E, M extends DecodeMode>(decoder: Decoder<T, E, M>, maximum: number): Decoder<T, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function startsWith<E, M extends DecodeMode>(decoder: Decoder<string, E, M>, prefix: string): Decoder<string, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function endsWith<E, M extends DecodeMode>(decoder: Decoder<string, E, M>, suffix: string): Decoder<string, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function pattern<E, M extends DecodeMode>(decoder: Decoder<string, E, M>, expression: RegExp): Decoder<string, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function multipleOf<T extends number | bigint, E, M extends DecodeMode>(decoder: Decoder<T, E, M>, factor: T): Decoder<T, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function integer<E, M extends DecodeMode>(decoder: Decoder<number, E, M>): Decoder<number, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function format<E, M extends DecodeMode>(decoder: Decoder<string, E, M>, expectedFormat: DecodeFormat): Decoder<string, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function array<T, E>(item: Decoder<T, E, 'sync'>): Decoder<readonly T[], E | DecodeFailure, 'sync'>;
// #[effects(add: [mut], unknown: [direct])]
export declare function array<T, E>(item: Decoder<T, E, 'async'>): Decoder<readonly T[], E | DecodeFailure, 'async'>;
// #[effects(add: [mut], unknown: [direct])]
export declare function readonlyRecord<T, E, M extends DecodeMode>(valueDecoder: Decoder<T, E, M>): Decoder<Readonly<Record<string, T>>, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function tuple<const TElements extends TupleShape>(...elements: TElements): Decoder<{
    readonly [K in keyof TElements]: DecoderValue<TElements[K]>;
}, DecoderError<TElements[number]> | DecodeFailure, TupleDecodeMode<TElements>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function option<T, E, M extends DecodeMode>(item: Decoder<T, E, M>): Decoder<Option<T>, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function result<T, EValue, EDecodeValue, EDecodeError, MOk extends DecodeMode, MErr extends DecodeMode>(okDecoder: Decoder<T, EDecodeValue, MOk>, errDecoder: Decoder<EValue, EDecodeError, MErr>): Decoder<Result<T, EValue>, EDecodeValue | EDecodeError | DecodeFailure, MergeDecodeModes<MOk | MErr>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function object<const TShape extends ObjectShape>(shape: TShape, options?: DecodeObjectOptions): Decoder<ObjectValueOfShape<TShape>, DecoderError<TShape[keyof TShape]> | DecodeFailure, ShapeDecodeMode<TShape>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function strictObject<const TShape extends ObjectShape>(shape: TShape): Decoder<ObjectValueOfShape<TShape>, DecoderError<TShape[keyof TShape]> | DecodeFailure, ShapeDecodeMode<TShape>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function passthroughObject<const TShape extends ObjectShape>(shape: TShape): Decoder<ObjectValueOfShape<TShape>, DecoderError<TShape[keyof TShape]> | DecodeFailure, ShapeDecodeMode<TShape>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function field<K extends string, T, E, M extends DecodeMode>(key: K, decoder: Decoder<T, E, M>): Decoder<T, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function optionalField<K extends string, T, E, M extends DecodeMode>(key: K, decoder: Decoder<T, E, M>): Decoder<T | undefined, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function union<A, B, ELeft, ERight, MLeft extends DecodeMode, MRight extends DecodeMode>(left: Decoder<A, ELeft, MLeft>, right: Decoder<B, ERight, MRight>): Decoder<A | B, ELeft | ERight | DecodeFailure, MergeDecodeModes<MLeft | MRight>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function map<A, B, E, M extends DecodeMode, TProjected>(decoder: Decoder<A, E, M>, project: (value: A) => TProjected): Decoder<Awaited<TProjected>, E, MergeDecodeModes<M | AsyncModeOf<TProjected>>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function andThen<A, TNext extends Decoder<unknown, E, DecodeMode>, E, M extends DecodeMode>(decoder: Decoder<A, E, M>, project: (value: A) => TNext): Decoder<DecoderValue<TNext>, E, MergeDecodeModes<M | DecoderModeOf<TNext>>>;
// #[effects(add: [mut], unknown: [direct])]
export declare function refine<A, B extends A, E, M extends DecodeMode>(decoder: Decoder<A, E, M>, predicate: (value: A, ctx: DecodeRefinementContext) => value is B, message: string): Decoder<B, E | DecodeFailure, M>;
// #[effects(add: [mut], unknown: [direct])]
export declare function refine<A, E, M extends DecodeMode, TResult extends DecodeRefinementResult | Promise<DecodeRefinementResult>>(decoder: Decoder<A, E, M>, predicate: (value: A, ctx: DecodeRefinementContext) => TResult, message: string): Decoder<A, E | DecodeFailure, MergeDecodeModes<M | AsyncModeOf<TResult>>>;
export {};
