/// <summary> /// Deserialises the specified value node into a .NET object /// </summary> /// <param name="t"></param> /// <param name="node"></param> /// <returns></returns> public object Deserialise(Type t, ValueNode node) { // Instantiate if (t.IsAbstract) { throw new Exception($"Can't instantiate type '{t}'"); } object obj; try { // Special case for arrays if (t.IsArray) { obj = Activator.CreateInstance(t, node.As <ArrayValue>().Count); } else { obj = Activator.CreateInstance(t); } } catch (Exception ex) { // TODO: Handle this better throw ex; } // Populate Deserialise(obj, node); // Return return(obj); }
/// <summary> /// Tests the enum value /// </summary> /// <param name="valueNode"></param> /// <param name="expectedFullValue"></param> public static void TestEnumValue(ValueNode valueNode, string expectedFullValue) { Assert.IsInstanceOfType(valueNode, typeof(EnumValue)); EnumValue enumValue = valueNode.As <EnumValue>(); Assert.IsNotNull(enumValue); Assert.AreEqual(expectedFullValue, enumValue.Full); }
/// <summary> /// Tests the primitive value /// </summary> /// <typeparam name="T"></typeparam> /// <param name="valueNode"></param> /// <param name="expectedValue"></param> public static void TestPrimitiveValue <T>(ValueNode valueNode, T expectedValue) { Assert.IsInstanceOfType(valueNode, typeof(PrimitiveValue <T>)); PrimitiveValue <T> testStringNodeStr = valueNode.As <PrimitiveValue <T> >(); Assert.IsNotNull(testStringNodeStr); Assert.AreEqual(expectedValue, testStringNodeStr.Value); }
/// <summary> /// Populates the a .NET object with the specified value node /// </summary> /// <param name="obj"></param> /// <param name="node"></param> public void Deserialise(object obj, ValueNode node) { // Sanity check if (obj == null) { return; } Type t = obj.GetType(); // Is it a map type? if (typeof(IDictionary).IsAssignableFrom(t) && node is MapValue) { IDictionary dict = obj as IDictionary; MapValue mapVal = node.As <MapValue>(); // Is it a generic dict? if (TranslateOptions.IsGenericType(typeof(IDictionary <,>), t)) { Type[] genArgs = t.GetGenericArguments(); if (genArgs[0] != typeof(string)) { return; // TODO: Throw error? } foreach (var pair in mapVal) { object val; if (translateOpts.Deserialise(genArgs[1], pair.Value, out val)) { dict[pair.Key] = val; } } } else { foreach (var pair in mapVal) { object val; if (translateOpts.Deserialise(null, pair.Value, out val)) { dict.Add(pair.Key, val); } } } } // Is it an array type? else if (t.IsArray) { Array arr = obj as Array; ArrayValue arrVal = node.As <ArrayValue>(); Type elementType = t.GetElementType(); for (int i = 0; i < Math.Min(arrVal.Count, arr.Length); i++) { object val; translateOpts.Deserialise(elementType == typeof(object) ? null : elementType, arrVal[i], out val); arr.SetValue(val, i); } } else if (typeof(IList).IsAssignableFrom(t)) { var list = obj as IList; ArrayValue arrVal = node.As <ArrayValue>(); list.Clear(); // Is it a generic list? if (TranslateOptions.IsGenericType(typeof(IList <>), t)) { Type elementType = t.GetGenericArguments()[0]; for (int i = 0; i < arrVal.Count; i++) { object val; translateOpts.Deserialise(elementType == typeof(object) ? null : elementType, arrVal[i], out val); list.Add(val); } } else { for (int i = 0; i < arrVal.Count; i++) { object val; translateOpts.Deserialise(null, arrVal[i], out val); list.Add(val); } } } else if (typeof(ICollection).IsAssignableFrom(t)) { throw new NotImplementedException("Can't deserialise into an ICollection"); } MapValue mapValue = node as MapValue; if (mapValue == null) { return; // Throw error? } foreach (var pair in mapValue) { MemberInfo member = t.GetMember(pair.Key, BindingFlags.Public | BindingFlags.Instance) .Where(m => m is FieldInfo || m is PropertyInfo) .SingleOrDefault(); if (member != null) { FieldInfo fieldInfo = member as FieldInfo; if (fieldInfo != null) { object val; translateOpts.Deserialise(fieldInfo.FieldType, pair.Value, out val); if ((val == null && !fieldInfo.FieldType.IsValueType) || fieldInfo.FieldType.IsAssignableFrom(val.GetType())) { fieldInfo.SetValue(obj, val); } } PropertyInfo propertyInfo = member as PropertyInfo; if (propertyInfo != null) { object val; translateOpts.Deserialise(propertyInfo.PropertyType, pair.Value, out val); if ((val == null && !propertyInfo.PropertyType.IsValueType) || propertyInfo.PropertyType.IsAssignableFrom(val.GetType())) { propertyInfo.SetValue(obj, val, null); } } } } }