changeTo<R> function

R changeTo<R>(
  1. dynamic value, [
  2. String? locale
])

Try change a value of any type into a value of type R.

  • If the value is null, returns null if R is nullable otherwise throws an exception.
  • If value is R returns the value as is.
  • If R is DateTime, converts the value to a DateTime using the toDate() method.
  • If R is num, parses the value as a num using the num.parse() method.
  • If R is int, parses the value as an int using the int.parse() method.
  • If R is double, parses the value as a double using the double.parse() method.
  • If R is String, returns the value as a String using jsonEncode().
  • If R is bool, converts the value to a bool using the asBool() method.
  • If R is Widget, converts the value to a Widget using the forceWidget() method.
  • If R is Text, converts the value to a Text using the asText() method.
  • If R is List, converts the value to a List containing the value.
  • if R is another type, try returns the value as R.
  • If none of the above conditions are met, throws an exception.

if locale is provided, it is used to format and parse numbers and dates.

Implementation

R changeTo<R>(dynamic value, [String? locale]) {
  locale = locale?.nullIfBlank;
  if (value is R) return value;
  if (value != null) {
    // consoleLog("Changing $value from ${value.runtimeType} to $R");
    NumberFormat? nf = locale == null ? null : NumberFormat(null, locale);
    if (isSameType<R, DateTime>()) {
      if (value is num) return DateTime.fromMillisecondsSinceEpoch(value.round()) as R;
      if (locale == null) return date.parse("$value") as R;
      return "$value".toDate(null, locale) as R;
    } else if (isSameType<R, int>()) {
      if (value is DateTime) {
        return changeTo(value.millisecondsSinceEpoch, locale);
      } else if (value is num) {
        return value.toInt() as R;
      } else {
        return int.parse("$value".ifBlank("0").onlyNumbers) as R;
      }
    } else if (isSameType<R, double>()) {
      if (value is DateTime) {
        return changeTo(value.millisecondsSinceEpoch, locale);
      } else if (value is num) {
        return value.toDouble() as R;
      } else {
        return (nf?.tryParse(changeTo(value, locale))?.toDouble() ?? double.parse(changeTo<string>(value, locale).ifBlank("0").removeLetters)) as R;
      }
    } else if (isSameType<R, num>()) {
      if (value is DateTime) {
        return changeTo(value.millisecondsSinceEpoch, locale);
      } else {
        return (nf?.tryParse(changeTo(value, locale)) ?? num.parse(changeTo<string>(value, locale).ifBlank("0").removeLetters)) as R;
      }
    } else if (isSameType<R, Color>()) {
      if (value is num) {
        return Color(value.round()) as R;
      }
      if (value is NamedColor) {
        return value as R;
      }
      return changeTo<string>(value).asColor as R;
    } else if (isSameType<R, String>()) {
      if (value is DateTime) {
        return value.format() as R;
      } else if (value is Duration) {
        return value.formatted as R;
      } else if (value is num) {
        return (nf?.format(value) ?? "$value") as R;
      } else if (value is Color) {
        return value.hexadecimal as R;
      } else if (value is Uri) {
        return value.toString() as R;
      } else if (value is Widget) {
        return value.text as R;
      } else if (value is List) {
        return jsonEncode(value) as R;
      } else if (value is Map) {
        return jsonEncode(value) as R;
      } else {
        return "$value" as R;
      }
    } else if (isSameType<R, bool>()) {
      return "$value".asBool() as R;
    } else if (isSameType<R, Uri>()) {
      return Uri.parse("$value") as R;
    } else if (isSameType<R, Widget>()) {
      return forceWidget(value) as R;
    } else if (isSameType<R, Text>()) {
      return (value as Object?).asNullableText() as R;
    } else if (isSameType<R, List>()) {
      return forceList(value) as R;
    }
  } else {
    if (isNullable<R>()) {
      return null as R;
    } else if (isSameType<R, string>()) {
      return "" as R;
    } else if (isSameType<R, bool>()) {
      return false as R;
    } else if (isSameType<R, int>()) {
      return 0 as R;
    } else if (isSameType<R, num>()) {
      return 0.0 as R;
    } else if (isSameType<R, double>()) {
      return 0.0 as R;
    } else if (isSameType<R, DateTime>()) {
      return minDate as R;
    } else if (isSameType<R, List>()) {
      return [] as R;
    } else if (isSameType<R, Text>()) {
      return const Text("") as R;
    } else if (isSameType<R, Widget>()) {
      return nil as R;
    } else if (isSameType<R, Color>()) {
      return Colors.transparent as R;
    } else if (isSameType<R, Uri>()) {
      return Uri.parse("http://localhost:80") as R;
    }
  }
  throw Exception("Incompatible conversion");
}