예제 #1
0
 static NumberValue()
 {
     for (var i = 0; i < NumbersMax; i++)
     {
         _intToValue[i]    = new NumberValue(i, true);
         _doubleToValue[i] = new NumberValue(i, false);
     }
 }
예제 #2
0
        protected override FluidValue GetValue(string name, TemplateContext context)
        {
            if (name == "size")
            {
                return(NumberValue.Create(_value.Length));
            }

            return(NilValue.Instance);
        }
예제 #3
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),
     });
예제 #4
0
        public override ValueTask <FluidValue> GetValueAsync(string name, TemplateContext context)
        {
            if (name == "size")
            {
                return(new ValueTask <FluidValue>(NumberValue.Create(_value.Count)));
            }

            if (!_value.TryGetValue(name, out var fluidValue))
            {
                return(new ValueTask <FluidValue>(NilValue.Instance));
            }

            return(new ValueTask <FluidValue>(fluidValue));
        }
예제 #5
0
        public override ValueTask <FluidValue> GetValueAsync(string name, TemplateContext context)
        {
            if (name == "size")
            {
                return(new ValueTask <FluidValue>(NumberValue.Create(_value.Count)));
            }

            object value = null;

            // NOTE: This code block doesn't seem to make any sense for a dictionary, just keeping it
            // as a comment in case it breaks something at some point.

            //var accessor = context.MemberAccessStrategy.GetAccessor(_value.GetType(), name);

            //if (accessor != null)
            //{
            //    if (accessor is IAsyncMemberAccessor asyncAccessor)
            //    {
            //        value = await asyncAccessor.GetAsync(_value, name, context);
            //    }
            //    else
            //    {
            //        value = accessor.Get(_value, name, context);
            //    }
            //}

            if (value == null)
            {
                if (!_value.TryGetValue(name, out var fluidValue))
                {
                    return(new ValueTask <FluidValue>(NilValue.Instance));
                }

                return(new ValueTask <FluidValue>(fluidValue));
            }

            return(new ValueTask <FluidValue>(FluidValue.Create(value)));
        }
예제 #6
0
        public bool IsInteger()
        {
            // Maps to https://github.com/Shopify/liquid/blob/1feaa6381300d56e2c71b49ad8fee0d4b625147b/lib/liquid/utils.rb#L38

            if (Type == FluidValues.Number)
            {
                return(NumberValue.GetScale(ToNumberValue()) == 0);
            }

            if (IsNil())
            {
                return(false);
            }

            var s = ToStringValue();

            if (String.IsNullOrWhiteSpace(s))
            {
                return(false);
            }

            return(int.TryParse(s, out var _));
        }
예제 #7
0
        protected override FluidValue GetValue(string name, TemplateContext context)
        {
            switch (name)
            {
            case "size":
                return(NumberValue.Create(_value.Count));

            case "first":
                if (_value.Count > 0)
                {
                    return(FluidValue.Create(_value[0]));
                }
                break;

            case "last":
                if (_value.Count > 0)
                {
                    return(FluidValue.Create(_value[_value.Count - 1]));
                }
                break;
            }

            return(NilValue.Instance);
        }
예제 #8
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();
            }
        }
예제 #9
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();
            }
        }