Advertisement
MKlegoman357

Argser.lua

Jun 20th, 2016
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.68 KB | None | 0 0
  1. -- written by MKlegoman357
  2.  
  3. local function argser (...)
  4.   local args = {...}
  5.  
  6.   if type(args[1]) == "table" then
  7.     args = args[1]
  8.   end
  9.  
  10.   local function tryConvert (val, typ)
  11.     if type(val) == typ then
  12.       return true, val
  13.     end
  14.  
  15.     if typ == "boolean" then
  16.       return true, val:lower():sub(1, 1) == "t"
  17.     elseif typ == "number" then
  18.       local n = tonumber(val)
  19.  
  20.       return not not n, n
  21.     elseif typ == "table" and type(val) == "string" then
  22.       local t = textutils.unserialize(val)
  23.  
  24.       if type(t) == "table" then
  25.         return true, t
  26.       end
  27.     end
  28.  
  29.     return false
  30.   end
  31.  
  32.   return {
  33.     rawArgs = args;
  34.     args = {};
  35.  
  36.     options = {};
  37.  
  38.     lastName = nil;
  39.  
  40.     num = function (self, i, name, valueType)
  41.       self.options[i] = {
  42.         type = "#";
  43.         name = name;
  44.  
  45.         i = i;
  46.  
  47.         valueType = valueType;
  48.       }
  49.  
  50.       if name then
  51.         self.options[name] = self.options[i]
  52.       end
  53.  
  54.       self.lastName = name or i;
  55.  
  56.       return self
  57.     end;
  58.  
  59.     switch = function (self, name, values, valueType)
  60.       self.options[name] = {
  61.         type = "-";
  62.         name = name;
  63.  
  64.         hasValue = not not values;
  65.         count = type(values) == "number" and values or values and math.huge or 0;
  66.  
  67.         valueType = valueType;
  68.       }
  69.  
  70.       self.lastName = name;
  71.  
  72.       return self
  73.     end;
  74.  
  75.     named = function (self, name, hasValue, valueType)
  76.       self.options[name] = {
  77.         type = "--";
  78.         name = name;
  79.  
  80.         hasValue = hasValue;
  81.  
  82.         valueType = valueType;
  83.       }
  84.  
  85.       self.lastName = name;
  86.  
  87.       return self
  88.     end;
  89.  
  90.     alias = function (self, name, alias)
  91.       if not alias then
  92.         name, alias = self.lastName, name
  93.       end
  94.  
  95.       self.options[alias] = self.options[name]
  96.  
  97.       return self
  98.     end;
  99.  
  100.     func = function (self, name, func)
  101.       if not func then
  102.         name, func = self.lastName, name
  103.       end
  104.  
  105.       local opt = self.options[name]
  106.  
  107.       if not opt then
  108.         error("Argument '" .. name .. "' does not exist.", 2)
  109.       end
  110.  
  111.       opt.func = func
  112.  
  113.       return self
  114.     end;
  115.  
  116.     default = function (self, name, default)
  117.       if default == nil then
  118.         name, default = self.lastName, name
  119.       end
  120.  
  121.       local opt = self.options[name]
  122.  
  123.       if opt and opt.func then
  124.         if opt.type == "-" then
  125.           for i, value in ipairs(default) do
  126.             default[i] = opt.func(value)
  127.           end
  128.         else
  129.           default = opt.func(default)
  130.         end
  131.       end
  132.  
  133.       self.args[name] = default
  134.  
  135.       if opt and opt.type == "#" then
  136.         self.args[type(name) == "number" and opt.name or opt.i] = default
  137.       end
  138.  
  139.       return self
  140.     end;
  141.  
  142.     parse = function (self)
  143.       local args = self.args
  144.       local options = self.options
  145.       local argn = 1
  146.       local switch = nil
  147.       local switchCount = 0
  148.  
  149.       for i, arg in ipairs(self.rawArgs) do
  150.         if arg:sub(1, 1) == "-" then
  151.           switch = nil
  152.  
  153.           if arg:sub(2, 2) == "-" then --named argument
  154.             local name, hasValue, value = arg:match("^%-%-([_a-zA-Z0-9]+)(=?)(.*)$")
  155.             local opt = options[name] and options[name].type == "--" and options[name]
  156.  
  157.             if hasValue == "" or opt and not opt.hasValue then
  158.               value = true
  159.             elseif opt and opt.hasValue and opt.valueType then
  160.               local success, val = tryConvert(value, opt.valueType)
  161.  
  162.               if not success then
  163.                 error("Argument '" .. opt.name .. "' must be a valid " .. opt.valueType .. ".", 0)
  164.               end
  165.  
  166.               value = val
  167.             end
  168.  
  169.             if opt and opt.func then
  170.               value = opt.func(value)
  171.             end
  172.  
  173.             args[opt and opt.name or name] = value
  174.           else -- switch
  175.             local name = arg:sub(2)
  176.             local opt = options[name] and options[name].type == "-" and options[name]
  177.             local value = opt and not opt.hasValue or not opt or {}
  178.  
  179.             if not args[opt and opt.name or name] then
  180.               args[opt and opt.name or name] = value
  181.             end
  182.  
  183.             if opt and opt.hasValue then
  184.               switch = opt
  185.               switchCount = opt.count
  186.             end
  187.           end
  188.         elseif switch then -- switch's argument
  189.           if switch.valueType then
  190.             local success, value = tryConvert(arg, switch.valueType)
  191.  
  192.             if not success then
  193.               error("Argument '" .. switch.name .. "' must be a valid " .. switch.valueType .. ".", 0)
  194.             end
  195.  
  196.             arg = value
  197.           end
  198.  
  199.           local params = args[switch.name]
  200.  
  201.           if switch.func then
  202.             arg = switch.func(arg)
  203.           end
  204.  
  205.           params[#params + 1] = arg
  206.  
  207.           switchCount = switchCount - 1
  208.  
  209.           if switchCount <= 0 then
  210.             switch = nil
  211.           end
  212.         else -- numbered argument
  213.           local opt = options[argn] and options[argn].type == "#" and options[argn]
  214.  
  215.           if opt and opt.valueType then
  216.             local success, value = tryConvert(arg, opt.valueType)
  217.  
  218.             if not success then
  219.               error("Argument #" .. argn .. (opt.name and " (" .. opt.name .. ")" or "") .. " must be a valid " .. opt.valueType .. ".", 0)
  220.             end
  221.  
  222.             arg = value
  223.           end
  224.  
  225.           if opt and opt.func then
  226.             arg = opt.func(arg)
  227.           end
  228.  
  229.           args[argn] = arg
  230.  
  231.           argn = argn + 1
  232.  
  233.           if opt and opt.name then
  234.             args[opt.name] = arg
  235.           end
  236.         end
  237.       end
  238.  
  239.       return self
  240.     end;
  241.   }
  242. end
  243.  
  244. return argser
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement