Adjust style of dub.internal.vibecompat.data.json to latest vibe.d and use vibe.data.json if available.
1 parent 9c8caee commit 304f32dc43434e3cde0b9262809d7be71092d3f8
@Sönke Ludwig Sönke Ludwig authored on 18 Nov 2013
Showing 6 changed files
View
4
source/dub/dub.d
 
/// Outputs a JSON description of the project, including its dependencies.
void describeProject(BuildPlatform platform, string config)
{
auto dst = Json.EmptyObject;
auto dst = Json.emptyObject;
dst.configuration = config;
dst.compiler = platform.compiler;
dst.architecture = platform.architecture.serializeToJson();
dst.platform = platform.platform.serializeToJson();
supplier = ps;
break;
} catch(Exception) {}
}
enforce(pinfo.type != Json.Type.Undefined, "No package "~packageId~" was found matching the dependency "~dep.toString());
enforce(pinfo.type != Json.Type.undefined, "No package "~packageId~" was found matching the dependency "~dep.toString());
string ver = pinfo["version"].get!string;
 
Path placement;
final switch (location) {
View
2
■■■
source/dub/internal/utils.d
return true;
}
 
Json jsonFromFile(Path file, bool silent_fail = false) {
if( silent_fail && !existsFile(file) ) return Json.EmptyObject;
if( silent_fail && !existsFile(file) ) return Json.emptyObject;
auto f = openFile(file.toNativeString(), FileMode.Read);
scope(exit) f.close();
auto text = stripUTF8Bom(cast(string)f.readAll());
return parseJson(text);
View
470
source/dub/internal/vibecompat/data/json.d
/**
JSON serialization and value handling.
 
This module provides the Json struct for reading, writing and manipulating JSON values in a seamless,
JavaScript like way. De(serialization) of arbitrary D types is also supported.
 
Examples:
 
---
void manipulateJson(Json j)
{
// object members can be accessed using member syntax, just like in JavaScript
j = Json.EmptyObject;
j.name = "Example";
j.id = 1;
 
// retrieving the values is done using get()
assert(j["name"].get!string == "Example");
assert(j["id"].get!int == 1);
 
// semantic convertions can be done using to()
assert(j.id.to!string == "1");
 
// prints:
// name: "Example"
// id: 1
foreach( string key, value; j ){
writefln("%s: %s", key, value);
}
 
// print out as JSON: {"name": "Example", "id": 1}
writefln("JSON: %s", j.toString());
}
---
 
Copyright: © 2012 RejectedSoftware e.K.
License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
Authors: Sönke Ludwig
*/
module dub.internal.vibecompat.data.json;
 
version (Have_vibe_d) public import vibe.data.json;
else:
 
import dub.internal.vibecompat.data.utils;
 
import std.array;
string m_string;
Json[] m_array;
Json[string] m_object;
};
Type m_type = Type.Undefined;
Type m_type = Type.undefined;
}
 
/** Represents the run time type of a JSON value.
*/
enum Type {
/// A non-existent value in a JSON object
Undefined,
undefined,
/// Null value
Null,
null_,
/// Boolean value
Bool,
bool_,
/// 64-bit integer value
Int,
int_,
/// 64-bit floating point value
Float,
float_,
/// UTF-8 string
String,
string,
/// Array of JSON values
Array,
array,
/// JSON object aka. dictionary from string to Json
Object
}
 
/// New JSON value of Type.Undefined
static @property Json Undefined() { return Json(); }
 
/// New JSON value of Type.Object
static @property Json EmptyObject() { return Json(cast(Json[string])null); }
 
/// New JSON value of Type.Array
static @property Json EmptyArray() { return Json(cast(Json[])null); }
object
}
 
/// New JSON value of Type.undefined
static @property Json undefined() { return Json(); }
 
/// New JSON value of Type.object
static @property Json emptyObject() { return Json(cast(Json[string])null); }
 
/// New JSON value of Type.array
static @property Json emptyArray() { return Json(cast(Json[])null); }
 
version(JsonLineNumbers) int line;
 
/**
Constructor for a JSON object.
*/
this(typeof(null)) { m_type = Type.Null; }
/// ditto
this(bool v) { m_type = Type.Bool; m_bool = v; }
/// ditto
this(int v) { m_type = Type.Int; m_int = v; }
/// ditto
this(long v) { m_type = Type.Int; m_int = v; }
/// ditto
this(double v) { m_type = Type.Float; m_float = v; }
/// ditto
this(string v) { m_type = Type.String; m_string = v; }
/// ditto
this(Json[] v) { m_type = Type.Array; m_array = v; }
/// ditto
this(Json[string] v) { m_type = Type.Object; m_object = v; }
this(typeof(null)) { m_type = Type.null_; }
/// ditto
this(bool v) { m_type = Type.bool_; m_bool = v; }
/// ditto
this(int v) { m_type = Type.int_; m_int = v; }
/// ditto
this(long v) { m_type = Type.int_; m_int = v; }
/// ditto
this(double v) { m_type = Type.float_; m_float = v; }
/// ditto
this(string v) { m_type = Type.string; m_string = v; }
/// ditto
this(Json[] v) { m_type = Type.array; m_array = v; }
/// ditto
this(Json[string] v) { m_type = Type.object; m_object = v; }
 
/**
Allows assignment of D values to a JSON value.
*/
ref Json opAssign(Json v){
m_type = v.m_type;
final switch(m_type){
case Type.Undefined: m_string = null; break;
case Type.Null: m_string = null; break;
case Type.Bool: m_bool = v.m_bool; break;
case Type.Int: m_int = v.m_int; break;
case Type.Float: m_float = v.m_float; break;
case Type.String: m_string = v.m_string; break;
case Type.Array: m_array = v.m_array; break;
case Type.Object: m_object = v.m_object; break;
case Type.undefined: m_string = null; break;
case Type.null_: m_string = null; break;
case Type.bool_: m_bool = v.m_bool; break;
case Type.int_: m_int = v.m_int; break;
case Type.float_: m_float = v.m_float; break;
case Type.string: m_string = v.m_string; break;
case Type.array: m_array = v.m_array; break;
case Type.object: m_object = v.m_object; break;
}
return this;
}
/// ditto
void opAssign(typeof(null)) { m_type = Type.Null; m_string = null; }
/// ditto
bool opAssign(bool v) { m_type = Type.Bool; m_bool = v; return v; }
/// ditto
int opAssign(int v) { m_type = Type.Int; m_int = v; return v; }
/// ditto
long opAssign(long v) { m_type = Type.Int; m_int = v; return v; }
/// ditto
double opAssign(double v) { m_type = Type.Float; m_float = v; return v; }
/// ditto
string opAssign(string v) { m_type = Type.String; m_string = v; return v; }
/// ditto
Json[] opAssign(Json[] v) { m_type = Type.Array; m_array = v; return v; }
/// ditto
Json[string] opAssign(Json[string] v) { m_type = Type.Object; m_object = v; return v; }
void opAssign(typeof(null)) { m_type = Type.null_; m_string = null; }
/// ditto
bool opAssign(bool v) { m_type = Type.bool_; m_bool = v; return v; }
/// ditto
int opAssign(int v) { m_type = Type.int_; m_int = v; return v; }
/// ditto
long opAssign(long v) { m_type = Type.int_; m_int = v; return v; }
/// ditto
double opAssign(double v) { m_type = Type.float_; m_float = v; return v; }
/// ditto
string opAssign(string v) { m_type = Type.string; m_string = v; return v; }
/// ditto
Json[] opAssign(Json[] v) { m_type = Type.array; m_array = v; return v; }
/// ditto
Json[string] opAssign(Json[string] v) { m_type = Type.object; m_object = v; return v; }
 
/**
The current type id of this JSON object.
*/
checkType!(Json[string])();
if( auto pv = key in m_object )
return *pv;
m_object[key] = Json();
m_object[key].m_type = Type.Undefined; // DMDBUG: AAs are teh $H1T!!!11
assert(m_object[key].type == Type.Undefined);
m_object[key].m_type = Type.undefined; // DMDBUG: AAs are teh $H1T!!!11
assert(m_object[key].type == Type.undefined);
m_object[key].m_string = key;
return m_object[key];
}
 
*/
@property size_t length()
const {
switch(m_type){
case Type.String: return m_string.length;
case Type.Array: return m_array.length;
case Type.Object: return m_object.length;
case Type.string: return m_string.length;
case Type.array: return m_array.length;
case Type.object: return m_object.length;
default:
enforce(false, "Json.length() can only be called on strings, arrays and objects, not "~.to!string(m_type)~".");
return 0;
}
Allows foreach iterating over JSON objects and arrays.
*/
int opApply(int delegate(ref Json obj) del)
{
enforce(m_type == Type.Array || m_type == Type.Object, "opApply may only be called on objects and arrays, not "~.to!string(m_type)~".");
if( m_type == Type.Array ){
enforce(m_type == Type.array || m_type == Type.object, "opApply may only be called on objects and arrays, not "~.to!string(m_type)~".");
if( m_type == Type.array ){
foreach( ref v; m_array )
if( auto ret = del(v) )
return ret;
return 0;
} else {
foreach( ref v; m_object )
if( v.type != Type.Undefined )
if( v.type != Type.undefined )
if( auto ret = del(v) )
return ret;
return 0;
}
}
/// ditto
int opApply(int delegate(ref const Json obj) del)
const {
enforce(m_type == Type.Array || m_type == Type.Object, "opApply may only be called on objects and arrays, not "~.to!string(m_type)~".");
if( m_type == Type.Array ){
enforce(m_type == Type.array || m_type == Type.object, "opApply may only be called on objects and arrays, not "~.to!string(m_type)~".");
if( m_type == Type.array ){
foreach( ref v; m_array )
if( auto ret = del(v) )
return ret;
return 0;
} else {
foreach( ref v; m_object )
if( v.type != Type.Undefined )
if( v.type != Type.undefined )
if( auto ret = del(v) )
return ret;
return 0;
}
}
/// ditto
int opApply(int delegate(ref size_t idx, ref Json obj) del)
{
enforce(m_type == Type.Array, "opApply may only be called on arrays, not "~.to!string(m_type)~"");
enforce(m_type == Type.array, "opApply may only be called on arrays, not "~.to!string(m_type)~"");
foreach( idx, ref v; m_array )
if( auto ret = del(idx, v) )
return ret;
return 0;
}
/// ditto
int opApply(int delegate(ref size_t idx, ref const Json obj) del)
const {
enforce(m_type == Type.Array, "opApply may only be called on arrays, not "~.to!string(m_type)~".");
enforce(m_type == Type.array, "opApply may only be called on arrays, not "~.to!string(m_type)~".");
foreach( idx, ref v; m_array )
if( auto ret = del(idx, v) )
return ret;
return 0;
}
/// ditto
int opApply(int delegate(ref string idx, ref Json obj) del)
{
enforce(m_type == Type.Object, "opApply may only be called on objects, not "~.to!string(m_type)~".");
enforce(m_type == Type.object, "opApply may only be called on objects, not "~.to!string(m_type)~".");
foreach( idx, ref v; m_object )
if( v.type != Type.Undefined )
if( v.type != Type.undefined )
if( auto ret = del(idx, v) )
return ret;
return 0;
}
/// ditto
int opApply(int delegate(ref string idx, ref const Json obj) del)
const {
enforce(m_type == Type.Object, "opApply may only be called on objects, not "~.to!string(m_type)~".");
enforce(m_type == Type.object, "opApply may only be called on objects, not "~.to!string(m_type)~".");
foreach( idx, ref v; m_object )
if( v.type != Type.Undefined )
if( v.type != Type.undefined )
if( auto ret = del(idx, v) )
return ret;
return 0;
}
@property inout(T) to(T)()
inout {
static if( is(T == bool) ){
final switch( m_type ){
case Type.Undefined: return false;
case Type.Null: return false;
case Type.Bool: return m_bool;
case Type.Int: return m_int != 0;
case Type.Float: return m_float != 0;
case Type.String: return m_string.length > 0;
case Type.Array: return m_array.length > 0;
case Type.Object: return m_object.length > 0;
case Type.undefined: return false;
case Type.null_: return false;
case Type.bool_: return m_bool;
case Type.int_: return m_int != 0;
case Type.float_: return m_float != 0;
case Type.string: return m_string.length > 0;
case Type.array: return m_array.length > 0;
case Type.object: return m_object.length > 0;
}
} else static if( is(T == double) ){
final switch( m_type ){
case Type.Undefined: return T.init;
case Type.Null: return 0;
case Type.Bool: return m_bool ? 1 : 0;
case Type.Int: return m_int;
case Type.Float: return m_float;
case Type.String: return .to!double(cast(string)m_string);
case Type.Array: return double.init;
case Type.Object: return double.init;
case Type.undefined: return T.init;
case Type.null_: return 0;
case Type.bool_: return m_bool ? 1 : 0;
case Type.int_: return m_int;
case Type.float_: return m_float;
case Type.string: return .to!double(cast(string)m_string);
case Type.array: return double.init;
case Type.object: return double.init;
}
} else static if( is(T == float) ){
final switch( m_type ){
case Type.Undefined: return T.init;
case Type.Null: return 0;
case Type.Bool: return m_bool ? 1 : 0;
case Type.Int: return m_int;
case Type.Float: return m_float;
case Type.String: return .to!float(cast(string)m_string);
case Type.Array: return float.init;
case Type.Object: return float.init;
case Type.undefined: return T.init;
case Type.null_: return 0;
case Type.bool_: return m_bool ? 1 : 0;
case Type.int_: return m_int;
case Type.float_: return m_float;
case Type.string: return .to!float(cast(string)m_string);
case Type.array: return float.init;
case Type.object: return float.init;
}
}
else static if( is(T == long) ){
final switch( m_type ){
case Type.Undefined: return 0;
case Type.Null: return 0;
case Type.Bool: return m_bool ? 1 : 0;
case Type.Int: return m_int;
case Type.Float: return cast(long)m_float;
case Type.String: return .to!long(m_string);
case Type.Array: return 0;
case Type.Object: return 0;
case Type.undefined: return 0;
case Type.null_: return 0;
case Type.bool_: return m_bool ? 1 : 0;
case Type.int_: return m_int;
case Type.float_: return cast(long)m_float;
case Type.string: return .to!long(m_string);
case Type.array: return 0;
case Type.object: return 0;
}
} else static if( is(T : long) ){
final switch( m_type ){
case Type.Undefined: return 0;
case Type.Null: return 0;
case Type.Bool: return m_bool ? 1 : 0;
case Type.Int: return cast(T)m_int;
case Type.Float: return cast(T)m_float;
case Type.String: return cast(T).to!long(cast(string)m_string);
case Type.Array: return 0;
case Type.Object: return 0;
case Type.undefined: return 0;
case Type.null_: return 0;
case Type.bool_: return m_bool ? 1 : 0;
case Type.int_: return cast(T)m_int;
case Type.float_: return cast(T)m_float;
case Type.string: return cast(T).to!long(cast(string)m_string);
case Type.array: return 0;
case Type.object: return 0;
}
} else static if( is(T == string) ){
switch( m_type ){
default: return toString();
case Type.String: return m_string;
case Type.string: return m_string;
}
} else static if( is(T == Json[]) ){
switch( m_type ){
default: return Json([this]);
case Type.Array: return m_array;
case Type.array: return m_array;
}
} else static if( is(T == Json[string]) ){
switch( m_type ){
default: return Json(["value": this]);
case Type.Object: return m_object;
case Type.object: return m_object;
}
} else static assert("JSON can only be casted to (bool, long, double, string, Json[] or Json[string]. Not "~T.stringof~".");
}
 
static if( op == "~" ){
checkType!bool();
return Json(~m_bool);
} else static if( op == "+" || op == "-" || op == "++" || op == "--" ){
if( m_type == Type.Int ) mixin("return Json("~op~"m_int);");
else if( m_type == Type.Float ) mixin("return Json("~op~"m_float);");
if( m_type == Type.int_ ) mixin("return Json("~op~"m_int);");
else if( m_type == Type.float_ ) mixin("return Json("~op~"m_float);");
else enforce(false, "'"~op~"' only allowed on scalar types, not on "~.to!string(m_type)~".");
} else static assert("Unsupported operator '"~op~"' for type JSON.");
}
 
Json opBinary(string op)(ref const(Json) other)
const {
enforce(m_type == other.m_type, "Binary operation '"~op~"' between "~.to!string(m_type)~" and "~.to!string(other.m_type)~" JSON objects.");
static if( op == "&&" ){
enforce(m_type == Type.Bool, "'&&' only allowed for Type.Bool, not "~.to!string(m_type)~".");
enforce(m_type == Type.bool_, "'&&' only allowed for Type.bool_, not "~.to!string(m_type)~".");
return Json(m_bool && other.m_bool);
} else static if( op == "||" ){
enforce(m_type == Type.Bool, "'||' only allowed for Type.Bool, not "~.to!string(m_type)~".");
enforce(m_type == Type.bool_, "'||' only allowed for Type.bool_, not "~.to!string(m_type)~".");
return Json(m_bool || other.m_bool);
} else static if( op == "+" ){
if( m_type == Type.Int ) return Json(m_int + other.m_int);
else if( m_type == Type.Float ) return Json(m_float + other.m_float);
if( m_type == Type.int_ ) return Json(m_int + other.m_int);
else if( m_type == Type.float_ ) return Json(m_float + other.m_float);
else enforce(false, "'+' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "-" ){
if( m_type == Type.Int ) return Json(m_int - other.m_int);
else if( m_type == Type.Float ) return Json(m_float - other.m_float);
if( m_type == Type.int_ ) return Json(m_int - other.m_int);
else if( m_type == Type.float_ ) return Json(m_float - other.m_float);
else enforce(false, "'-' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "*" ){
if( m_type == Type.Int ) return Json(m_int * other.m_int);
else if( m_type == Type.Float ) return Json(m_float * other.m_float);
if( m_type == Type.int_ ) return Json(m_int * other.m_int);
else if( m_type == Type.float_ ) return Json(m_float * other.m_float);
else enforce(false, "'*' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "/" ){
if( m_type == Type.Int ) return Json(m_int / other.m_int);
else if( m_type == Type.Float ) return Json(m_float / other.m_float);
if( m_type == Type.int_ ) return Json(m_int / other.m_int);
else if( m_type == Type.float_ ) return Json(m_float / other.m_float);
else enforce(false, "'/' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "%" ){
if( m_type == Type.Int ) return Json(m_int % other.m_int);
else if( m_type == Type.Float ) return Json(m_float % other.m_float);
if( m_type == Type.int_ ) return Json(m_int % other.m_int);
else if( m_type == Type.float_ ) return Json(m_float % other.m_float);
else enforce(false, "'%' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "~" ){
if( m_type == Type.String ) return Json(m_string ~ other.m_string);
if( m_type == Type.string ) return Json(m_string ~ other.m_string);
else enforce(false, "'~' only allowed for strings, not "~.to!string(m_type)~".");
} else static assert("Unsupported operator '"~op~"' for type JSON.");
assert(false);
}
Json opBinary(string op)(Json other)
if( op == "~" )
{
static if( op == "~" ){
if( m_type == Type.String ) return Json(m_string ~ other.m_string);
else if( m_type == Type.Array ) return Json(m_array ~ other.m_array);
if( m_type == Type.string ) return Json(m_string ~ other.m_string);
else if( m_type == Type.array ) return Json(m_array ~ other.m_array);
else enforce(false, "'~' only allowed for strings and arrays, not "~.to!string(m_type)~".");
} else static assert("Unsupported operator '"~op~"' for type JSON.");
assert(false);
}
if( op == "+" || op == "-" || op == "*" ||op == "/" || op == "%" )
{
enforce(m_type == other.m_type, "Binary operation '"~op~"' between "~.to!string(m_type)~" and "~.to!string(other.m_type)~" JSON objects.");
static if( op == "+" ){
if( m_type == Type.Int ) m_int += other.m_int;
else if( m_type == Type.Float ) m_float += other.m_float;
if( m_type == Type.int_ ) m_int += other.m_int;
else if( m_type == Type.float_ ) m_float += other.m_float;
else enforce(false, "'+' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "-" ){
if( m_type == Type.Int ) m_int -= other.m_int;
else if( m_type == Type.Float ) m_float -= other.m_float;
if( m_type == Type.int_ ) m_int -= other.m_int;
else if( m_type == Type.float_ ) m_float -= other.m_float;
else enforce(false, "'-' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "*" ){
if( m_type == Type.Int ) m_int *= other.m_int;
else if( m_type == Type.Float ) m_float *= other.m_float;
if( m_type == Type.int_ ) m_int *= other.m_int;
else if( m_type == Type.float_ ) m_float *= other.m_float;
else enforce(false, "'*' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "/" ){
if( m_type == Type.Int ) m_int /= other.m_int;
else if( m_type == Type.Float ) m_float /= other.m_float;
if( m_type == Type.int_ ) m_int /= other.m_int;
else if( m_type == Type.float_ ) m_float /= other.m_float;
else enforce(false, "'/' only allowed for scalar types, not "~.to!string(m_type)~".");
} else static if( op == "%" ){
if( m_type == Type.Int ) m_int %= other.m_int;
else if( m_type == Type.Float ) m_float %= other.m_float;
if( m_type == Type.int_ ) m_int %= other.m_int;
else if( m_type == Type.float_ ) m_float %= other.m_float;
else enforce(false, "'%' only allowed for scalar types, not "~.to!string(m_type)~".");
} /*else static if( op == "~" ){
if( m_type == Type.String ) m_string ~= other.m_string;
else if( m_type == Type.Array ) m_array ~= other.m_array;
if( m_type == Type.string ) m_string ~= other.m_string;
else if( m_type == Type.array ) m_array ~= other.m_array;
else enforce(false, "'%' only allowed for scalar types, not "~.to!string(m_type)~".");
}*/ else static assert("Unsupported operator '"~op~"' for type JSON.");
assert(false);
}
Json opBinary(string op)(string other) const { checkType!string(); mixin("return Json(m_string "~op~" other);"); }
/// ditto
Json opBinary(string op)(Json other)
if (op == "~") {
if (m_type == Type.Array) return Json(m_array ~ other);
if (m_type == Type.array) return Json(m_array ~ other);
else return Json(this ~ other);
}
/// ditto
Json opBinaryRight(string op)(bool other) const { checkType!bool(); mixin("return Json(other "~op~" m_bool);"); }
inout(Json)* opBinaryRight(string op)(string other) inout if(op == "in") {
checkType!(Json[string])();
auto pv = other in m_object;
if( !pv ) return null;
if( pv.type == Type.Undefined ) return null;
if( pv.type == Type.undefined ) return null;
return pv;
}
 
/**
bool opEquals(ref const Json other)
const {
if( m_type != other.m_type ) return false;
final switch(m_type){
case Type.Undefined: return false;
case Type.Null: return true;
case Type.Bool: return m_bool == other.m_bool;
case Type.Int: return m_int == other.m_int;
case Type.Float: return m_float == other.m_float;
case Type.String: return m_string == other.m_string;
case Type.Array: return m_array == other.m_array;
case Type.Object: return m_object == other.m_object;
case Type.undefined: return false;
case Type.null_: return true;
case Type.bool_: return m_bool == other.m_bool;
case Type.int_: return m_int == other.m_int;
case Type.float_: return m_float == other.m_float;
case Type.string: return m_string == other.m_string;
case Type.array: return m_array == other.m_array;
case Type.object: return m_object == other.m_object;
}
}
/// ditto
bool opEquals(const Json other) const { return opEquals(other); }
/// ditto
bool opEquals(typeof(null)) const { return m_type == Type.Null; }
/// ditto
bool opEquals(bool v) const { return m_type == Type.Bool && m_bool == v; }
/// ditto
bool opEquals(long v) const { return m_type == Type.Int && m_int == v; }
/// ditto
bool opEquals(double v) const { return m_type == Type.Float && m_float == v; }
/// ditto
bool opEquals(string v) const { return m_type == Type.String && m_string == v; }
bool opEquals(typeof(null)) const { return m_type == Type.null_; }
/// ditto
bool opEquals(bool v) const { return m_type == Type.bool_ && m_bool == v; }
/// ditto
bool opEquals(long v) const { return m_type == Type.int_ && m_int == v; }
/// ditto
bool opEquals(double v) const { return m_type == Type.float_ && m_float == v; }
/// ditto
bool opEquals(string v) const { return m_type == Type.string && m_string == v; }
 
/**
Compares two JSON values.
 
int opCmp(ref const Json other)
const {
if( m_type != other.m_type ) return m_type < other.m_type ? -1 : 1;
final switch(m_type){
case Type.Undefined: return 0;
case Type.Null: return 0;
case Type.Bool: return m_bool < other.m_bool ? -1 : m_bool == other.m_bool ? 0 : 1;
case Type.Int: return m_int < other.m_int ? -1 : m_int == other.m_int ? 0 : 1;
case Type.Float: return m_float < other.m_float ? -1 : m_float == other.m_float ? 0 : 1;
case Type.String: return m_string < other.m_string ? -1 : m_string == other.m_string ? 0 : 1;
case Type.Array: return m_array < other.m_array ? -1 : m_array == other.m_array ? 0 : 1;
case Type.Object:
case Type.undefined: return 0;
case Type.null_: return 0;
case Type.bool_: return m_bool < other.m_bool ? -1 : m_bool == other.m_bool ? 0 : 1;
case Type.int_: return m_int < other.m_int ? -1 : m_int == other.m_int ? 0 : 1;
case Type.float_: return m_float < other.m_float ? -1 : m_float == other.m_float ? 0 : 1;
case Type.string: return m_string < other.m_string ? -1 : m_string == other.m_string ? 0 : 1;
case Type.array: return m_array < other.m_array ? -1 : m_array == other.m_array ? 0 : 1;
case Type.object:
enforce(false, "JSON objects cannot be compared.");
assert(false);
}
}
/**
Returns the type id corresponding to the given D type.
*/
static @property Type typeId(T)() {
static if( is(T == typeof(null)) ) return Type.Null;
else static if( is(T == bool) ) return Type.Bool;
else static if( is(T == double) ) return Type.Float;
else static if( is(T == float) ) return Type.Float;
else static if( is(T : long) ) return Type.Int;
else static if( is(T == string) ) return Type.String;
else static if( is(T == Json[]) ) return Type.Array;
else static if( is(T == Json[string]) ) return Type.Object;
static if( is(T == typeof(null)) ) return Type.null_;
else static if( is(T == bool) ) return Type.bool_;
else static if( is(T == double) ) return Type.float_;
else static if( is(T == float) ) return Type.float_;
else static if( is(T : long) ) return Type.int_;
else static if( is(T == string) ) return Type.string;
else static if( is(T == Json[]) ) return Type.array;
else static if( is(T == Json[string]) ) return Type.object;
else static assert(false, "Unsupported JSON type '"~T.stringof~"'. Only bool, long, double, string, Json[] and Json[string] are allowed.");
}
 
/**
 
private void checkType(T)()
const {
string dbg;
if( m_type == Type.Undefined ) dbg = " field "~m_string;
if( m_type == Type.undefined ) dbg = " field "~m_string;
enforce(typeId!T == m_type, "Trying to access JSON"~dbg~" of type "~.to!string(m_type)~" as "~T.stringof~".");
}
 
/*invariant()
{
assert(m_type >= Type.Undefined && m_type <= Type.Object);
assert(m_type >= Type.undefined && m_type <= Type.object);
}*/
}
 
 
default:
enforce(false, "Expected valid json token, got '"~to!string(range.length)~range[0 .. range.length>12?12:range.length]~"'.");
}
 
assert(ret.type != Json.Type.Undefined);
assert(ret.type != Json.Type.undefined);
version(JsonLineNumbers) ret.line = curline;
return ret;
}
 
The following types of values are supported:
 
$(DL
$(DT Json) $(DD Used as-is)
$(DT null) $(DD Converted to Json.Type.Null)
$(DT bool) $(DD Converted to Json.Type.Bool)
$(DT null) $(DD Converted to Json.Type.null_)
$(DT bool) $(DD Converted to Json.Type.bool_)
$(DT float, double) $(DD Converted to Json.Type.Double)
$(DT short, ushort, int, uint, long, ulong) $(DD Converted to Json.Type.Int)
$(DT string) $(DD Converted to Json.Type.String)
$(DT T[]) $(DD Converted to Json.Type.Array)
$(DT T[string]) $(DD Converted to Json.Type.Object)
$(DT struct) $(DD Converted to Json.Type.Object)
$(DT class) $(DD Converted to Json.Type.Object or Json.Type.Null)
$(DT short, ushort, int, uint, long, ulong) $(DD Converted to Json.Type.int_)
$(DT string) $(DD Converted to Json.Type.string)
$(DT T[]) $(DD Converted to Json.Type.array)
$(DT T[string]) $(DD Converted to Json.Type.object)
$(DT struct) $(DD Converted to Json.Type.object)
$(DT class) $(DD Converted to Json.Type.object or Json.Type.null_)
)
 
All entries of an array or an associative array, as well as all R/W properties and
all public fields of a struct/class are recursively serialized using the same rules.
}
}
return dst;
} else static if( is(T == class) ){
if( src.type == Json.Type.Null ) return null;
if( src.type == Json.Type.null_ ) return null;
auto dst = new T;
foreach( m; __traits(allMembers, T) ){
static if( isRWPlainField!(T, m) || isRWField!(T, m) ){
alias typeof(__traits(getMember, dst, m)) TM;
}
}
return dst;
} else static if( isPointer!T ){
if( src.type == Json.Type.Null ) return null;
if( src.type == Json.Type.null_ ) return null;
alias typeof(*T.init) TD;
dst = new TD;
*dst = deserializeJson!TD(src);
return dst;
void writeJsonString(R)(ref R dst, in Json json)
// if( isOutputRange!R && is(ElementEncodingType!R == char) )
{
final switch( json.type ){
case Json.Type.Undefined: dst.put("undefined"); break;
case Json.Type.Null: dst.put("null"); break;
case Json.Type.Bool: dst.put(cast(bool)json ? "true" : "false"); break;
case Json.Type.Int: formattedWrite(dst, "%d", json.get!long); break;
case Json.Type.Float: formattedWrite(dst, "%.16g", json.get!double); break;
case Json.Type.String:
case Json.Type.undefined: dst.put("undefined"); break;
case Json.Type.null_: dst.put("null"); break;
case Json.Type.bool_: dst.put(cast(bool)json ? "true" : "false"); break;
case Json.Type.int_: formattedWrite(dst, "%d", json.get!long); break;
case Json.Type.float_: formattedWrite(dst, "%.16g", json.get!double); break;
case Json.Type.string:
dst.put("\"");
jsonEscape(dst, cast(string)json);
dst.put("\"");
break;
case Json.Type.Array:
case Json.Type.array:
dst.put("[");
bool first = true;
foreach( ref const Json e; json ){
if( e.type == Json.Type.Undefined ) continue;
if( e.type == Json.Type.undefined ) continue;
if( !first ) dst.put(",");
first = false;
writeJsonString(dst, e);
}
dst.put("]");
break;
case Json.Type.Object:
case Json.Type.object:
dst.put("{");
bool first = true;
foreach( string k, ref const Json e; json ){
if( e.type == Json.Type.Undefined ) continue;
if( e.type == Json.Type.undefined ) continue;
if( !first ) dst.put(",");
first = false;
dst.put("\"");
jsonEscape(dst, k);
void writePrettyJsonString(R)(ref R dst, in Json json, int level = 0)
// if( isOutputRange!R && is(ElementEncodingType!R == char) )
{
final switch( json.type ){
case Json.Type.Undefined: dst.put("undefined"); break;
case Json.Type.Null: dst.put("null"); break;
case Json.Type.Bool: dst.put(cast(bool)json ? "true" : "false"); break;
case Json.Type.Int: formattedWrite(dst, "%d", json.get!long); break;
case Json.Type.Float: formattedWrite(dst, "%.16g", json.get!double); break;
case Json.Type.String:
case Json.Type.undefined: dst.put("undefined"); break;
case Json.Type.null_: dst.put("null"); break;
case Json.Type.bool_: dst.put(cast(bool)json ? "true" : "false"); break;
case Json.Type.int_: formattedWrite(dst, "%d", json.get!long); break;
case Json.Type.float_: formattedWrite(dst, "%.16g", json.get!double); break;
case Json.Type.string:
dst.put("\"");
jsonEscape(dst, cast(string)json);
dst.put("\"");
break;
case Json.Type.Array:
case Json.Type.array:
dst.put("[");
bool first = true;
foreach( e; json ){
if( e.type == Json.Type.Undefined ) continue;
if( e.type == Json.Type.undefined ) continue;
if( !first ) dst.put(",");
first = false;
dst.put("\n");
foreach( tab; 0 .. level+1 ) dst.put('\t');
foreach( tab; 0 .. level ) dst.put('\t');
}
dst.put("]");
break;
case Json.Type.Object:
case Json.Type.object:
dst.put("{");
bool first = true;
foreach( string k, e; json ){
if( e.type == Json.Type.Undefined ) continue;
if( e.type == Json.Type.undefined ) continue;
if( !first ) dst.put(",");
dst.put("\n");
first = false;
foreach( tab; 0 .. level+1 ) dst.put('\t');
View
14
source/dub/package_.d
 
// prettify files output
Json[] files;
foreach (f; bs.sourceFiles) {
auto jf = Json.EmptyObject;
auto jf = Json.emptyObject;
jf.path = f;
jf["type"] = "source";
files ~= jf;
}
foreach (f; bs.importFiles) {
auto jf = Json.EmptyObject;
auto jf = Json.emptyObject;
jf.path = f;
jf["type"] = "import";
files ~= jf;
}
foreach (f; bs.stringImportFiles) {
auto jf = Json.EmptyObject;
auto jf = Json.emptyObject;
jf.path = f;
jf["type"] = "stringImport";
files ~= jf;
}
case "dependencies":
foreach( string pkg, verspec; value ) {
enforce(pkg !in this.dependencies, "The dependency '"~pkg~"' is specified more than once." );
Dependency dep;
if( verspec.type == Json.Type.Object ){
if( verspec.type == Json.Type.object ){
enforce("version" in verspec, "Package information provided for package " ~ pkg ~ " is missing a version field.");
auto ver = verspec["version"].get!string;
if( auto pp = "path" in verspec ) {
// This enforces the "version" specifier to be a simple version,
}
 
Json toJson()
const {
auto ret = Json.EmptyObject;
auto ret = Json.emptyObject;
if( this.dependencies !is null ){
auto deps = Json.EmptyObject;
auto deps = Json.emptyObject;
foreach( pack, d; this.dependencies ){
if( d.path.empty && !d.optional ){
deps[pack] = d.toString();
} else {
auto vjson = Json.EmptyObject;
auto vjson = Json.emptyObject;
vjson["version"] = d.version_.toString();
if (!d.path.empty) vjson["path"] = d.path.toString();
if (d.optional) vjson["optional"] = true;
deps[pack] = vjson;
View
8
source/dub/packagemanager.d
logDiagnostic("Looking for local package map at %s", local_package_file.toNativeString());
if( !existsFile(local_package_file) ) return;
logDiagnostic("Try to load local package map at %s", local_package_file.toNativeString());
auto packlist = jsonFromFile(list_path ~ LocalPackagesFilename);
enforce(packlist.type == Json.Type.Array, LocalPackagesFilename~" must contain an array.");
enforce(packlist.type == Json.Type.array, LocalPackagesFilename~" must contain an array.");
foreach( pentry; packlist ){
try {
auto name = pentry.name.get!string();
auto path = Path(pentry.path.get!string());
if (name == "*") {
paths ~= path;
} else {
auto ver = pentry["version"].get!string();
auto info = Json.EmptyObject;
auto info = Json.emptyObject;
if( existsFile(path ~ PackageJsonFilename) ) info = jsonFromFile(path ~ PackageJsonFilename);
if( "name" in info && info.name.get!string() != name )
logWarn("Local package at %s has different name than %s (%s)", path.toNativeString(), name, info.name.get!string());
info.name = name;
private void writeLocalPackageList(LocalPackageType type)
{
Json[] newlist;
foreach (p; m_repositories[type].searchPath) {
auto entry = Json.EmptyObject;
auto entry = Json.emptyObject;
entry.name = "*";
entry.path = p.toNativeString();
newlist ~= entry;
}
 
foreach (p; m_repositories[type].localPackages) {
auto entry = Json.EmptyObject;
auto entry = Json.emptyObject;
entry["name"] = p.name;
entry["version"] = p.ver.toString();
entry["path"] = p.path.toNativeString();
newlist ~= entry;
View
12
source/dub/project.d
{
m_packageManager = package_manager;
m_root = project_path;
m_fixedPackage = false;
m_json = Json.EmptyObject;
m_json = Json.emptyObject;
reinit();
}
 
this(PackageManager package_manager, Package pack)
m_packageManager = package_manager;
m_root = pack.path;
m_main = pack;
m_fixedPackage = true;
m_json = Json.EmptyObject;
m_json = Json.emptyObject;
reinit();
}
 
/// Gathers information
// load package description
if (!m_fixedPackage) {
if (!existsFile(m_root~PackageJsonFilename)) {
logWarn("There was no '"~PackageJsonFilename~"' found for the application in '%s'.", m_root.toNativeString());
auto json = Json.EmptyObject;
auto json = Json.emptyObject;
json.name = "unknown";
m_main = new Package(json, m_root);
return;
}
dst.mainPackage = m_main.name;
 
auto configs = getPackageConfigs(platform, config);
 
auto mp = Json.EmptyObject;
auto mp = Json.emptyObject;
m_main.describe(mp, platform, config);
dst.packages = Json([mp]);
 
foreach (dep; m_dependencies) {
auto dp = Json.EmptyObject;
auto dp = Json.emptyObject;
dep.describe(dp, platform, configs[dep.name]);
dst.packages = dst.packages.get!(Json[]) ~ dp;
}
}
private void markUpToDate(string packageId) {
logDebug("markUpToDate(%s)", packageId);
Json create(ref Json json, string object) {
if( object !in json ) json[object] = Json.EmptyObject;
if( object !in json ) json[object] = Json.emptyObject;
return json[object];
}
create(m_json, "dub");
create(m_json["dub"], "lastUpdate");