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 }