Line data Source code
1 : import 'package:flutter/services.dart'; 2 : import 'package:folly_fields/validators/abstract_validator.dart'; 3 : 4 : /// 5 : /// 6 : /// 7 : class DurationValidator extends AbstractParserValidator<Duration> { 8 : final String yearSuffix; 9 : final String monthSuffix; 10 : final String daySuffix; 11 : final String hourSuffix; 12 : final String minuteSuffix; 13 : final String secondSuffix; 14 : final String millisecondSuffix; 15 : 16 : /// 17 : /// 18 : /// 19 1 : DurationValidator({ 20 : this.yearSuffix = 'y', 21 : this.monthSuffix = 'M', 22 : this.daySuffix = 'd', 23 : this.hourSuffix = 'h', 24 : this.minuteSuffix = 'm', 25 : this.secondSuffix = 's', 26 : this.millisecondSuffix = 'ms', 27 2 : }) : assert(yearSuffix.isNotEmpty, "yearSuffix can't be empty."), 28 2 : assert(monthSuffix.isNotEmpty, "monthSuffix can't be empty."), 29 2 : assert(daySuffix.isNotEmpty, "daySuffix can't be empty."), 30 2 : assert(hourSuffix.isNotEmpty, "hourSuffix can't be empty."), 31 2 : assert(minuteSuffix.isNotEmpty, "minuteSuffix can't be empty."), 32 2 : assert(secondSuffix.isNotEmpty, "secondsSuffix can't be empty."), 33 : assert( 34 2 : millisecondSuffix.isNotEmpty, 35 : "millisecondSuffix can't be empty.", 36 : ); 37 : 38 : /// 39 : /// 40 : /// 41 0 : @override 42 : String format(Duration duration) { 43 0 : int milliseconds = duration.inMilliseconds; 44 : int seconds = 0; 45 : int minutes = 0; 46 : int hours = 0; 47 : int days = 0; 48 : int months = 0; 49 : int years = 0; 50 : 51 : String ret = ''; 52 : 53 0 : if (milliseconds == 0) { 54 0 : return '0$millisecondSuffix'; 55 0 : } else if (milliseconds >= 1000) { 56 0 : seconds = (milliseconds / 1000).floor(); 57 0 : milliseconds = milliseconds % 1000; 58 : } 59 : 60 0 : if (seconds >= 60) { 61 0 : minutes = (seconds / 60).floor(); 62 0 : seconds = seconds % 60; 63 : } 64 : 65 0 : if (minutes >= 60) { 66 0 : hours = (minutes / 60).floor(); 67 0 : minutes = minutes % 60; 68 : } 69 : 70 0 : if (hours >= 24) { 71 0 : days = (hours / 24).floor(); 72 0 : hours = hours % 24; 73 : } 74 : 75 0 : if (days >= 30) { 76 0 : months = (days / 30).floor(); 77 0 : days = days % 30; 78 : } 79 : 80 0 : if (months >= 12) { 81 0 : years = (months / 12).floor(); 82 0 : months = months % 12; 83 : } 84 : 85 0 : if (milliseconds != 0) { 86 0 : ret = '$milliseconds$millisecondSuffix'; 87 : } 88 : 89 0 : if (seconds != 0) { 90 0 : ret = '$seconds$secondSuffix${ret.isEmpty ? '' : ' $ret'}'; 91 : } 92 : 93 0 : if (minutes != 0) { 94 0 : ret = '$minutes$minuteSuffix${ret.isEmpty ? '' : ' $ret'}'; 95 : } 96 : 97 0 : if (hours != 0) { 98 0 : ret = '$hours$hourSuffix${ret.isEmpty ? '' : ' $ret'}'; 99 : } 100 : 101 0 : if (days != 0) { 102 0 : ret = '$days$daySuffix${ret.isEmpty ? '' : ' $ret'}'; 103 : } 104 : 105 0 : if (months != 0) { 106 0 : ret = '$months$monthSuffix${ret.isEmpty ? '' : ' $ret'}'; 107 : } 108 : 109 0 : if (years != 0) { 110 0 : ret = '$years$yearSuffix${ret.isEmpty ? '' : ' $ret'}'; 111 : } 112 : 113 : return ret; 114 : } 115 : 116 : /// 117 : /// 118 : /// 119 0 : @override 120 : String strip(String value) => value; 121 : 122 : /// 123 : /// 124 : /// 125 0 : RegExp get regExp => RegExp( 126 : r'(\d+' 127 0 : '$yearSuffix)?' 128 : r'\s*(\d+' 129 0 : '$monthSuffix)?' 130 : r'\s*(\d+' 131 0 : '$daySuffix)?' 132 : r'\s*(\d+' 133 0 : '$hourSuffix)?' 134 : r'\s*(\d+' 135 0 : '$minuteSuffix)?' 136 : r'\s*(\d+' 137 0 : '$secondSuffix)?' 138 : r'\s*(\d+' 139 0 : '$millisecondSuffix)?', 140 : ); 141 : 142 : /// 143 : /// 144 : /// 145 0 : @override 146 : bool isValid(String value) { 147 0 : RegExpMatch? match = regExp.firstMatch(value.trim()); 148 : 149 0 : return match != null && match.group(0) == value.trim(); 150 : } 151 : 152 : /// 153 : /// 154 : /// 155 1 : @override 156 : TextInputType get keyboard => TextInputType.text; 157 : 158 : /// 159 : /// 160 : /// 161 0 : @override 162 : Duration? parse(String? value) { 163 0 : if (value == null || !isValid(value)) { 164 : return Duration.zero; 165 : } 166 : 167 0 : String input = value.split(' ').join(); 168 0 : RegExp onlyNumbers = RegExp(r'\d+'); 169 : 170 0 : RegExp yearRegex = RegExp(r'(\d)+' '$yearSuffix'); 171 0 : RegExp monthRegex = RegExp(r'(\d)+' '$monthSuffix'); 172 0 : RegExp dayRegex = RegExp(r'(\d)+' '$daySuffix'); 173 0 : RegExp hourRegex = RegExp(r'(\d)+' '$hourSuffix'); 174 0 : RegExp minuteRegex = RegExp(r'(\d)+' '$minuteSuffix'); 175 0 : RegExp secondRegex = RegExp(r'(\d)+' '$secondSuffix'); 176 0 : RegExp millisecondRegex = RegExp(r'(\d)+' '$millisecondSuffix'); 177 : 178 0 : String? yearsString = yearRegex.firstMatch(input)?.group(0) ?? ''; 179 0 : String? monthsString = monthRegex.firstMatch(input)?.group(0) ?? ''; 180 0 : String? daysString = dayRegex.firstMatch(input)?.group(0) ?? ''; 181 0 : String? hoursString = hourRegex.firstMatch(input)?.group(0) ?? ''; 182 0 : String? minutesString = minuteRegex.firstMatch(input)?.group(0) ?? ''; 183 0 : String? secondsString = secondRegex.firstMatch(input)?.group(0) ?? ''; 184 : String? millisecondsString = 185 0 : millisecondRegex.firstMatch(input)?.group(0) ?? ''; 186 : 187 : int? years = 188 0 : int.tryParse(onlyNumbers.firstMatch(yearsString)?.group(0) ?? ''); 189 : int? months = 190 0 : int.tryParse(onlyNumbers.firstMatch(monthsString)?.group(0) ?? ''); 191 : int? days = 192 0 : int.tryParse(onlyNumbers.firstMatch(daysString)?.group(0) ?? ''); 193 : int? hours = 194 0 : int.tryParse(onlyNumbers.firstMatch(hoursString)?.group(0) ?? ''); 195 : int? minutes = 196 0 : int.tryParse(onlyNumbers.firstMatch(minutesString)?.group(0) ?? ''); 197 : int? seconds = 198 0 : int.tryParse(onlyNumbers.firstMatch(secondsString)?.group(0) ?? ''); 199 0 : int? milliseconds = int.tryParse( 200 0 : onlyNumbers.firstMatch(millisecondsString)?.group(0) ?? '', 201 : ); 202 : 203 0 : days = (days ?? 0) + 30 * (months ?? 0) + 365 * (years ?? 0); 204 : 205 0 : return Duration( 206 : days: days, 207 : hours: hours ?? 0, 208 : minutes: minutes ?? 0, 209 : seconds: seconds ?? 0, 210 : milliseconds: milliseconds ?? 0, 211 : ); 212 : } 213 : 214 : /// 215 : /// 216 : /// 217 0 : @override 218 : String? valid(String value) => null; 219 : }