/// <summary>
 /// Parses a Redis string to a <see cref="Nullable{DateTime}"/> value, if string is not null or empty. If the string is null or empty, returns null.
 /// </summary>
 /// <param name="value">The string value to parse.</param>
 /// <returns>The parsed <see cref="Nullable{DateTime}"/> value.</returns>
 /// <exception cref="ArgumentException">Parameter <paramref name="value"/> is neither null nor empty and cannot be parsed to <see cref="Nullable{DateTime}"/>.</exception>
 public static DateTime?ParseDateTimeOrNull(string value)
 {
     if (string.IsNullOrWhiteSpace(value))
     {
         return(null);
     }
     else
     {
         return(RedisConverter.ParseDateTime(value));
     }
 }
        /// <summary>
        /// Parses a Redis string to a strongly-typed collection.
        /// </summary>
        /// <typeparam name="T">The type of the elements in the collection.</typeparam>
        /// <param name="value">The string value to parse.</param>
        /// <returns>The parsed strongly-typed collection.</returns>
        /// <exception cref="ArgumentException">Parameter <paramref name="value"/> cannot be parsed to a collection of <typeparamref name="T"/>.</exception>
        public static IEnumerable <T> ParseCollection <T>(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return(Enumerable.Empty <T>());
            }

            return(value
                   .Split(RedisConverter.ArraySeparatorAsChar)
                   .Select(v => RedisConverter.ParseValue <T>(v)));
        }
 /// <summary>
 /// Parses a Redis string to a <see cref="Nullable{Guid}"/> value, if string is not null or empty. If the string is null or empty, returns null.
 /// </summary>
 /// <param name="value">The string value to parse.</param>
 /// <returns>The parsed <see cref="Nullable{Guid}"/> value.</returns>
 /// <exception cref="ArgumentException">Parameter <paramref name="value"/> is neither null nor empty and cannot be parsed to <see cref="Nullable{Guid}"/>.</exception>
 public static Guid?ParseGuidOrNull(string value)
 {
     if (string.IsNullOrWhiteSpace(value))
     {
         return(null);
     }
     else
     {
         return(RedisConverter.ParseGuid(value));
     }
 }
 /// <summary>
 /// Parses a Redis string to a <see cref="Nullable{Int32}"/> value, if string is not null or empty. If the string is null or empty, returns null.
 /// </summary>
 /// <param name="value">The string value to parse.</param>
 /// <returns>The parsed <see cref="Nullable{Int32}"/> value.</returns>
 /// <exception cref="ArgumentException">Parameter <paramref name="value"/> is neither null nor empty and cannot be parsed to <see cref="Nullable{Int32}"/>.</exception>
 public static int?ParseIntegerOrNull(string value)
 {
     if (string.IsNullOrWhiteSpace(value))
     {
         return(null);
     }
     else
     {
         return(RedisConverter.ParseInteger(value));
     }
 }
 /// <summary>
 /// Parses a Redis string to a <see cref="Nullable{Double}"/> value, if string is not null or empty. If the string is null or empty, returns 0.
 /// </summary>
 /// <param name="value">The string value to parse.</param>
 /// <returns>The parsed <see cref="Nullable{Double}"/> value.</returns>
 /// <exception cref="ArgumentException">Parameter <paramref name="value"/> is neither null nor empty and cannot be parsed to <see cref="Nullable{Double}"/>.</exception>
 public static double ParseDoubleOrDefault(string value)
 {
     if (string.IsNullOrWhiteSpace(value))
     {
         return(default(double));
     }
     else
     {
         return(RedisConverter.ParseDouble(value));
     }
 }
 public static int ParseIntegerOrDefault(string value)
 {
     if (string.IsNullOrWhiteSpace(value))
     {
         return(default(int));
     }
     else
     {
         return(RedisConverter.ParseInteger(value));
     }
 }
        /// <summary>
        /// Parses a Redis string to an object.
        /// </summary>
        /// <param name="value">The string value to parse.</param>
        /// <param name="toType">The type of the object to parse.</param>
        /// <returns>The parsed object.</returns>
        /// <exception cref="ArgumentNullException">Parameter <paramref name="toType"/> is null.</exception>
        /// <exception cref="NotSupportedException">Type <paramref name="toType" /> is not supported.</exception>
        public static object ParseValue(string value, Type toType)
        {
            if (toType == null)
            {
                throw new ArgumentNullException("toType");
            }

            if (toType == typeof(string))
            {
                return(value);
            }

            if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (string.IsNullOrEmpty(value))
                {
                    return(null);
                }

                toType = toType.GetGenericArguments()[0];
            }

            if (toType == typeof(int))
            {
                return(RedisConverter.ParseInteger(value));
            }

            if (toType == typeof(long))
            {
                return(RedisConverter.ParseLong(value));
            }

            if (toType == typeof(float))
            {
                return(RedisConverter.ParseFloat(value));
            }

            if (toType == typeof(double))
            {
                return(RedisConverter.ParseDouble(value));
            }

            if (toType == typeof(Guid))
            {
                return(RedisConverter.ParseGuid(value));
            }

            if (toType == typeof(TimeSpan))
            {
                return(RedisConverter.ParseTimeSpan(value));
            }

            if (toType == typeof(DateTime))
            {
                return(RedisConverter.ParseDateTime(value));
            }

            if (toType == typeof(bool))
            {
                return(RedisConverter.ParseBoolean(value));
            }

            if (toType.IsEnum)
            {
                return(RedisConverter.ParseEnum(value, toType));
            }

            if (toType == typeof(Type))
            {
                return(RedisConverter.ParseType(value));
            }

            if (toType == typeof(Version))
            {
                return(RedisConverter.ParseVersion(value));
            }

            throw new NotSupportedException <Type>(toType);
        }
 /// <summary>
 /// Parses a Redis string to an object.
 /// </summary>
 /// <typeparam name="T">The type of the object to parse.</typeparam>
 /// <param name="value">The string value to parse.</param>
 /// <returns>The parsed object.</returns>
 /// <exception cref="NotSupportedException">Type <typeparamref name="T" /> is not supported.</exception>
 public static T ParseValue <T>(string value)
 {
     return((T)RedisConverter.ParseValue(value, typeof(T)));
 }
 /// <summary>
 /// Parses a Redis string to an enumeration value.
 /// </summary>
 /// <typeparam name="TEnum">The enumeration type.</typeparam>
 /// <param name="value">The string value to parse.</param>
 /// <returns>The parsed enumeration value.</returns>
 /// <exception cref="ArgumentNullException">Parameter <paramref name="value"/> is null.</exception>
 /// <exception cref="ArgumentException">Parameter <paramref name="value"/> cannot be parsed to <typeparamref name="TEnum"/>.</exception>
 public static TEnum ParseEnum <TEnum>(string value)
 {
     return((TEnum)RedisConverter.ParseEnum(value, typeof(TEnum)));
 }
        /// <summary>
        /// Parses a Redis string to a <see cref="TimeSpan"/> value.
        /// </summary>
        /// <param name="value">The string value to parse.</param>
        /// <returns>The parsed <see cref="TimeSpan"/> value.</returns>
        /// <exception cref="ArgumentNullException">Parameter <paramref name="value"/> is null.</exception>
        /// <exception cref="ArgumentException">Parameter <paramref name="value"/> cannot be parsed to <see cref="TimeSpan"/>.</exception>
        public static TimeSpan ParseTimeSpan(string value)
        {
            long ticks = RedisConverter.ParseLong(value);

            return(TimeSpan.FromTicks(ticks));
        }
        /// <summary>
        /// Parses a Redis string to a <see cref="DateTime"/> value.
        /// </summary>
        /// <param name="value">The string value to parse.</param>
        /// <returns>The parsed <see cref="DateTime"/> value.</returns>
        /// <exception cref="ArgumentNullException">Parameter <paramref name="value"/> is null.</exception>
        /// <exception cref="ArgumentException">Parameter <paramref name="value"/> cannot be parsed to <see cref="DateTime"/>.</exception>
        public static DateTime ParseDateTime(string value)
        {
            long ticks = RedisConverter.ParseLong(value);

            return(new DateTime(ticks));
        }
        /// <summary>
        /// Converts a collection to a string that can be stored in Redis.
        /// </summary>
        /// <param name="collection">The collection to convert.</param>
        /// <returns>A string representation of the specified collection that can be stored in Redis.</returns>
        /// <exception cref="ArgumentNullException">Parameter <paramref name="collection"/> is null.</exception>
        public static string ToString(params object[] collection)
        {
            if (collection == null)
            {
                return(string.Empty);
            }

            return(string.Join(RedisConverter.ArraySeparatorAsString, collection.Select(c => RedisConverter.ToString(c))));
        }
        /// <summary>
        /// Converts an object to a string that can be stored in Redis.
        /// </summary>
        /// <param name="value">The object to convert.</param>
        /// <returns>A string representation of the specified object that can be stored in Redis.</returns>
        /// <exception cref="NotSupportedException">The type of the specified object is not supported.</exception>
        public static string ToString(object value)
        {
            if (value == null)
            {
                return(string.Empty);
            }

            Type type = value.GetType();

            if (type == typeof(string))
            {
                return((string)value);
            }

            if (type == typeof(int))
            {
                return(RedisConverter.ToString((int)value));
            }

            if (type == typeof(long))
            {
                return(RedisConverter.ToString((long)value));
            }

            if (type == typeof(float))
            {
                return(RedisConverter.ToString((float)value));
            }

            if (type == typeof(double))
            {
                return(RedisConverter.ToString((double)value));
            }

            if (type == typeof(Guid))
            {
                return(RedisConverter.ToString((Guid)value));
            }

            if (type == typeof(TimeSpan))
            {
                return(RedisConverter.ToString((TimeSpan)value));
            }

            if (type == typeof(DateTime))
            {
                return(RedisConverter.ToString((DateTime)value));
            }

            if (type == typeof(bool))
            {
                return(RedisConverter.ToString((bool)value));
            }

            if (type == typeof(Version))
            {
                return(RedisConverter.ToString((Version)value));
            }

            if (type.IsEnum)
            {
                return(value.ToString());
            }

            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                return(RedisConverter.ToString(((IEnumerable)value).Cast <object>().ToArray()));
            }

            throw new NotSupportedException <Type>(type);
        }