1 /** 2 * Interface for writing `rpdl.tree.RpdlTree` to the external files 3 * 4 * Copyright: © 2017 Andrey Kabylin 5 * License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. 6 */ 7 module rpdl.writer; 8 9 import std.file; 10 import std.stdio; 11 import std.conv; 12 13 import rpdl.node; 14 import rpdl.value; 15 import rpdl.exception; 16 17 /// Declare interface for writers and tell them - how to write each type of node to file. 18 interface IWriter { 19 void writeObject(ObjectNode object); 20 void writeParameter(Parameter parameter); 21 void writeValue(Value value); 22 void writeNumberValue(NumberValue value); 23 void writeBooleanValue(BooleanValue value); 24 void writeStringValue(StringValue value); 25 void writeIdentifierValue(IdentifierValue value); 26 void writeArrayValue(ArrayValue array); 27 } 28 29 /** 30 * Default IWriter implementation 31 */ 32 abstract class Writer : IWriter { 33 /** 34 * Write `root` node and it children to file 35 */ 36 this(Node root) { 37 this.root = root; 38 } 39 40 void save(in string fileName) { 41 this.file = File(fileName, "w"); 42 43 foreach (Node node; root.children) { 44 writeObject(cast(ObjectNode) node); 45 } 46 } 47 48 protected: 49 Node root; 50 File file; 51 52 void rawWrite(in ubyte ch) { 53 file.rawWrite([ch]); 54 } 55 56 void rawWrite(in bool value) { 57 file.rawWrite([value]); 58 } 59 60 void rawWrite(in int value) { 61 file.rawWrite([value]); 62 } 63 64 void rawWrite(in float value) { 65 file.rawWrite([value]); 66 } 67 68 void rawWrite(in string str) { 69 file.rawWrite(str); 70 } 71 72 override void writeObject(ObjectNode object) { 73 foreach (Node child; object.children) { 74 if (cast(Parameter) child) { 75 writeParameter(cast(Parameter) child); 76 } else if (cast(ObjectNode) child) { 77 writeObject(cast(ObjectNode) child); 78 } else { 79 throw new WrongNodeType("Should be Value or Parameter"); 80 } 81 } 82 } 83 84 override void writeParameter(Parameter parameter) { 85 foreach (Node child; parameter.children) { 86 if (cast(Value) child) { 87 writeValue(cast(Value) child); 88 } else { 89 throw new WrongNodeType("Should be Value"); 90 } 91 } 92 } 93 94 override void writeValue(Value value) { 95 switch (value.type) { 96 case Value.Type.Number: 97 writeNumberValue(cast(NumberValue) value); 98 break; 99 100 case Value.Type.Boolean: 101 writeBooleanValue(cast(BooleanValue) value); 102 break; 103 104 case Value.Type.Identifier: 105 writeIdentifierValue(cast(IdentifierValue) value); 106 break; 107 108 case Value.Type.String: 109 writeStringValue(cast(StringValue) value); 110 break; 111 112 case Value.Type.Array: 113 writeArrayValue(cast(ArrayValue) value); 114 break; 115 116 default: 117 throw new WrongNodeType(); 118 } 119 } 120 121 override void writeNumberValue(NumberValue value) {} 122 123 override void writeBooleanValue(BooleanValue value) {} 124 125 override void writeStringValue(StringValue value) {} 126 127 override void writeIdentifierValue(IdentifierValue value) {} 128 129 override void writeArrayValue(ArrayValue array) { 130 foreach (Node node; array.children) 131 writeValue(cast(Value) node); 132 } 133 }