<commit_before>#if os(Linux)
import Glibc
#else
import Darwin
#endif

import Nest
import Commander
import Inquiline


extension ArgumentConvertible {
  init(string: String) throws {
    try self.init(parser: ArgumentParser(arguments: [string]))
  }
}


class MultiOption<T : ArgumentConvertible> : ArgumentDescriptor {
  typealias ValueType = [T]

  let name: String
  let flag: Character?
  let description: String?
  let `default`: ValueType
  var type: ArgumentType { return .option }

  init(_ name: String, _ default: ValueType, flag: Character? = nil, description: String? = nil) {
    self.name = name
    self.flag = flag
    self.description = description
    self.`default` = `default`
  }

  func parse(_ parser: ArgumentParser) throws -> ValueType {
    var options: ValueType = []

    while let value = try parser.shiftValueForOption(name) {
      let value = try T(string: value)
      options.append(value)
    }

    if let flag = flag {
      while let value = try parser.shiftValueForFlag(flag) {
        let value = try T(string: value)
        options.append(value)
      }
    }

    if options.isEmpty {
      return `default`
    }

    return options
  }
}


func getIntEnv(_ key: String, default: Int) -> Int {
  let value = getenv(key)
  if value != nil {
    if let stringValue = String(validatingUTF8: value!), let intValue = Int(stringValue) {
      return intValue
    }
  }

  return `default`
}


struct ServeError : Error, CustomStringConvertible {
  let description: String

  init(_ description: String) {
    self.description = description
  }
}


public func serve(_ closure: @escaping (RequestType) -> ResponseType) -> Never  {
  let port = UInt16(getIntEnv("PORT", default: 8000))
  let workers = getIntEnv("WEB_CONCURRENCY", default: 1)

  command(
    Option("worker-type", "sync"),
    Option("workers", workers, description: "The number of processes for handling requests."),
    MultiOption("bind", [Address.ip(hostname: "0.0.0.0", port: port)], description: "The address to bind sockets."),
    Option("timeout", 30, description: "Amount of seconds to wait on a worker without activity before killing and restarting the worker."),
    Flag("daemon", description: "Detaches the server from the controlling terminal and enter the background.")
  ) { workerType, workers, addresses, timeout, daemonize in
    var configuration = Configuration()
    configuration.addresses = addresses
    configuration.timeout = timeout

    if workerType == "synchronous" || workerType == "sync" {
      let arbiter = Arbiter<SynchronousWorker>(configuration: configuration, workers: workers, application: closure)
      try arbiter.run(daemonize: daemonize)
    } else if workerType == "dispatch" || workerType == "gcd" {
      let arbiter = Arbiter<DispatchWorker>(configuration: configuration, workers: workers, application: closure)
      try arbiter.run(daemonize: daemonize)<commit_msg>chore: Support to Commanders VariadicOption<commit_after>#if os(Linux)
import Glibc
#else
import Darwin
#endif

import Nest
import Commander
import Inquiline


func getIntEnv(_ key: String, default: Int) -> Int {
  let value = getenv(key)
  if value != nil {
    if let stringValue = String(validatingUTF8: value!), let intValue = Int(stringValue) {
      return intValue
    }
  }

  return `default`
}


struct ServeError : Error, CustomStringConvertible {
  let description: String

  init(_ description: String) {
    self.description = description
  }
}


public func serve(_ closure: @escaping (RequestType) -> ResponseType) -> Never  {
  let port = UInt16(getIntEnv("PORT", default: 8000))
  let workers = getIntEnv("WEB_CONCURRENCY", default: 1)

  command(
    Option("worker-type", "sync"),
    Option("workers", workers, description: "The number of processes for handling requests."),
    VariadicOption("bind", [Address.ip(hostname: "0.0.0.0", port: port)], description: "The address to bind sockets."),
    Option("timeout", 30, description: "Amount of seconds to wait on a worker without activity before killing and restarting the worker."),
    Flag("daemon", description: "Detaches the server from the controlling terminal and enter the background.")
  ) { workerType, workers, addresses, timeout, daemonize in
    var configuration = Configuration()
    configuration.addresses = addresses
    configuration.timeout = timeout

    if workerType == "synchronous" || workerType == "sync" {
      let arbiter = Arbiter<SynchronousWorker>(configuration: configuration, workers: workers, application: closure)
      try arbiter.run(daemonize: daemonize)
    } else if workerType == "dispatch" || workerType == "gcd" {
      let arbiter = Arbiter<DispatchWorker>(configuration: configuration, workers: workers, application: closure)
      try arbiter.run(daemonize: daemonize)
{'fraction_non_alphanumeric': 0.10817557728312877, 'fraction_numerical': 0.005824838776783857, 'mean_word_length': 3.992731048805815, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4098554', 'n_tokens_mistral': 1406, 'n_tokens_neox': 1342, 'n_words': 438}