using System.Runtime.CompilerServices; using Jint.Native; using Jint.Native.Promise; using Jint.Runtime; namespace Jint { public static class JsValueExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool AsBoolean(this JsValue value) { if (value._type != InternalTypes.Boolean) { ThrowWrongTypeException(value, "boolean"); } return ((JsBoolean) value)._value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double AsNumber(this JsValue value) { if (!value.IsNumber()) { ThrowWrongTypeException(value, "number"); } return ((JsNumber) value)._value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int AsInteger(this JsValue value) { return (int) ((JsNumber) value)._value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string AsString(this JsValue value) { if (!value.IsString()) { ThrowWrongTypeException(value, "string"); } return value.ToString(); } /// /// If the value is a Promise /// 1. If "Fulfilled" returns the value it was fulfilled with /// 2. If "Rejected" throws "PromiseRejectedException" with the rejection reason /// 3. If "Pending" throws "InvalidOperationException". Should be called only in "Settled" state /// Else /// returns the value intact /// /// value to unwrap /// inner value if Promise the value itself otherwise public static JsValue UnwrapIfPromise(this JsValue value) { if (value is PromiseInstance promise) { switch (promise.State) { case PromiseState.Pending: ExceptionHelper.ThrowInvalidOperationException("'UnwrapIfPromise' called before Promise was settled"); return null; case PromiseState.Fulfilled: return promise.Value; case PromiseState.Rejected: ExceptionHelper.ThrowPromiseRejectedException(promise.Value); return null; default: ExceptionHelper.ThrowArgumentOutOfRangeException(); return null; } } return value; } [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowWrongTypeException(JsValue value, string expectedType) { ExceptionHelper.ThrowArgumentException($"Expected {expectedType} but got {value._type}"); } } }