
import { Nullable, IDisposable, disposeSafe, defaultOf, Exception, IEqualityComparer, IComparer, structuralHash, equals } from "./Util.ts";
import { int32 } from "./Int32.ts";
import { HashIdentity_Structural, ComparisonIdentity_Structural } from "./FSharp.Collections.ts";
import { nonNullValue, Option } from "./Option.ts";
import { NullReferenceException_$ctor, ArgumentNullException_$ctor_Z721C83C5 } from "./System.ts";
import { FSharpChoice$2_$union, FSharpChoice$2_Choice2Of2, FSharpChoice$2_Choice1Of2 } from "./Choice.ts";
import { StringBuilder__Append_Z721C83C5 } from "./System.Text.ts";

export const LanguagePrimitives_GenericEqualityComparer: any = {
    Equals(x: any, y: any): boolean {
        return equals(x, y);
    },
    GetHashCode(x_1: any): int32 {
        return structuralHash(x_1) | 0;
    },
};

export const LanguagePrimitives_GenericEqualityERComparer: any = {
    Equals(x: any, y: any): boolean {
        return equals(x, y);
    },
    GetHashCode(x_1: any): int32 {
        return structuralHash(x_1) | 0;
    },
};

export function LanguagePrimitives_FastGenericComparer<T>(): IComparer<T> {
    return ComparisonIdentity_Structural<T>();
}

export function LanguagePrimitives_FastGenericComparerFromTable<T>(): IComparer<T> {
    return ComparisonIdentity_Structural<T>();
}

export function LanguagePrimitives_FastGenericEqualityComparer<T>(): IEqualityComparer<T> {
    return HashIdentity_Structural<T>();
}

export function LanguagePrimitives_FastGenericEqualityComparerFromTable<T>(): IEqualityComparer<T> {
    return HashIdentity_Structural<T>();
}

export function Operators_Failure(message: string): any {
    return new Exception(message);
}

export function Operators_FailurePattern(exn: Exception): Option<string> {
    return exn.message;
}

export function Operators_NullArg<$a>(argumentName: string): $a {
    throw ArgumentNullException_$ctor_Z721C83C5(argumentName);
}

export function Operators_Using<T extends IDisposable, R>(resource: T, action: ((arg0: T) => R)): R {
    try {
        return action(resource);
    }
    finally {
        if (equals(resource, defaultOf())) {
        }
        else {
            let copyOfStruct: T = resource;
            disposeSafe(copyOfStruct);
        }
    }
}

export function Operators_Lock<$a, $b>(_lockObj: $a, action: (() => $b)): $b {
    return action();
}

export function Operators_IsNull<T>(value: T): boolean {
    if (equals(value, defaultOf())) {
        return true;
    }
    else {
        return false;
    }
}

export function Operators_IsNotNull<T>(value: T): boolean {
    if (equals(value, defaultOf())) {
        return false;
    }
    else {
        return true;
    }
}

export function Operators_IsNullV<T extends any>(value: Nullable<T>): boolean {
    return !(value != null);
}

export function Operators_NonNull<T>(value: T): T {
    if (equals(value, defaultOf())) {
        throw NullReferenceException_$ctor();
    }
    else {
        return value;
    }
}

export function Operators_NonNullV<T extends any>(value: Nullable<T>): T {
    if (value != null) {
        return nonNullValue(value);
    }
    else {
        throw NullReferenceException_$ctor();
    }
}

export function Operators_NullMatchPattern<T>(value: T): FSharpChoice$2_$union<void, T> {
    if (equals(value, defaultOf())) {
        return FSharpChoice$2_Choice1Of2<void, T>(undefined);
    }
    else {
        return FSharpChoice$2_Choice2Of2<void, T>(value);
    }
}

export function Operators_NullValueMatchPattern<T extends any>(value: Nullable<T>): FSharpChoice$2_$union<void, T> {
    if (value != null) {
        return FSharpChoice$2_Choice2Of2<void, T>(nonNullValue(value));
    }
    else {
        return FSharpChoice$2_Choice1Of2<void, T>(undefined);
    }
}

export function Operators_NonNullQuickPattern<T>(value: T): T {
    if (equals(value, defaultOf())) {
        throw NullReferenceException_$ctor();
    }
    else {
        return value;
    }
}

export function Operators_NonNullQuickValuePattern<T extends any>(value: Nullable<T>): T {
    if (value != null) {
        return nonNullValue(value);
    }
    else {
        throw NullReferenceException_$ctor();
    }
}

export function Operators_WithNull<T>(value: T): T {
    return value;
}

export function Operators_WithNullV<T extends any>(value: T): T {
    return value;
}

export function Operators_NullV<T extends any>(): Nullable<T> {
    return null;
}

export function Operators_NullArgCheck<T>(argumentName: string, value: T): T {
    if (equals(value, defaultOf())) {
        throw ArgumentNullException_$ctor_Z721C83C5(argumentName);
    }
    else {
        return value;
    }
}

export function ExtraTopLevelOperators_LazyPattern<$a>(input: any): $a {
    return input.Value;
}

export function PrintfModule_PrintFormatToStringBuilderThen<$a, $b>(continuation: (() => $a), builder: any, format: any): $b {
    return format.cont((s: string): $a => {
        StringBuilder__Append_Z721C83C5(builder, s);
        return continuation();
    });
}

export function PrintfModule_PrintFormatToStringBuilder<$a>(builder: any, format: any): $a {
    return PrintfModule_PrintFormatToStringBuilderThen<void, $a>((): void => {
    }, builder, format);
}

