这是indexloc提供的服务,不要输入任何密码
Skip to content

feat: [mason_logger] support validation for prompt, promptAny, and chooseAny #1550

@Luckey-Elijah

Description

@Luckey-Elijah

Description

Logger has some user inputs that accept arbitrary data. It can be useful to validate that user input "inline" with a given user input without having to re-prompt the user for an input.

Requirements

  • define Validator<T> typedef like Flutter's FormFieldValidator.
  • add optional Validator<String>? validator parameter to Logger.prompt
  • add optional Validator<List<String>>? validator parameter to Logger.promptAny
  • add optional Validator<List<T>>? validator parameter to Logger.chooseAny

Additional Context

Why these methods?

I think these are the only places a validation makes sense since data types are not very constrained compored to the other inputs.

  • chooseOne is already very limiting with select one (how would you validate "one" item?).
  • confirm's return value is it's "validation" by nature of booleans. "Inline" validation does seem to provide any additional information to the user.

How would this work?

Take this current validation flow for requiring a compatible dart package name.

void main(List<String> arguments) {
  final value = collectInput();
  print(value);
}

String? validate(String value) {
  if (value.contains(' ')) return 'Cannot contain spaces';
  if (value.contains('.')) return 'Cannot contain dots';
  if (value.contains('-')) return 'Cannot contain hyphen';
  // descriptive messages
  return null;
}

String collectInput() {
  Logger logger = Logger();
  String value;
  String? validation;
  do {
    var prompt = 'Dart package name';
    if (validation != null) {
      prompt = 'Dart package name ${red.wrap(validation)}';
    }
    value = logger.prompt(prompt, defaultValue: 'my_app');
    validation = validate(value);
  } while (validation != null);

  return value;
}

Could be reduced to this kind of flow by passing in the validator directly: validator: validate

void main(List<String> arguments) {
  final value = collectInput();
  print(value);
}

String? validate(String value) {
  if (value.contains(' ')) return 'Cannot contain spaces';
  if (value.contains('.')) return 'Cannot contain dots';
  if (value.contains('-')) return 'Cannot contain hyphen';
  return null;
}

String collectInput() {
  Logger logger = Logger();
  return logger.prompt(
    'Dart package name',
    defaultValue: 'my_app',
    validator: validate,
  );
}

How should it look?

I think an "inline" message can use the same style as Logger.theme.warn.

void main(List<String> arguments) {
  Logger logger = Logger();
  // simulate validation failing
  String? validation = logger.theme.warn('Cannot contain spaces');
  logger.prompt('Dart package name $validation', defaultValue: 'my_app');
}
Dart package name Cannot contain spaces (my_app) my app
Image

When should the validator function be executed?

If a validator is provided, the function executes when the user submits a value. When validator(value) returns null the value returns as normal to its consumer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions