freezed icon indicating copy to clipboard operation
freezed copied to clipboard

Custom factory methods in union classes

Open hacker1024 opened this issue 2 years ago • 1 comments

Is your feature request related to a problem? Please describe. Consider the following structure for HTTP request information. The request body can potentially be binary data, and is stored as such. For convenience, a text extension getter is defined.

The problem, however, is that there's no way to construct a CompleteRequest object by using a text string in the constructor - it only takes the binary form.

@freezed
class Request with _$Request {
  const factory Request.summary({
    required String method,
    required Uri url,
  }) = RequestSummary;

  const factory Request.complete({
    required String method,
    required Uri url,
    required Map<String, List<String>> headers,
    required Uint8List body,
  }) = CompleteRequest;
}

extension RequestBodyExtension on CompleteRequest {
  String? get text {
    try {
      return utf8.decode(body);
    } on FormatException {
      return null;
    }
  }
}

Describe the solution you'd like It would be great if there was a way to add custom factory methods to union classes. Maybe with an API like so:

@freezed
class Request with _$Request {
  const factory Request.complete({
    required String method,
    required Uri url,
    required Map<String, List<String>> headers,
    required Uint8List body,
  }) = CompleteRequest;

  const factory Request.completeWithText({
    required String method,
    required Uri url,
    required Map<String, List<String>> headers,
    required String text,
  }) = CompleteRequest.completeWithText

  @Factory("completeWithText")
  static CompleteRequest _withText({
    required String method,
    required Uri url,
    required Map<String, List<String>> headers,
    required String text,
  }) =>
      CompleteRequest(
        method: method,
        url: url,
        headers: headers,
        body: utf8.encoder.convert(text),
      );
}

Describe alternatives you've considered A regular static or factory method can be made in the class declaration, but this is messy as a constructor won't be generated in the union class.

Additional context

hacker1024 avatar May 28 '22 02:05 hacker1024

Hello! Sorry for the delay

Why not make a normal factory?

factory Request._withText({
    required String method,
    required Uri url,
    required Map<String, List<String>> headers,
    required String text,
}) {
  return CompleteRequest(
        method: method,
        url: url,
        headers: headers,
        body: utf8.encoder.convert(text),
      );
}

rrousselGit avatar Jul 06 '22 14:07 rrousselGit

Closing as this isn't planned.

rrousselGit avatar Sep 27 '22 14:09 rrousselGit