public static LiquidExpressionResult Cast <TSource, TDest>(TSource src) where TDest : ILiquidValue where TSource : ILiquidValue { if (src == null) { return(LiquidExpressionResult.Success(new None <ILiquidValue>())); } if (src is TDest) { //var result = (TDest) ((dynamic) src); //ILiquidValue success = (TDest)((dynamic)src); ILiquidValue success = (TDest)(object)src; return(LiquidExpressionResult.Success(new Some <ILiquidValue>(success))); } if (typeof(TDest) == typeof(LiquidString)) { return(LiquidExpressionResult.Success(LiquidString.Create(src.ToString()))); } var str = src as LiquidString; if (str != null) { return(Convert <TDest>(str)); } var num = src as LiquidNumeric; if (num != null) { return(Convert <TDest>(num)); } var boo = src as LiquidBoolean; if (boo != null) { return(Convert <TDest>(boo)); } var dict = src as LiquidHash; if (dict != null) { return(Convert <TDest>(dict)); } var arr = src as LiquidCollection; if (arr != null) { return(Convert <TDest>(arr)); } var date = src as LiquidDate; if (date != null) { return(Convert <TDest>(date)); } //return Convert<TDest>(src); throw new Exception("Unknown type: " + src.GetType()); }
/// <summary> /// This applies the liquid casting rules, e.g. "null is zero when LiquidNumeric" or /// "null is empty string when LiquidString". /// </summary> /// <typeparam name="TDest"></typeparam> /// <returns></returns> public static LiquidExpressionResult ConvertFromNull <TDest>() where TDest : ILiquidValue { var destType = typeof(TDest); if (destType == typeof(LiquidNumeric)) { return(LiquidExpressionResult.Success(new Some <ILiquidValue>(LiquidNumeric.Create(0)))); } if (destType == typeof(LiquidString)) { return(LiquidExpressionResult.Success(LiquidString.Create(String.Empty))); } return(LiquidExpressionResult.Success(new None <ILiquidValue>())); }
// TODO: this is inefficient and ugly and duplicates much of LiquidCollection private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidString str, ILiquidValue indexProperty) { var strValues = str.StringVal.ToCharArray().Select(ch => LiquidString.Create(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(LiquidNumeric.Create(strValues.Count))); } else { //var maybeIndexResult = ValueCaster.Cast<ILiquidValue, LiquidNumeric>(indexProperty); var numericIndexProperty = indexProperty as LiquidNumeric; if (numericIndexProperty == null) { return(ctx.Options.ErrorWhenValueMissing ? LiquidExpressionResult.Error("invalid string index: '" + propertyNameString + "'") : LiquidExpressionResult.Success(new None <ILiquidValue>())); } else { index = numericIndexProperty.IntValue; } } if (strValues.Count == 0) { //return LiquidExpressionResult.Error("Empty string: " + propertyNameString); return(LiquidExpressionResult.Success(new None <ILiquidValue>())); // not an error in Ruby liquid. } return(LiquidExpressionResult.Success(CollectionIndexer.ValueAt(strValues, index))); }
private static LiquidExpressionResult Convert <TDest>(LiquidHash liquidHash) where TDest : ILiquidValue { var destType = typeof(TDest); // So, according to https://github.com/Shopify/liquid/wiki/Liquid-for-Designers, a hash value will be iterated // as an array with two indices. if (destType == typeof(LiquidCollection)) { var newArray = new LiquidCollection(); var dictarray = liquidHash.Keys.Select( k => (Option <ILiquidValue>) new Some <ILiquidValue>(new LiquidCollection { LiquidString.Create(k), liquidHash[k] })).ToList(); foreach (var item in dictarray) { newArray.Add(item); } return(LiquidExpressionResult.Success(newArray)); } // TODO: Should this return the default value for whatever TDest is requested? return(LiquidExpressionResult.Error("Can't convert from a LiquidHash to " + destType)); }
public static LiquidExpressionResult Parse(String str) { return(ValueCaster.Cast <ILiquidValue, LiquidNumeric>(LiquidString.Create(str))); }