google / googleapis.dart

Repository for building the googleapis packages
https://pub.dev/packages/googleapis
BSD 3-Clause "New" or "Revised" License
393 stars 119 forks source link

Document.fromMap() #92

Closed jimmyff closed 3 years ago

jimmyff commented 4 years ago

I've created a helped function that converts a Map<String, dynamic> to Map<String, Value>, I think this would be a good named constructor for Document, it could be called Document.fromMap(). Shall i send a PR?

This is inspired by DocumentData.fromMap() in firestore.dart

jimmyff commented 4 years ago

If anyone is needs this functionality, below is my code. I think this would be much nicer if this were properly integrated in to the Document class to give Document.fromMap() constructors etc.

class GoogleApisUtil {
  /// Converts a Map<String, Value> to Map<String, dynamic>
  static Map<String, dynamic> fieldsToJson(Map<String, Value> source) {
    return Map<String, dynamic>.fromIterables(
        source.keys, source.values.map((v) => _valueToVar(v)));
  }

  /// Converts a Map<String, dynamic> to Map<String, Value>
  static Map<String, Value> jsonToFields(Map<String, dynamic> source) {
    return Map<String, Value>.fromIterables(
        source.keys, source.values.map((v) => _varToValue(v)));
  }

  static Value _varToValue(dynamic value) {
    // TODO: Implement GeoPoint, Blob, DocumentReference, FieldValue
    if (value == null) {
      return Value()..nullValue = 'NULL_VALUE';
    } else if (value is String) {
      return Value()..stringValue = value;
    } else if (value is int) {
      return Value()..integerValue = value.toString();
    } else if (value is double) {
      return Value()..doubleValue = value;
    } else if (value is bool) {
      return Value()..booleanValue = value;
    } else if (value is DateTime) {
      return Value()
        ..timestampValue = value.toUtc().microsecondsSinceEpoch.toString();
    } else if (value is List) {
      return Value()
        ..arrayValue =
            (ArrayValue()..values = value.map((e) => _varToValue(e)).toList());
    } else if (value is Map) {
      return Value()
        ..mapValue = (MapValue()
          ..fields = Map.fromIterables(
              value.keys, value.values.map((e) => _varToValue(e))));
    } else {
      throw UnimplementedError();
    }
  }

  // TODO: Implement GeoPoint, Blob, DocumentReference, FieldValue
  static dynamic _valueToVar(Value value) {
    if (value.nullValue == 'NULL_VALUE') {
      return null;
    } else if (value.stringValue != null) {
      return value.stringValue;
    } else if (value.integerValue != null) {
      return int.parse(value.integerValue.toString());
    } else if (value.doubleValue != null) {
      return value.doubleValue;
    } else if (value.booleanValue != null) {
      return value.booleanValue;
    } else if (value.timestampValue != null) {
      return DateTime.fromMillisecondsSinceEpoch(
          int.parse(value.timestampValue.toString()));
    } else if (value.arrayValue != null) {
      return (value.arrayValue?.values ?? [])
          .map((v) => _valueToVar(v))
          .toList();
    } else if (value.mapValue != null) {
      return Map.fromIterables((value.mapValue?.fields ?? {}).keys,
          (value.mapValue?.fields ?? {}).values.map((v) => _valueToVar(v)));
    } else {
      throw UnimplementedError('Not implemented: ${value.toJson()}');
    }
  }
}
kevmoo commented 3 years ago

This is for firestore, right?

At the moment, we don't have the ability to augment generated code w/ user-defined code.

This would be a great add-on package, though!