1 /** 2 License: 3 Boost Software License - Version 1.0 - August 17th, 2003 4 5 Permission is hereby granted, free of charge, to any person or organization 6 obtaining a copy of the software and accompanying documentation covered by 7 this license (the "Software") to use, reproduce, display, distribute, 8 execute, and transmit the Software, and to prepare derivative works of the 9 Software, and to permit third-parties to whom the Software is furnished to 10 do so, all subject to the following: 11 12 The copyright notices in the Software and this entire statement, including 13 the above license grant, this restriction and the following disclaimer, 14 must be included in all copies of the Software, in whole or in part, and 15 all derivative works of the Software, unless such copies or derivative 16 works are solely in the form of machine-executable object code generated by 17 a source language processor. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 DEALINGS IN THE SOFTWARE. 26 27 Authors: 28 aermicioi 29 **/ 30 module aermicioi.aedi_property_reader.yaml.yaml; 31 32 import aermicioi.aedi.storage.storage; 33 import aermicioi.aedi.storage.locator; 34 import aermicioi.aedi_property_reader.core.accessor; 35 import aermicioi.aedi_property_reader.core.convertor; 36 import aermicioi.aedi_property_reader.core.type_guesser; 37 import aermicioi.aedi_property_reader.yaml.accessor; 38 import aermicioi.aedi_property_reader.yaml.convertor; 39 import aermicioi.aedi_property_reader.core.document; 40 import aermicioi.aedi_property_reader.yaml.type_guesser; 41 import dyaml; 42 import std.experimental.logger; 43 import std.experimental.allocator; 44 45 alias YamlDocumentContainer = AdvisedDocumentContainer!(Node, Node, YamlConvertor); 46 47 /** 48 Create a convertor container with data source being yaml document. 49 50 Params: 51 value = source of data for container to use to construct components. 52 accessor = property accessing logic 53 guesser = type guesser based on held yaml value 54 allocator = allocator used to allocate converted values 55 Returns: 56 JsonConvertorContainer 57 **/ 58 auto yaml(Node value, PropertyAccessor!Node accessor, TypeGuesser!Node guesser, RCIAllocator allocator = theAllocator) { 59 60 YamlDocumentContainer container = new YamlDocumentContainer(value); 61 container.guesser = guesser; 62 container.accessor = accessor; 63 container.allocator = allocator; 64 65 return container; 66 } 67 68 /** 69 ditto 70 **/ 71 auto yaml(Node value, TypeGuesser!Node guesser, RCIAllocator allocator = theAllocator) { 72 73 return value.yaml(accessor, guesser, allocator); 74 } 75 76 /** 77 ditto 78 **/ 79 auto yaml(Node value, RCIAllocator allocator = theAllocator) { 80 import std.meta : AliasSeq; 81 auto container = value.yaml(accessor, new YamlTypeGuesser, allocator); 82 import std.datetime; 83 import std.traits; 84 85 static foreach (T; AliasSeq!( 86 long, 87 real, 88 ubyte[], 89 bool, 90 string, 91 SysTime 92 )) { 93 container.set(YamlConvertor!(T, Node)(), fullyQualifiedName!T); 94 } 95 96 return container; 97 } 98 99 /** 100 ditto 101 **/ 102 auto yaml(RCIAllocator allocator = theAllocator) { 103 104 return Node("").yaml(allocator); 105 } 106 107 /** 108 Create a convertor container with data source being yaml document. 109 110 Params: 111 pathOrData = path to a yaml file or yaml data itself 112 returnEmpty = wheter to return or not a locator with empty data source 113 Returns: 114 yamlConvertorContainer 115 **/ 116 auto yaml(string pathOrData, bool returnEmpty = true) { 117 import std.file; 118 119 try { 120 121 if (pathOrData.exists) { 122 return yaml(Loader(pathOrData).load()); 123 } else { 124 return yaml(Loader.fromString(pathOrData.dup).load()); 125 } 126 } catch (YAMLException e) { 127 debug(trace) trace("Error parsing yaml: ", e); 128 129 if (returnEmpty) { 130 debug(trace) trace("Providing empty container"); 131 return yaml(); 132 } 133 134 throw new Exception("Could not create yaml convertor container from file or content passed in pathOrData: " ~ pathOrData, e); 135 } 136 } 137 138 package auto accessor() { 139 import aermicioi.aedi_property_reader.core.accessor; 140 141 return dsl( 142 new YamlNodePropertyAccessor(), 143 new YamlIntegerIndexAccessor() 144 ); 145 }