mavickers / factor

0 stars 0 forks source link

Args Parser #1

Open mavickers opened 3 years ago

mavickers commented 3 years ago

Use case is for overloading methods.

Currently doing something like this often:

function(...args) {
    const var1 = args.filter(arg => arg instanceof SomeClass)[0];
    // etc
}

This allows for shoving any number and types of arguments to a method. It's up to the method to figure out which arguments get used in which fashion. It is handy for overloading a method but the parsing can be tedious.

How about an args parser function or pipeline?

function(...args) {
    let string1, num1, obj1, instance1, bool1, bool2;
    argsParser(args, [Number, String, Boolean, Class1, Object, Boolean], [num1, string1, bool1, instance1, obj1, bool2]);
}

Or maybe:

function(...args) {
  let string1 = String, 
      num1 = Number,
      obj1 = Object,
      instance1 = Class1,
      bool1 = Boolean,
      bool2 = Boolean;

  argsParser(args, [ num1, string1, bool1, instance1, obj1, bool2 ], [ num1, string1, obj1, bool1 ]);
}

The second way allows for different arg profiles to be sent, and the vars would be changed from types to actual values upon return from the parser.

mavickers commented 3 years ago

Ideas for interface.

const parser1 = ArgsParser
                .addProfile({ num1: { Number: true }, num2: { Number: true }, str1: { String: false }, bool1: { Boolean: false }, class1: { Class1: true } })
                .addProfile({ str1: { String: true }, class1: { Class1: true }})
                .throwOnInvalid("Arguments did not validate");

function test(...args) {
  const { num1, num2, str1, bool1, class1 } = parser1.parse(args).values;

  console.log(parser1.errors); // [ { num2: ArgsValidationFlag.Missing, class1: ArgsValidationFlag.TypeMismatch } ];
}
class Class1 { };
const instance1 = new Class1();
const instance2 = new Object();

const profile1 = { num1: { Number: true }, num2: { Number: true }, str1: { String: false }, bool1: { Boolean: false }, instance1: { Class1: true } };
const profile2 = { str1: { String: true }, instance1: { Class1: true }};

const parser1 = ArgsParser.addProfile("profile1", profile1).addProfile("profile2", profile2);
const parser2 = ArgsParser.addProfiles({ profile1: profile1, profile2: profile2 });

function test(...args) {
  // parse() returns { profile: << selected profile object >>, values: { }, errors: { profile1: { }, profile2: { } }
  const result = parser1.parse(args);
  const { num1, num2, str1, bool1, class1 } = result.values;
  const errors = result.errors;
  const profile = result.profile;

  console.log(parser1.errors); 
  console.log(parser1.profile);
}

test(1, "hello", instance1); // profile = profile2, errors = { profile1: [ num2 ] }
test(1, "hello", instance2); // profile = null, errors = { profile1: [ num2, class1 ], profile2: [ class1 ] }
test(1, "hello", instance1, 2); // profile = profile1, errors = null
mavickers commented 3 years ago