1 /***********************************************************************************************
2 *	Copyright: © 2017-2021 UI Manufaktur UG
3 *	License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
4 *	Authors: UI Manufaktur Team
5 *	Documentation [DE]: https://ui-manufaktur.com/docu/uim-core/dataytypes/uuid
6 ************************************************************************************************/
7 module uim.core.datatypes.uuid;
8 
9 @safe: 
10 import uim.core;
11 import std.uuid;
12 
13 enum NULLID = "00000000-0000-0000-0000-000000000000";
14 enum NULLUUID = UUID(NULLID);
15 
16 @safe auto isNull(UUID id) { return (NULLUUID == id); }
17 
18 @safe bool isUUID(string uuid, bool stripInput = true) {
19 	import std.meta;
20 	alias skipSeq = AliasSeq!(8, 13, 18, 23);
21 	alias byteSeq = AliasSeq!(0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34);
22 	import std.conv : to, parse;
23 
24 	auto u = uuid;
25 	if (stripInput) u = u.strip;
26 	if (u.length < 36) return false; // "Insufficient Input"
27 	if (u.length > 36) return false; // "Input is too long, need exactly 36 characters";
28 
29 	static immutable skipInd = [skipSeq];
30 	foreach (pos; skipInd) if (u[pos] != '-') return false; // Expected '-'
31 	
32 	foreach (i, p; byteSeq) {
33 		enum uint s = 'a'-10-'0';
34 		uint h = u[p];
35 		uint l = u[p+1];
36 		if (h < '0') return false;
37 		if (l < '0') return false;
38 		if (h > '9') {
39 			h |= 0x20; //poorman's tolower
40 			if (h < 'a') return false;
41 			if (h > 'f') return false;
42 			h -= s;
43 		}
44 		if (l > '9') {
45 			l |= 0x20; //poorman's tolower
46 			if (l < 'a') return false;
47 			if (l > 'f') return false;
48 			l -= s;
49 		}
50 		h -= '0';
51 		l -= '0';
52 	}
53 	return true;
54 }
55 unittest {
56 	assert(isUUID(randomUUID.toString));
57 	assert(!isUUID(randomUUID.toString[0..4]));
58 }
59 
60 @safe string[] toString(UUID[] ids) {
61 	auto result = new string[ids.length];
62 	foreach(i, id; ids) result[i] = id.toString;
63 	return result;
64 }
65 unittest {
66 	/// TODO
67 }
68 
69 @safe string[] toStringCompact(UUID[] ids) {
70 	auto result = new string[ids.length];
71 	foreach(i, id; ids) result[i] = id.toStringCompact;
72 	return result;
73 }
74 @safe string toStringCompact(UUID id) { return id.toString.replace("_", ""); }
75 unittest {
76 	/// TODO
77 }
78 
79 @safe UUID[] toUUID(string[] ids) {
80 	auto result = new UUID[ids.length];
81 	foreach(i, id; ids) result[i] = toUUID(id);
82 	return result;
83 }
84 @safe UUID toUUID(string id) {
85 	import std..string;
86 	// TODO strip quotes
87 	// if ((id.indexOf("'") == 0) || (id.indexOf(`"`) == 0)) 
88 
89 	return UUID(id.strip);
90 }
91 unittest {
92 	/// TODO
93 }