This repository was archived by the owner on Aug 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathinternals.dart
192 lines (172 loc) · 5.62 KB
/
internals.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import 'package:certlogic_dart/src/evaluate.dart';
import 'package:certlogic_dart/src/typings.dart';
class CertLogicInternals {
static bool isFalsy(dynamic value) =>
value == false ||
value == null ||
(value is String && value.isEmpty) ||
(value is num && value == 0) ||
(value is Iterable && value.isEmpty) ||
(value is Map && value.isEmpty);
static bool isTruthy(dynamic value) =>
value == true ||
(value is String && value.isNotEmpty) ||
(value is num && value != 0) ||
(value is Iterable && value.isNotEmpty) ||
(value is Map && value.isNotEmpty);
static bool? boolsiness(dynamic value) {
if (isTruthy(value)) {
return true;
}
if (isFalsy(value)) {
return false;
}
return null;
}
/// NOTE:
/// Effectively, any date is always converted to the corresponding ms-precise date-time
/// at midnight of that date. Note that that doesn't properly reflect the resolution of
/// the input date. That effect has to be taken into account by the logic implementor.
static DateTime dateFromString(String str) {
DateTime? dateTime;
if (str.length == 10) {
// No TZ is added
final date = DateTime.parse(str);
dateTime = DateTime.utc(
date.year, date.month, date.day); // Set it to midnight as per specs
}
final regex =
r'(^[T,\-,:,\.0-9]{10,}[+,-])([0-9]|[0-9]{3}|[0-9]:[0-9]{2})$';
str = str.replaceAllMapped(
RegExp(regex), (match) => '${match.group(1)}0${match.group(2)}');
dateTime ??= DateTime.parse(str);
return DateTime.utc(
dateTime.year,
dateTime.month,
dateTime.day,
dateTime.hour,
dateTime.minute,
dateTime.second,
dateTime.millisecond,
);
}
static final yyyyRegExp = new RegExp(r'^\d{4}$');
static final yyyymmRegExp = new RegExp(r'^\d{4}-\d{2}$');
static final yyyymmddRegExp = new RegExp(r'^\d{4}-\d{2}-\d{2}$');
static DateTime? roundUpPartialDate(String str) {
if (yyyyRegExp.hasMatch(str)) {
return dateFromString('${str}-12-31');
}
if (yyyymmRegExp.hasMatch(str)) {
final dateTime = dateFromString('${str}-01');
return DateTime.utc(
dateTime.year,
dateTime.month + 1,
dateTime.day - 1,
dateTime.hour,
dateTime.minute,
dateTime.second,
dateTime.millisecond);
}
return null;
}
static DateTime plusTime(
String dateTimeLikeStr, int amount, CertLogicTimeUnit unit) {
final dateTime = roundUpPartialDate(dateTimeLikeStr) ?? dateFromString(dateTimeLikeStr);
switch (unit) {
case CertLogicTimeUnit.HOUR:
return DateTime.utc(
dateTime.year,
dateTime.month,
dateTime.day,
dateTime.hour + amount,
dateTime.minute,
dateTime.second,
dateTime.millisecond,
);
case CertLogicTimeUnit.DAY:
return DateTime.utc(
dateTime.year,
dateTime.month,
dateTime.day + amount,
dateTime.hour,
dateTime.minute,
dateTime.second,
dateTime.millisecond,
);
case CertLogicTimeUnit.MONTH:
return DateTime.utc(
dateTime.year,
dateTime.month + amount,
dateTime.day,
dateTime.hour,
dateTime.minute,
dateTime.second,
dateTime.millisecond,
);
case CertLogicTimeUnit.YEAR:
return DateTime.utc(
dateTime.year + amount,
dateTime.month,
dateTime.day,
dateTime.hour,
dateTime.minute,
dateTime.second,
dateTime.millisecond,
);
}
}
/// returns A Dart [DateTime] representing the given date that may be partial (YYYY[-MM[-DD]]).
/// See [the CertLogic specification](https://github.com/ehn-dcc-development/dgc-business-rules/blob/main/certlogic/specification/README.md) for details.
static DateTime dccDateOfBirth(String str) {
final forPartialDate = roundUpPartialDate(str);
if (forPartialDate != null) {
return forPartialDate;
}
if (yyyymmddRegExp.hasMatch(str)) {
return dateFromString(str);
}
throw CertLogicException(
'can\'t parse "${str}" as an EU DCC date-of-birth');
}
static const optionalPrefix = "URN:UVCI:";
/// returns The fragment with given index from the UVCI string
/// (see Annex 2 in the [UVCI specification](https://ec.europa.eu/health/sites/default/files/ehealth/docs/vaccination-proof_interoperability-guidelines_en.pdf)),
/// or `null` when that fragment doesn't exist.
static String? extractFromUVCI(String? uvci, int index) {
if (uvci == null || index < 0) {
return null;
}
final prefixlessUvci = uvci.startsWith(optionalPrefix)
? uvci.substring(optionalPrefix.length)
: uvci;
final fragments = prefixlessUvci.split(RegExp(r'[/#:]'));
return index < fragments.length ? fragments[index] : null;
}
static dynamic access(dynamic data, String path) {
if (path == '') return data;
var returnData = data;
path.split('.').forEach((fragment) {
if (returnData == null) return;
if (returnData is Iterable) {
try {
final index = int.parse(fragment);
if (index < 0 || index > (returnData as Iterable).length - 1) {
returnData = null;
return;
}
returnData = returnData[index];
return;
} catch (e) {
return;
}
}
if (returnData is Map) {
returnData = returnData[fragment];
return;
}
returnData = null;
});
return returnData;
}
}