Ejemplo n.º 1
0
 public override ValueTask <FluidValue> GetValueAsync(string name, TemplateContext context)
 {
     return(name switch
     {
         "length" => new ValueTask <FluidValue>(NumberValue.Create(Length)),
         "index" => new ValueTask <FluidValue>(NumberValue.Create(Index)),
         "index0" => new ValueTask <FluidValue>(NumberValue.Create(Index0)),
         "rindex" => new ValueTask <FluidValue>(NumberValue.Create(RIndex)),
         "rindex0" => new ValueTask <FluidValue>(NumberValue.Create(RIndex0)),
         "first" => new ValueTask <FluidValue>(BooleanValue.Create(First)),
         "last" => new ValueTask <FluidValue>(BooleanValue.Create(Last)),
         _ => new ValueTask <FluidValue>(NilValue.Instance),
     });
Ejemplo n.º 2
0
        public static FluidValue Create(object value, TemplateOptions options)
        {
            if (value == null)
            {
                return(NilValue.Instance);
            }

            if (value is FluidValue fluidValue)
            {
                return(fluidValue);
            }

            if (options.ValueConverters.Count > 0)
            {
                foreach (var valueConverter in options.ValueConverters)
                {
                    var result = valueConverter(value);

                    if (result != null)
                    {
                        // If a converter returned a FluidValue instance use it directly
                        if (result is FluidValue resultFluidValue)
                        {
                            return(resultFluidValue);
                        }

                        // Otherwise stop custom conversions

                        value = result;
                        break;
                    }
                }
            }

            var typeOfValue = value.GetType();

            switch (System.Type.GetTypeCode(typeOfValue))
            {
            case TypeCode.Boolean:
                return(BooleanValue.Create(Convert.ToBoolean(value)));

            case TypeCode.Byte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
                return(NumberValue.Create(Convert.ToUInt32(value)));

            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.Int32:
                return(NumberValue.Create(Convert.ToInt32(value)));

            case TypeCode.UInt64:
            case TypeCode.Int64:
            case TypeCode.Decimal:
            case TypeCode.Double:
            case TypeCode.Single:
                return(NumberValue.Create(Convert.ToDecimal(value)));

            case TypeCode.Empty:
                return(NilValue.Instance);

            case TypeCode.Object:

                switch (value)
                {
                case DateTimeOffset dateTimeOffset:
                    return(new DateTimeValue(dateTimeOffset));

                case IDictionary <string, object> dictionary:
                    return(new DictionaryValue(new ObjectDictionaryFluidIndexable(dictionary, options)));

                case IDictionary <string, FluidValue> fluidDictionary:
                    return(new DictionaryValue(new FluidValueDictionaryFluidIndexable(fluidDictionary)));

                case IDictionary otherDictionary:
                    return(new DictionaryValue(new DictionaryDictionaryFluidIndexable(otherDictionary, options)));

                case FluidValue[] array:
                    return(new ArrayValue(array));

                case IList <FluidValue> list:
                    return(new ArrayValue(list));

                case IEnumerable <FluidValue> enumerable:
                    return(new ArrayValue(enumerable));

                case IList list:
                    var values = new List <FluidValue>(list.Count);
                    foreach (var item in list)
                    {
                        values.Add(Create(item, options));
                    }
                    return(new ArrayValue(values));

                case IEnumerable enumerable:
                    var fluidValues = new List <FluidValue>();
                    foreach (var item in enumerable)
                    {
                        fluidValues.Add(Create(item, options));
                    }
                    return(new ArrayValue(fluidValues));
                }

                return(new ObjectValue(value));

            case TypeCode.DateTime:
                return(new DateTimeValue((DateTime)value));

            case TypeCode.Char:
            case TypeCode.String:
                return(new StringValue(Convert.ToString(value, CultureInfo.InvariantCulture)));

            default:
                throw new InvalidOperationException();
            }
        }
Ejemplo n.º 3
0
        public static FluidValue Create(object value)
        {
            if (value == null)
            {
                return(NilValue.Instance);
            }

            if (value is FluidValue fluidValue)
            {
                return(fluidValue);
            }

            var typeOfValue = value.GetType();

            // First check for a specific type conversion before falling back to an automatic one
            var mapping = GetTypeMapping(typeOfValue);

            if (mapping != null)
            {
                return(mapping(value));
            }

            switch (System.Type.GetTypeCode(typeOfValue))
            {
            case TypeCode.Boolean:
                return(BooleanValue.Create(Convert.ToBoolean(value)));

            case TypeCode.Decimal:
            case TypeCode.Double:
            case TypeCode.Single:
                return(NumberValue.Create(Convert.ToDouble(value)));

            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
                return(NumberValue.Create(Convert.ToDouble(value), true));

            case TypeCode.Empty:
                return(NilValue.Instance);

            case TypeCode.Object:

                if (value == null)
                {
                    return(NilValue.Instance);
                }

                switch (value)
                {
                case FluidValue fluid:
                    return(fluid);

                case DateTimeOffset dateTimeOffset:
                    return(new DateTimeValue(dateTimeOffset));

                case IDictionary <string, object> dictionary:
                    return(new DictionaryValue(new ObjectDictionaryFluidIndexable(dictionary)));

                case IDictionary <string, FluidValue> fluidDictionary:
                    return(new DictionaryValue(new FluidValueDictionaryFluidIndexable(fluidDictionary)));

                case IDictionary otherDictionary:
                    return(new DictionaryValue(new DictionaryDictionaryFluidIndexable(otherDictionary)));

                case IList <FluidValue> list:
                    return(new ArrayValue(list));

                case IEnumerable <FluidValue> enumerable:
                    return(new ArrayValue(enumerable));

                case IEnumerable enumerable:
                    var fluidValues = new List <FluidValue>();
                    foreach (var item in enumerable)
                    {
                        fluidValues.Add(Create(item));
                    }

                    return(new ArrayValue(fluidValues));
                }

                return(new ObjectValue(value));

            case TypeCode.DateTime:
                return(new DateTimeValue((DateTime)value));

            case TypeCode.Char:
            case TypeCode.String:
                return(new StringValue(Convert.ToString(value, CultureInfo.InvariantCulture)));

            default:
                throw new InvalidOperationException();
            }
        }