Example #1
0
 public static MondValue Bind <T>(MondState state = null, MondBindingOptions options = MondBindingOptions.None)
 => MondObjectBinder.Bind(typeof(T), out var dummy, state, options);
Example #2
0
        public static MondValue MarshalToMond(
            object value,
            MondValueType expectedType,
            MondState state,
            MondBindingOptions options)
        {
            if (value == null)
            {
                return(MondValue.Null);
            }

            if (expectedType == MondValueType.Object)
            {
                if (state == null)
                {
                    throw new ArgumentNullException(
                              nameof(state),
                              "Must have a valid MondState when binding an object");
                }

                return(MondObjectBinder.Bind(value.GetType(), value, state, options));
            }

            if (!TypeConverter.MatchType(expectedType, value.GetType()))
            {
                throw new ArgumentException("Given value does not match expected type", nameof(value));
            }

            if (value is MondValue mond)
            {
                return(mond);
            }

            var type = value.GetType();

            if (type.IsConstructedGenericType && (type.GetGenericTypeDefinition() == typeof(Nullable <>)))
            {
                var     innerType = type.GetGenericArguments()[0];
                dynamic nullable  = value;
                if (!TypeConverter.MatchType(expectedType, innerType) ||
                    (!nullable.HasValue &&
                     (expectedType != MondValueType.Null) &&
                     (expectedType != MondValueType.Undefined)))
                {
                    throw new ArgumentException("Given value does not match expected type", nameof(value));
                }

                value = nullable.Value;
            }

            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (expectedType)
            {
            case MondValueType.False:
            case MondValueType.True: return((bool)value);

            case MondValueType.Null: return(MondValue.Null);

            case MondValueType.Undefined: return(MondValue.Undefined);

            case MondValueType.String: return(value.ToString());

            case MondValueType.Number: return((double)Convert.ChangeType(value, typeof(double)));

            case MondValueType.Function:
                var info = value.GetType().GetTypeInfo();
                if (value is MulticastDelegate || (info.BaseType == typeof(MulticastDelegate)))
                {
                    return(MondObjectBinder.Bind(value as MulticastDelegate));
                }

                if (value is Delegate || (info.BaseType == typeof(Delegate)))
                {
                    return(MondObjectBinder.Bind(value as Delegate));
                }

                throw new NotSupportedException("Unsupported delegate type");

            case MondValueType.Object:
                return(MondObjectBinder.Bind(value.GetType(), value, null, MondBindingOptions.AutoLock));

            default:
                TypeConverter.UnsupportedMondTypeError(expectedType);
                break;
            }

            return(null); // we should never get here
        }