1 module vision.json.patch.operation.add;
2 
3 public import vision.json.patch.operation.basic;
4 
5 class AddOperation : DiffOperation
6 {
7 	JsonItem value;
8 	override @property string op() pure const @safe { return "add"; }
9 	
10 	this(T)(T path, JsonItem value) @safe
11 	{
12 		super(path);
13 		this.value = value;
14 	}
15 
16 	override JsonItem toJson() const
17 	{
18 		JsonItem retval = super.toJson;
19 		retval.object["value"] = value;
20 		return retval;
21 	}
22 	
23 	override bool applyToPtr(JsonItem* document) const
24 	{
25 		import std.conv : to;
26 		
27 		if(path.isRoot)
28 		{
29 			*document = value;
30 			return true;
31 		}
32 		auto parent = path.parent.evaluate(document);
33 		string index = path.lastComponent;
34 		
35 		if(parent.isNull)
36 			return error("No path "~path.parent.get.toString()~" to add to");
37 			
38 		switch(parent.type)
39 		{
40 			case JSON_TYPE.ARRAY:
41 				if(index == "-")
42 				{
43 					parent.array ~= value;
44 				}
45 				else try 
46 				{
47 					import std.array: insertInPlace;
48 					
49 					auto numeric = index.to!int;
50 					if(numeric > parent.array.length)
51 						return error("Too big index in "~path.toString~", length="~parent.array.length.to!string);
52 					parent.array.insertInPlace(numeric, value);
53 				}
54 				catch(Exception e)
55 				{
56 					return error(parent.get.toString~" is array, index can't be "~index);
57 				}
58 				break;
59 			case JSON_TYPE.OBJECT:
60 				parent.get.object[index] = value;
61 				break;
62 			
63 			default: 
64 				return error(parent.get.toString ~ " is not array or object");
65 		}
66 		return true;
67 	}
68 }