1 /**
2  * ae.sys.persistence.json
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.sys.persistence.json;
15 
16 import ae.sys.file : atomicWrite;
17 import ae.sys.persistence.core;
18 
19 // ****************************************************************************
20 
21 /// `FileCache` wrapper which stores a D type as JSON serialization.
22 template JsonFileCache(T, FlushPolicy flushPolicy = FlushPolicy.none)
23 {
24 	import std.file;
25 	import ae.utils.json;
26 
27 	static T getJson(T)(string fileName)
28 	{
29 		return fileName.readText.jsonParse!T;
30 	}
31 
32 	static void putJson(T)(string fileName, in T t)
33 	{
34 		atomicWrite(fileName, t.toJson());
35 	}
36 
37 	alias JsonFileCache = FileCache!(getJson!T, putJson!T, flushPolicy);
38 }
39 
40 unittest
41 {
42 	import std.file;
43 
44 	enum FN = "test1.json";
45 	std.file.write(FN, "{}");
46 	scope(exit) remove(FN);
47 
48 	auto cache = JsonFileCache!(string[string])(FN);
49 	assert(cache.length == 0);
50 }
51 
52 unittest
53 {
54 	import std.file;
55 
56 	enum FN = "test2.json";
57 	scope(exit) if (FN.exists) remove(FN);
58 
59 	auto cache = JsonFileCache!(string[string], FlushPolicy.manual)(FN);
60 	assert(cache.length == 0);
61 	cache["foo"] = "bar";
62 	cache.save();
63 
64 	auto cache2 = JsonFileCache!(string[string])(FN);
65 	assert(cache2["foo"] == "bar");
66 }
67 
68 unittest
69 {
70 	import std.file;
71 
72 	enum FN = "test3.json";
73 	scope(exit) if (FN.exists) remove(FN);
74 
75 	{
76 		auto cache = JsonFileCache!(string[string], FlushPolicy.atScopeExit)(FN);
77 		cache["foo"] = "bar";
78 	}
79 
80 	auto cache2 = JsonFileCache!(string[string])(FN);
81 	assert(cache2["foo"] == "bar");
82 }