static NumberValue() { for (var i = 0; i < NumbersMax; i++) { _intToValue[i] = new NumberValue(i, true); _doubleToValue[i] = new NumberValue(i, false); } }
protected override FluidValue GetValue(string name, TemplateContext context) { if (name == "size") { return(NumberValue.Create(_value.Length)); } return(NilValue.Instance); }
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), });
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)); }
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))); }
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 _)); }
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); }
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(); } }
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(); } }