///|
fn Command::del(keys : ArrayView[String]) -> Command[Int] {
  Command(ArgsBuilder(b"DEL")..push_strings(keys).build(), value => {
    value.as_int()
  })
}

///|
fn Command::exists(keys : ArrayView[String]) -> Command[Int] {
  Command(ArgsBuilder(b"EXISTS")..push_strings(keys).build(), value => {
    value.as_int()
  })
}

///|
fn Command::expire(key : String, seconds : Int) -> Command[Bool] {
  Command(ArgsBuilder(b"EXPIRE")..push_string(key)..push_int(seconds).build(), value => {
    value.as_bool_int()
  })
}

///|
fn Command::ttl(key : String) -> Command[Int] {
  Command(ArgsBuilder(b"TTL")..push_string(key).build(), value => value.as_int())
}

///|
fn Command::ping(message? : String) -> Command[String] {
  let args = ArgsBuilder(b"PING")
  if message is Some(message) {
    args.push_string(message)
  }
  Command(args.build(), value => value.as_string())
}

///|
fn Command::echo(message : String) -> Command[String] {
  Command(ArgsBuilder(b"ECHO")..push_string(message).build(), value => {
    value.as_string()
  })
}

///|
fn Command::pexpire(key : String, milliseconds : Int) -> Command[Bool] {
  Command(
    ArgsBuilder(b"PEXPIRE")..push_string(key)..push_int(milliseconds).build(),
    value => value.as_bool_int(),
  )
}

///|
fn Command::pttl(key : String) -> Command[Int] {
  Command(ArgsBuilder(b"PTTL")..push_string(key).build(), value => {
    value.as_int()
  })
}

///|
fn Command::persist(key : String) -> Command[Bool] {
  Command(ArgsBuilder(b"PERSIST")..push_string(key).build(), value => {
    value.as_bool_int()
  })
}

///|
fn Command::rename(key : String, new_key : String) -> Command[Unit] {
  Command(
    ArgsBuilder(b"RENAME")..push_string(key)..push_string(new_key).build(),
    value => value.expect_ok(),
  )
}

///|
fn Command::renamenx(key : String, new_key : String) -> Command[Bool] {
  Command(
    ArgsBuilder(b"RENAMENX")..push_string(key)..push_string(new_key).build(),
    value => value.as_bool_int(),
  )
}

///|
fn Command::type_(key : String) -> Command[String] {
  Command(ArgsBuilder(b"TYPE")..push_string(key).build(), value => {
    value.as_string()
  })
}

///|
fn Command::keys(pattern : String) -> Command[Array[String]] {
  Command(ArgsBuilder(b"KEYS")..push_string(pattern).build(), value => {
    value.as_array(value => value.as_string())
  })
}

///|
fn Command::scan(
  cursor : String,
  pattern? : String,
  count? : Int,
) -> Command[(String, Array[String])] {
  Command(
    ArgsBuilder(b"SCAN")
    ..push_string(cursor)
    ..push_scan_options(pattern, count)
    .build(),
    value => value.as_scan_strings(),
  )
}

///|
fn Command::randomkey() -> Command[String?] {
  Command(ArgsBuilder(b"RANDOMKEY").build(), value => {
    value.as_option(value => value.as_string())
  })
}