1 // Written in the D programming language.
2 
3 module yajl.common;
4 
5 import yajl.c.common;
6 
7 import core.memory : GC;
8 import std.typecons : Nullable;
9 
10 /// Exception for yajl-d
11 class YajlException : Exception
12 {
13     pure @trusted
14     this(string msg, string filename = __FILE__, size_t line = __LINE__)
15     {
16         super(msg, filename, line);
17     }
18 }
19 
20 struct JSONName
21 {
22     string name;
23 }
24 
25 package:
26 
27 extern(C)
28 {
29     void* yajlMalloc(void *ctx, size_t sz)
30     {
31         return GC.malloc(sz);
32     }
33 
34     void* yajlRealloc(void *ctx, void * previous, size_t sz)
35     {
36         return GC.realloc(previous, sz);
37     }
38 
39     void yajlFree(void *ctx, void * ptr)
40     {
41         GC.free(ptr);
42     }
43 
44     yajl_alloc_funcs yajlAllocFuncs = yajl_alloc_funcs(&yajlMalloc, &yajlRealloc, &yajlFree);
45 }
46 
47 template getFieldName(Type, size_t i)
48 {
49     import std.conv : text;
50 
51     static assert((is(Type == class) || is(Type == struct)), "Type must be class or struct: type = " ~ Type.stringof);
52     static assert(i < Type.tupleof.length, text(Type.stringof, " has ", Type.tupleof.length, " attributes: given index = ", i));
53 
54     string helper()
55     {
56         foreach (attribute; __traits(getAttributes, Type.tupleof[i])) {
57             static if (is(typeof(attribute) == JSONName))
58             {
59                 return attribute.name;
60             }
61         }
62 
63         return __traits(identifier, Type.tupleof[i]);
64     }
65 
66     enum getFieldName = helper();
67 }
68 
69 // Code from: http://forum.dlang.org/thread/tkxmfencyhgnxopcsljw@forum.dlang.org#post-mailman.294.1386309272.3242.digitalmars-d-learn:40puremagic.com
70 template isNullable(N)
71 {
72     static if(is(N == Nullable!(T), T) ||
73               is(N == NullableRef!(T), T) ||
74               is(N == Nullable!(T, nV), T, alias nV) && is(typeof(nV) == T))
75     {
76         enum isNullable = true;
77     }
78     else
79     {
80         enum isNullable = false;
81     }
82 }
83 
84 unittest
85 {
86     static assert(isNullable!(Nullable!int));
87     static assert(isNullable!(const Nullable!int));
88     static assert(isNullable!(immutable Nullable!int));
89 
90     static assert(!isNullable!int);
91     static assert(!isNullable!(const int));
92 
93     struct S {}
94     static assert(!isNullable!S);
95 }