parse static method

dynamic parse(
  1. dynamic value
)

Implementation

static dynamic parse(dynamic value) {
  if (value is String) {
    final v = value.trim();
    // Null
    if (StringIs.isNull(v)) return null;

    // Integer
    if (StringIs.isNumber(v)) return int.parse(v);
    // Double
    if (StringIs.isDouble(v)) return double.parse(v);
    // Boolean
    if (StringIs.isBoolean(v)) return v.toLowerCase() == 'true';

    // DateTime (ISO 8601 or similar common formats, times optional)
    if (StringIs.isDate(v)) {
      try {
        return DateTime.parse(v);
      } catch (_) {}
    }

    // Try to parse from a single-quoted or "relaxed" JSON-like object: { k:v }
    if (StringIs.isMap(v)) {
      try {
        // Convert { key: value, ... } into JSON by quoting keys and string values as needed
        // This is a *very simple* approach and not robust for nested or complex objects
        String quoted = v;

        // Quote keys: find any key (possibly nested) not in quotes and add double quotes
        quoted = quoted.replaceAllMapped(
          RegExp(r'([,{]\s*)([A-Za-z0-9_]+)\s*:'),
          (m) => '${m[1]}"${m[2]}" :',
        );

        // Quote string values that look like words (not already quoted, not true/false/null, not numbers)
        quoted = quoted.replaceAllMapped(
          RegExp(r':\s*([A-Za-z_][A-Za-z0-9_\s]*)'), // not starting with quote
          (m) {
            final val = m[1]!.trim();
            // If value looks like number or bool or null, do not quote.
            if (StringIs.isNumber(val) || StringIs.isBoolean(val) || StringIs.isNull(val)) {
              return ': $val';
            }
            // If already quoted, leave it
            if (val.startsWith('"') || val.startsWith("'")) return ': $val';
            return ': "$val"';
          },
        );

        // Now parse with standard JSON decoder, then use parse on each value in the resulting Map
        final jsonObj = jsonDecode(quoted);

        // Recursively parse using Json.parse for each value
        dynamic convert(dynamic obj) {
          if (obj is Map) {
            return obj.map((key, value) => MapEntry(key, convert(value)));
          } else if (obj is List) {
            return obj.map(convert).toList();
          } else if (obj is String) {
            return Json.parse(obj); // use this very function to parse values
          } else {
            return obj;
          }
        }

        return convert(jsonObj);
      } catch (_) {
        // fallback below
      }
    }

    // If none matched, return original string
    return value;
  }

  return value;
}