1 module yamlserialized.serialization; 2 3 import std.conv; 4 import std.traits; 5 6 import dyaml; 7 8 @safe: 9 10 Node toYAMLNode(T)(in ref T array) if (isArray!T) { 11 alias ElementType = ForeachType!T; 12 13 Node[] nodes; 14 15 // Iterate each item in the array and add them to the array of nodes 16 foreach(item; array) { 17 static if (is(ElementType == struct)) { 18 // This item is a struct 19 nodes ~= item.toYAMLNode(); 20 } 21 else static if (is(ElementType == class)) { 22 // This item is a class - serialize it unless it is null 23 if (item !is null) { 24 nodes ~= item.toYAMLNode(); 25 } 26 } 27 else static if (isSomeString!ElementType) { 28 nodes ~= Node(item.to!string); 29 } 30 else static if (isArray!ElementType) { 31 // An array of arrays. Recursion time! 32 nodes ~= item.toYAMLNode(); 33 } 34 else { 35 nodes ~= Node(item); 36 } 37 } 38 39 return Node(nodes); 40 } 41 42 Node toYAMLNode(T)(in ref T associativeArray) if (isAssociativeArray!T) { 43 alias KType = KeyType!T; 44 alias VType = ValueType!T; 45 46 Node[KType] items; 47 48 // Iterate each item in the associative array 49 foreach(key, value; associativeArray) { 50 // Convert key to the correct type 51 auto typedKey = key.to!KType; 52 53 static if (is(VType == struct)) { 54 // The value type is struct 55 items[typedKey] = value.toYAMLNode(); 56 } 57 else static if (is(VType == class)) { 58 // The value is a class - serialize it unless it is null 59 if (value !is null) { 60 items[typedKey] = value.toYAMLNode(); 61 } 62 } 63 else static if (isAssociativeArray!VType) { 64 /* The associative array's value type is another associative array type. 65 It's recursion time. */ 66 items[typedKey] = value.toYAMLNode(); 67 } 68 else static if (isSomeString!VType) { 69 items[typedKey] = Node(value.to!string); 70 } 71 else { 72 items[typedKey] = Node(value); 73 } 74 } 75 76 return Node(items); 77 } 78 79 Node toYAMLNode(T)(in ref T obj) if (is(T == struct) || is(T == class)) { 80 enum fieldNames = FieldNameTuple!T; 81 82 Node[string] nodes; 83 84 foreach(fieldName; fieldNames) { 85 auto field = __traits(getMember, obj, fieldName); 86 alias FieldType = typeof(field); 87 88 static if (is(FieldType == struct)) { 89 // This field is a struct - recurse into it 90 nodes[fieldName] = field.toYAMLNode(); 91 } 92 else static if (is(FieldType == class)) { 93 // This field is a class - recurse into it unless it is null 94 if (field !is null) { 95 nodes[fieldName] = field.toYAMLNode(); 96 } 97 } 98 else static if (isSomeString!FieldType) { 99 // TODO: Because Node only seems to work with string strings (and not char[], etc), convert all string types to string 100 nodes[fieldName] = Node(field.to!string); 101 } 102 else static if (isArray!FieldType) { 103 // Field is an array 104 nodes[fieldName] = field.toYAMLNode(); 105 } 106 else static if (isAssociativeArray!FieldType) { 107 // Field is an associative array 108 nodes[fieldName] = field.toYAMLNode(); 109 } 110 else { 111 // TODO: Verify if this is correct 112 nodes[fieldName] = Node(field.to!string); 113 } 114 } 115 116 return Node(nodes); 117 }