1 module jsonschema.adapters;
2 
3 import std, jsonschema, sdlite;
4 
5 struct StdJsonAdapter
6 {
7     static:
8 
9     alias AggregateType = JSONValue;
10 
11     JsonSchemaType getType(AggregateType value)
12     {
13         final switch(value.type) with(JSONType)
14         {
15             case null_: return JsonSchemaType.null_;
16             case string: return JsonSchemaType.string_;
17             case integer: return JsonSchemaType.integer | JsonSchemaType.number;
18             case uinteger: return JsonSchemaType.integer | JsonSchemaType.number;
19             case float_: return JsonSchemaType.number;
20             case array: return JsonSchemaType.array;
21             case object: return JsonSchemaType.object;
22             case true_: return JsonSchemaType.boolean;
23             case false_: return JsonSchemaType.boolean;
24         }
25     }
26 
27     bool isNull(AggregateType value) { return value.isNull; }
28     string getString(AggregateType value) { return value.str; }
29     long getInteger(AggregateType value) { return value.get!ulong; }
30     double getNumber(AggregateType value) { return value.get!double; }
31     bool getBoolean(AggregateType value) { return value.get!bool; }
32 
33     AggregateType getArrayValue(AggregateType value, size_t index) { return value.array[index]; }
34     AggregateType getObjectProperty(AggregateType value, string index) { return value.object[index]; }
35 
36     void eachArrayValue(AggregateType value, void delegate(size_t, AggregateType) handler)
37     {
38         foreach(i, v; value.array)
39             handler(i, v);
40     }
41 
42     void eachObjectProperty(AggregateType value, void delegate(string, AggregateType) handler)
43     {
44         foreach(k, v; value.object)
45             handler(k, v);
46     }
47 }
48 
49 struct SdliteAdapter
50 {
51     static:
52 
53     alias AggregateType = SDLNode;
54 
55     JsonSchemaType getType(AggregateType value)
56     {
57         JsonSchemaType type;
58         if(value.values.length)
59             type |= JsonSchemaType.array;
60         if(value.children.length)
61             type |= JsonSchemaType.object;
62 
63         if(value.values.length == 1)
64         {
65             final switch(value.values[0].kind) with(SDLValue.Kind)
66             {
67                 case null_:     type |= JsonSchemaType.null_; break;
68                 case text:      type |= JsonSchemaType.string_; break;
69                 case binary:    throw new Exception("binary is not supported, at least for now.");
70                 case int_:      type |= JsonSchemaType.integer | JsonSchemaType.number; break;
71                 case long_:     type |= JsonSchemaType.integer | JsonSchemaType.number; break;
72                 case decimal:   type |= JsonSchemaType.number; break;
73                 case float_:    type |= JsonSchemaType.number; break;
74                 case double_:   type |= JsonSchemaType.number; break;
75                 case bool_:     type |= JsonSchemaType.boolean; break;
76                 case dateTime:  throw new Exception("dateTime is not supported, at least for now");
77                 case date:      throw new Exception("date is not supported, at least for now");
78                 case duration:  throw new Exception("duration is not supported, at least for now");
79             }
80         }
81 
82         return type;
83     }
84 
85     bool isNull(AggregateType value) { return value.values[0].isNull; }
86     string getString(AggregateType value) { return value.values[0].textValue; }
87     long getInteger(AggregateType value) { return value.values[0].isInt ? value.values[0].intValue : value.values[0].longValue; }
88     double getNumber(AggregateType value) { return value.values[0].isFloat ? value.values[0].floatValue : value.values[0].doubleValue; }
89     bool getBoolean(AggregateType value) { return value.values[0].boolValue; }
90 
91     AggregateType getArrayValue(AggregateType value, size_t index) { return SDLNode("__value", [value.values[index]]); }
92     AggregateType getObjectProperty(AggregateType value, string index) { return value.children.filter!(c => c.qualifiedName == index).front; }
93     AggregateType getObjectAttribute(AggregateType value, string index) { return SDLNode("__value", [value.getAttribute(index)]); }
94 }