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.sdlang.sdlang;
31 
32 import aermicioi.aedi.storage.storage;
33 import aermicioi.aedi.storage.locator;
34 import aermicioi.aedi_property_reader.sdlang.accessor;
35 import aermicioi.aedi_property_reader.core.accessor;
36 import aermicioi.aedi_property_reader.sdlang.convertor;
37 import aermicioi.aedi_property_reader.core.convertor;
38 import aermicioi.aedi_property_reader.core.type_guesser;
39 import aermicioi.aedi_property_reader.core.document;
40 import aermicioi.aedi_property_reader.sdlang.type_guesser;
41 import sdlanguage = sdlang;
42 import std.experimental.logger;
43 import std.experimental.allocator;
44 
45 alias SdlangDocumentContainer = AdvisedDocumentContainer!(SdlangElement, SdlangElement, SdlangConvertor);
46 
47 /**
48 Create a convertor container with data source being sdlang 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 sdlang value
54     allocator = allocator used to allocate converted values
55 Returns:
56     JsonConvertorContainer
57 **/
58 auto sdlang(SdlangElement value, PropertyAccessor!SdlangElement accessor, TypeGuesser!SdlangElement guesser, RCIAllocator allocator = theAllocator) {
59 
60     SdlangDocumentContainer container = new SdlangDocumentContainer(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 sdlang(SdlangElement value, TypeGuesser!SdlangElement guesser, RCIAllocator allocator = theAllocator) {
72 
73     return value.sdlang(accessor, guesser, allocator);
74 }
75 
76 /**
77 ditto
78 **/
79 auto sdlang(SdlangElement value, RCIAllocator allocator = theAllocator) {
80 
81     auto container = value.sdlang(accessor, new SdlangTypeGuesser(), allocator);
82     import std.traits : fullyQualifiedName;
83     import std.meta : AliasSeq;
84     import std.datetime;
85     import sdlang.token;
86 
87     static foreach (T; AliasSeq!(
88         bool,
89         string, dchar,
90         int, long,
91         float, double, real,
92         Date, DateTimeFrac, SysTime, DateTimeFracUnknownZone, Duration,
93         ubyte[]
94     )) {
95 
96         container.set(SdlangConvertor!(T, SdlangElement)(), fullyQualifiedName!T);
97     }
98 
99     return container;
100 }
101 
102 /**
103 ditto
104 **/
105 auto sdlang(RCIAllocator allocator = theAllocator) {
106     import sdlang.ast;
107 
108     return SdlangElement(new Tag()).sdlang(allocator);
109 }
110 
111 /**
112 Create a convertor container with data source being sdlang document.
113 
114 Params:
115     pathOrData = path to a sdlang file or sdlang data itself
116     returnEmpty = wheter to return or not a locator with empty data source
117 Returns:
118     SdlangConvertorContainer
119 **/
120 auto sdlang(string pathOrData, bool returnEmpty = true) {
121     import std.file;
122 
123     try {
124 
125         debug(trace) trace("Loading sdlang document from ", pathOrData);
126         if (pathOrData.exists) {
127             debug(trace) trace("Detected ", pathOrData, " being a sdlang file, parsing it");
128             return sdlang(SdlangElement(sdlanguage.parseFile(pathOrData)));
129         } else {
130 
131             debug(trace) trace("Attempting to parse ", pathOrData, " as sdlang content");
132             return sdlang(SdlangElement(sdlanguage.parseSource(pathOrData)));
133         }
134     } catch (sdlanguage.SDLangException e) {
135         debug(trace) trace("Error parsing sdlang: ", e);
136 
137         if (returnEmpty) {
138             debug(trace) trace("Providing empty container");
139             return sdlang();
140         }
141 
142         throw new Exception("Could not create sdlang convertor container from file or content passed in pathOrData: " ~ pathOrData, e);
143     }
144 }
145 
146 package auto accessor() {
147     return dsl(
148         new AggregatePropertyAccessor!SdlangElement(
149             new TaggedElementPropertyAccessorWrapper!(SdlangElement, SdlangAttributePropertyAccessor)(new SdlangAttributePropertyAccessor),
150             new TaggedElementPropertyAccessorWrapper!(SdlangElement, SdlangTagPropertyAccessor)(new SdlangTagPropertyAccessor),
151             new TaggedElementPropertyAccessorWrapper!(SdlangElement, SdlangIntegerIndexAccessor)(new SdlangIntegerIndexAccessor)
152         ),
153         new AggregatePropertyAccessor!SdlangElement(
154             new TaggedElementPropertyAccessorWrapper!(SdlangElement, SdlangAttributePropertyAccessor)(new SdlangAttributePropertyAccessor),
155             new TaggedElementPropertyAccessorWrapper!(SdlangElement, SdlangTagPropertyAccessor)(new SdlangTagPropertyAccessor),
156             new TaggedElementPropertyAccessorWrapper!(SdlangElement, SdlangIntegerIndexAccessor)(new SdlangIntegerIndexAccessor)
157         )
158     );
159 }