예제 #1
0
        public static bool IsEmpty(ILiquidValue val)
        {
            if (val == null)
            {
                return(false);
            }

            var str = val as LiquidString;

            if (str != null)
            {
                return(CheckIsEmpty(str));
            }

            var arr = val as LiquidCollection;

            if (arr != null)
            {
                return(CheckIsEmpty(arr));
            }

            var dict = val as LiquidHash;

            if (dict != null)
            {
                return(CheckIsEmpty(dict));
            }

            return(CheckIsEmpty(val));
        }
예제 #2
0
        public static bool IsBlank(ILiquidValue val)
        {
            if (val == null)
            {
                return(true); // regardless of what shopify liquid + activesupport do
            }
            //return CheckIsBlank((dynamic)val);
            var str = val as LiquidString;

            if (str != null)
            {
                return(CheckIsBlank(str));
            }
            var arr = val as LiquidCollection;

            if (arr != null)
            {
                return(CheckIsBlank(arr));
            }
            var dict = val as LiquidHash;

            if (dict != null)
            {
                return(CheckIsBlank(dict));
            }
            return(CheckIsBlank(val));
        }
예제 #3
0
        /// <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,
            ILiquidValue value,
            ILiquidValue indexProperty)
        {
            var arr = value as LiquidCollection;

            if (arr != null)
            {
                return(DoLookup(ctx, arr, indexProperty));
            }

            var dict = value as LiquidHash;

            if (dict != null)
            {
                return(DoLookup(ctx, dict, indexProperty));
            }

            var str = value as LiquidString;

            if (str != null)
            {
                return(DoLookup(ctx, str, indexProperty));
            }

            return(LiquidExpressionResult.Error("ERROR : cannot apply an index to a " + value.LiquidTypeName + "."));
        }
예제 #4
0
        private static LiquidExpressionResult CastParameter(ILiquidValue filterList, Type parmType)
        {
            MethodInfo method = typeof(ValueCaster).GetMethod("Cast");

            MethodInfo generic = method.MakeGenericMethod(filterList.GetType(), parmType);

            return((LiquidExpressionResult)generic.Invoke(null, new object[] { filterList }));
        }
예제 #5
0
 public static string RenderAsString(ILiquidValue val)
 {
     if (val == null)
     {
         return("");
     }
     return(val.ToString());
 }
예제 #6
0
        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());
        }
예제 #7
0
        public static LiquidString Eval(ILiquidValue liquidExpression, Func <String, String> f)
        {
            String before = ValueCaster.RenderAsString(liquidExpression);

            if (String.IsNullOrWhiteSpace(before))
            {
                return(LiquidString.Create(""));
            }
            return(LiquidString.Create(f(before)));
        }
 private static Func <Option <ILiquidValue>, bool> IsEqual(ILiquidValue liquidValue)
 {
     return(x =>
     {
         if (x.HasValue)
         {
             return x.Value.Value.Equals(liquidValue.Value);
         }
         else
         {
             return liquidValue == null;
         }
     });
 }
        public static LiquidBoolean Compare(ILiquidValue x, ILiquidValue y,
                                            Func <decimal, decimal, bool> func)
        {
            var numericValueResult1 = ValueCaster.Cast <ILiquidValue, LiquidNumeric>(x);
            var numericValueResult2 = ValueCaster.Cast <ILiquidValue, LiquidNumeric>(y);

            if (numericValueResult2.IsError || numericValueResult1.IsError)
            {
                return(new LiquidBoolean(false));
            }

            var decimalValue1 = numericValueResult1.SuccessValue <LiquidNumeric>().DecimalValue;
            var decimalValue2 = numericValueResult2.SuccessValue <LiquidNumeric>().DecimalValue;

            return(new LiquidBoolean(func(decimalValue1, decimalValue2)));
        }
예제 #10
0
        public static LiquidExpressionResult TryField(
            ITemplateContext ctx,
            ILiquidValue liquidValue,
            string index)
        {
            var dict = liquidValue as LiquidHash;

            if (dict == null)
            {
                return(LiquidExpressionResult.ErrorOrNone(ctx, index));
            }

            return(dict.ContainsKey(index)
                ? LiquidExpressionResult.Success(dict[index])
                : LiquidExpressionResult.ErrorOrNone(ctx, index));
        }
예제 #11
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, ILiquidValue expr)
        {
            var metaData = new LiquidHash();

            foreach (var kvp in expr.MetaData)
            {
                metaData.Add(kvp.Key, kvp.Value == null
                    ? Option <ILiquidValue> .Create(LiquidString.Create(""))
                    : Option <ILiquidValue> .Create(LiquidString.Create(kvp.Value.ToString())));
            }

            var result = new LiquidHash
            {
                { "metadata", metaData },
                { "value", Option <ILiquidValue> .Create(expr) },
                { "type", LiquidString.Create(expr.LiquidTypeName) }
            };

            return(LiquidExpressionResult.Success(result));
        }
예제 #12
0
 // ReSharper disable UnusedParameter.Local
 private LiquidExpressionResult Contains(ILiquidValue expr, ILiquidValue liquidValue)
 // ReSharper restore UnusedParameter.Local
 {
     return(LiquidExpressionResult.Error("Unable to use 'contains' on this type."));
 }
예제 #13
0
        private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidCollection liquidCollection, ILiquidValue indexProperty)
        {
            bool errorOnEmpty = ctx.Options.ErrorWhenValueMissing && liquidCollection.Count == 0;



            String propertyNameString = ValueCaster.RenderAsString(indexProperty);
            int    index;

            if (propertyNameString.ToLower().Equals("first"))
            {
                if (errorOnEmpty)
                {
                    return(LiquidExpressionResult.Error("cannot dereference empty array"));
                }
                index = 0;
            }
            else if (propertyNameString.ToLower().Equals("last"))
            {
                if (errorOnEmpty)
                {
                    return(LiquidExpressionResult.Error("cannot dereference empty array"));
                }
                index = liquidCollection.Count - 1;
            }
            else if (propertyNameString.ToLower().Equals("size"))
            {
                return(LiquidExpressionResult.Success(LiquidNumeric.Create(liquidCollection.Count)));
            }
            else
            {
                var success = Int32.TryParse(propertyNameString, out index);
                //var maybeIndexResult = ValueCaster.Cast<ILiquidValue, LiquidNumeric>(indexProperty);

                if (!success)
                {
                    if (ctx.Options.ErrorWhenValueMissing)
                    {
                        return(LiquidExpressionResult.Error("invalid index: '" + propertyNameString + "'"));
                    }
                    else
                    {
                        return(LiquidExpressionResult.Success(new None <ILiquidValue>()));// liquid seems to return nothing when non-int index.
                    }
                }

//                if (maybeIndexResult.IsError || !maybeIndexResult.SuccessResult.HasValue)
//                {
//                    return LiquidExpressionResult.Error("invalid array index: " + propertyNameString);
//                }
//                else
//                {
//                    index = maybeIndexResult.SuccessValue<LiquidNumeric>().IntValue;
//                }
            }

            if (liquidCollection.Count == 0)
            {
                return(errorOnEmpty ?
                       LiquidExpressionResult.Error("cannot dereference empty array") :
                       LiquidExpressionResult.Success(new None <ILiquidValue>()));
            }
            var result = liquidCollection.ValueAt(index);

            return(LiquidExpressionResult.Success(result));
        }
예제 #14
0
 // ReSharper disable once UnusedParameter.Local
 private static bool CheckIsBlank(ILiquidValue _)
 {
     return(false); // the only conditions will have been caught by IsBlank -- other types are never blank
 }
예제 #15
0
        private LiquidExpressionResult Contains(LiquidString liquidString, ILiquidValue liquidValue)
        {
            String s = ValueCaster.RenderAsString(liquidValue);

            return(LiquidExpressionResult.Success(liquidString.StringVal.Contains(s) ? new LiquidBoolean(true) : new LiquidBoolean(false)));
        }
예제 #16
0
 private LiquidExpressionResult Contains(LiquidHash dictValue, ILiquidValue liquidValue)
 {
     return(LiquidExpressionResult.Success(new LiquidBoolean(dictValue.Keys.Any(x => x.Equals(liquidValue.Value)))));
 }
예제 #17
0
 private LiquidExpressionResult Contains(LiquidCollection liquidCollection, ILiquidValue liquidValue)
 {
     return(LiquidExpressionResult.Success(new LiquidBoolean(liquidCollection.Any(IsEqual(liquidValue)))));
 }
예제 #18
0
 // ReSharper disable once UnusedParameter.Local
 private static bool CheckIsEmpty(ILiquidValue _)
 {
     return(false); // the only conditions will have been caught by IsEmpty
 }
예제 #19
0
        private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidHash liquidHash, ILiquidValue indexProperty)
        {
            String propertyNameString = ValueCaster.RenderAsString(indexProperty);

            if (propertyNameString.ToLower().Equals("size"))
            {
                return(LiquidExpressionResult.Success(LiquidNumeric.Create(liquidHash.Keys.Count)));
            }

            var valueAt = liquidHash.ValueAt(indexProperty.Value.ToString());

            if (valueAt.HasValue)
            {
                return(LiquidExpressionResult.Success(valueAt));
            }
            else
            {
                return(LiquidExpressionResult.ErrorOrNone(ctx, indexProperty.ToString()));
            }
        }
예제 #20
0
 public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, ILiquidValue liquidExpression)
 {
     return(LiquidExpressionResult.Success(LiquidString.Create(liquidExpression.LiquidTypeName)));
 }
예제 #21
0
 public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, ILiquidValue liquidExpression)
 {
     return(GetSize(liquidExpression, () => LiquidNumeric.Create(1)));// if it's not an enumerable, it must be of length 1.
 }
예제 #22
0
        // 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)));
        }
예제 #23
0
 private static LiquidExpressionResult GetSize(ILiquidValue liquidExpression, Func <LiquidNumeric> measureSizeFunc)
 {
     return(liquidExpression == null || liquidExpression.Value == null
         ? SizeOfNil()
         : LiquidExpressionResult.Success(measureSizeFunc()));
 }
예제 #24
0
 public abstract LiquidExpressionResult Apply(ITemplateContext ctx, ILiquidValue liquidExpression);
예제 #25
0
 /* override some or all of these ApplyTo functions */
 public virtual LiquidExpressionResult ApplyTo(ITemplateContext _, ILiquidValue liquidExpression)
 {
     throw new NotImplementedException();
 }
예제 #26
0
 public String Render(ILiquidValue result)
 {
     return(ValueCaster.RenderAsString(result));
 }