/// <summary> /// Look up the index in the value. This works for dictionaries, arrays and strings. /// </summary> /// <param name="ctx"></param> /// <param name="value"></param> /// <param name="indexProperty"></param> /// <returns></returns> public LiquidExpressionResult Lookup( ITemplateContext ctx, IExpressionConstant value, IExpressionConstant indexProperty) { //Console.WriteLine("LOOKUP=> VALUE: " + value); //Console.WriteLine(" => INDEX: " + indexProperty); if (value == null) { return LiquidExpressionResult.Error("ERROR : cannot apply an index to a nil value."); } //return DoLookup(ctx, (dynamic) value, indexProperty); var arr = value as ArrayValue; if (arr != null) { return DoLookup(ctx, arr, indexProperty); } var dict = value as DictionaryValue; if (dict != null) { return DoLookup(ctx, dict, indexProperty); } var str = value as StringValue; if (str != null) { return DoLookup(ctx, str, indexProperty); } return LiquidExpressionResult.Error("ERROR : cannot apply an index to a " + value.LiquidTypeName + "."); }
public static StringValue Eval(IExpressionConstant liquidExpression, Func<String, String> f) { String before = ValueCaster.RenderAsString(liquidExpression); if (String.IsNullOrWhiteSpace(before)) { return new StringValue(""); } return new StringValue(f(before)); }
private static Func<Option<IExpressionConstant>, bool> IsEqual(IExpressionConstant expressionConstant) { return x => { if (x.HasValue) { return x.Value.Value.Equals(expressionConstant.Value); } else { return expressionConstant == null; } }; }
public static Option<IExpressionConstant> TryField(IExpressionConstant expressionConstant, string stringVal) { var dict = expressionConstant as DictionaryValue; if (dict == null) { return new None<IExpressionConstant>(); //return new Undefined(stringVal); } if (!dict.DictValue.ContainsKey(stringVal)) { return new None<IExpressionConstant>(); } else { return dict.DictValue[stringVal]; } }
private LiquidExpressionResult DoLookup(ITemplateContext ctx, ArrayValue arrayValue, IExpressionConstant indexProperty) { String propertyNameString = ValueCaster.RenderAsString(indexProperty); int index; if (propertyNameString.ToLower().Equals("first")) { index = 0; } else if (propertyNameString.ToLower().Equals("last")) { index = arrayValue.ArrValue.Count - 1; } else if (propertyNameString.ToLower().Equals("size")) { return LiquidExpressionResult.Success(NumericValue.Create(arrayValue.ArrValue.Count)); } else { var maybeIndexResult = ValueCaster.Cast<IExpressionConstant, NumericValue>(indexProperty); if (maybeIndexResult.IsError || !maybeIndexResult.SuccessResult.HasValue) { return LiquidExpressionResult.Error("invalid array index: " + propertyNameString); } else { index = maybeIndexResult.SuccessValue<NumericValue>().IntValue; } } if (arrayValue.ArrValue.Count == 0) { //return LiquidExpressionResult.Error("array is empty: " + propertyNameString); return LiquidExpressionResult.Success(new None<IExpressionConstant>()); // not an error in Ruby liquid. } var result = arrayValue.ValueAt(index); return LiquidExpressionResult.Success(result); }
public static bool IsBlank(IExpressionConstant val) { if (val == null) { return true; // regardless of what shopify liquid + activesupport do } //return CheckIsBlank((dynamic)val); var str = val as StringValue; if (str != null) { return CheckIsBlank(str); } var arr = val as ArrayValue; if (arr != null) { return CheckIsBlank(arr); } var dict = val as DictionaryValue; if (dict != null) { return CheckIsBlank(dict); } return CheckIsBlank(val); }
public static bool IsEmpty(IExpressionConstant val) { if (val == null /* || val.IsNil */) { return false; // this appears to be the case in liquid? } //return CheckIsEmpty((dynamic)val); var str = val as StringValue; if (str != null) { return CheckIsEmpty(str); } var arr = val as ArrayValue; if (arr != null) { return CheckIsEmpty(arr); } var dict = val as DictionaryValue; if (dict != null) { return CheckIsEmpty(dict); } return CheckIsEmpty(val); }
public String Render(IExpressionConstant result) { return ValueCaster.RenderAsString(result); }
private LiquidExpressionResult Contains(DictionaryValue dictValue, IExpressionConstant expressionConstant) { return LiquidExpressionResult.Success(new BooleanValue(dictValue.DictValue.Keys.Any(x => x.Equals(expressionConstant.Value)))); }
private LiquidExpressionResult Contains(ArrayValue arrayValue, IExpressionConstant expressionConstant) { return LiquidExpressionResult.Success(new BooleanValue(arrayValue.ArrValue.Any(IsEqual(expressionConstant)))); }
private LiquidExpressionResult Contains(StringValue stringValue, IExpressionConstant expressionConstant) { String s = ValueCaster.RenderAsString(expressionConstant); return LiquidExpressionResult.Success(stringValue.StringVal.Contains(s) ? new BooleanValue(true) : new BooleanValue(false)); }
private LiquidExpressionResult Contains(IExpressionConstant expr, IExpressionConstant expressionConstant) { //Console.WriteLine("ERROR"); return LiquidExpressionResult.Error("Unable to use 'contains' on this type."); }
private LiquidExpressionResult DoLookup(ITemplateContext ctx, IExpressionConstant c, IExpressionConstant indexProperty) { return LiquidExpressionResult.Error("ERROR : cannot apply an index to a "+c.LiquidTypeName+"."); }
public static BooleanValue Compare(IExpressionConstant x, IExpressionConstant y, Func<decimal, decimal, bool> func) { var numericValueResult1 = ValueCaster.Cast<IExpressionConstant, NumericValue>(x); var numericValueResult2 = ValueCaster.Cast<IExpressionConstant, NumericValue>(y); if (numericValueResult2.IsError || numericValueResult1.IsError) { return new BooleanValue(false); } var decimalValue1 = numericValueResult1.SuccessValue<NumericValue>().DecimalValue; var decimalValue2 = numericValueResult2.SuccessValue<NumericValue>().DecimalValue; return new BooleanValue(func(decimalValue1, decimalValue2)); }
private LiquidExpressionResult DoLookup(ITemplateContext ctx, DictionaryValue dictionaryValue, IExpressionConstant indexProperty) { String propertyNameString = ValueCaster.RenderAsString(indexProperty); if (propertyNameString.ToLower().Equals("size")) { return LiquidExpressionResult.Success(NumericValue.Create(dictionaryValue.DictValue.Keys.Count())); } return LiquidExpressionResult.Success(dictionaryValue.ValueAt(indexProperty.Value.ToString())); }
private static bool CheckIsBlank(IExpressionConstant _) { return false; // the only conditions will have been caught by IsBlank -- other types are never blank }
// TODO: this is inefficient and ugly and duplicates much of ArrayValue private LiquidExpressionResult DoLookup(ITemplateContext ctx, StringValue strValue, IExpressionConstant indexProperty) { var strValues = strValue.StringVal.ToCharArray().Select(ch => new StringValue(ch.ToString()).ToOption()).ToList(); String propertyNameString = ValueCaster.RenderAsString(indexProperty); int index; if (propertyNameString.ToLower().Equals("first")) { index = 0; } else if (propertyNameString.ToLower().Equals("last")) { index = strValues.Count - 1; } else if (propertyNameString.ToLower().Equals("size")) { return LiquidExpressionResult.Success(NumericValue.Create(strValues.Count)); } else { var maybeIndexResult = ValueCaster.Cast<IExpressionConstant, NumericValue>(indexProperty); if (maybeIndexResult.IsError || !maybeIndexResult.SuccessResult.HasValue) { return LiquidExpressionResult.Error("invalid array index: " + propertyNameString); } else { index = maybeIndexResult.SuccessValue<NumericValue>().IntValue; } } if (strValues.Count == 0) { //return LiquidExpressionResult.Error("Empty string: " + propertyNameString); return LiquidExpressionResult.Success(new None<IExpressionConstant>()); // not an error in Ruby liquid. } return LiquidExpressionResult.Success(ArrayIndexer.ValueAt(strValues, index)); }
private static bool CheckIsEmpty(IExpressionConstant _) { return false; // the only conditions will have been caught by IsEmpty }
public void DefineGlobal(string key, IExpressionConstant obj) { _symbolTables[0].DefineLocalVariable(key, obj); }
public void Define(string reference, IExpressionConstant obj) { //Console.WriteLine("Adding " + reference + " to current scope"); _symbolTables.Last().DefineLocalVariable(reference, obj); }