///|
fn Command::sadd(key : String, members : ArrayView[String]) -> Command[Int] {
  Command(
    ArgsBuilder(b"SADD")..push_string(key)..push_strings(members).build(),
    value => value.as_int(),
  )
}

///|
fn Command::srem(key : String, members : ArrayView[String]) -> Command[Int] {
  Command(
    ArgsBuilder(b"SREM")..push_string(key)..push_strings(members).build(),
    value => value.as_int(),
  )
}

///|
fn Command::smembers(key : String) -> Command[@hashset.HashSet[String]] {
  Command(ArgsBuilder(b"SMEMBERS")..push_string(key).build(), value => {
    value.as_set(value => value.as_string())
  })
}

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

///|
fn Command::smismember(
  key : String,
  members : ArrayView[String],
) -> Command[Array[Bool]] {
  Command(
    ArgsBuilder(b"SMISMEMBER")..push_string(key)..push_strings(members).build(),
    value => value.as_array(value => value.as_bool_int()),
  )
}

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

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

///|
fn Command::spop_count(
  key : String,
  count : Int,
) -> Command[@hashset.HashSet[String]] {
  Command(ArgsBuilder(b"SPOP")..push_string(key)..push_int(count).build(), value => {
    value.as_set(value => value.as_string())
  })
}

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

///|
fn Command::srandmember_count(
  key : String,
  count : Int,
) -> Command[Array[String]] {
  Command(
    ArgsBuilder(b"SRANDMEMBER")..push_string(key)..push_int(count).build(),
    value => value.as_array(value => value.as_string()),
  )
}

///|
fn Command::smove(
  source : String,
  destination : String,
  value : String,
) -> Command[Bool] {
  Command(
    ArgsBuilder(b"SMOVE")
    ..push_string(source)
    ..push_string(destination)
    ..push_string(value)
    .build(),
    value => value.as_bool_int(),
  )
}

///|
fn Command::sdiff(
  keys : ArrayView[String],
) -> Command[@hashset.HashSet[String]] {
  Command(ArgsBuilder(b"SDIFF")..push_strings(keys).build(), value => {
    value.as_set(value => value.as_string())
  })
}

///|
fn Command::sinter(
  keys : ArrayView[String],
) -> Command[@hashset.HashSet[String]] {
  Command(ArgsBuilder(b"SINTER")..push_strings(keys).build(), value => {
    value.as_set(value => value.as_string())
  })
}

///|
fn Command::sunion(
  keys : ArrayView[String],
) -> Command[@hashset.HashSet[String]] {
  Command(ArgsBuilder(b"SUNION")..push_strings(keys).build(), value => {
    value.as_set(value => value.as_string())
  })
}

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

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

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

///|
fn Command::sscan(
  key : String,
  cursor : String,
  pattern? : String,
  count? : Int,
) -> Command[(String, @hashset.HashSet[String])] {
  Command(
    ArgsBuilder(b"SSCAN")
    ..push_string(key)
    ..push_string(cursor)
    ..push_scan_options(pattern, count)
    .build(),
    value => value.as_scan_set(),
  )
}