module FakeRedis::BitopCommand

def apply(operator, keys)

def apply(operator, keys)
  case operator
  when :~
    raise ArgumentError if keys.count != 1
    bitwise_not(keys.first)
  when :&, :|, :'^'
    raise ArgumentError if keys.empty?
    bitwise_operation(operator, keys)
  else
    raise ArgumentError
  end
end

def bitop(operation, destkey, *keys)

def bitop(operation, destkey, *keys)
  if result = apply(operator(operation), keys)
    set(destkey, result)
    result.length
  else
    0
  end
rescue ArgumentError => _
  raise_argument_error('bitop')
end

def bitwise_not(key)

def bitwise_not(key)
  if value = get(keys.first)
    value.bytes.map { |byte| ~ byte }.pack('c*')
  end
end

def bitwise_operation(operation, keys)

def bitwise_operation(operation, keys)
  apply_onto, *values = keys.map { |key| get(key) }.reject(&:nil?)
  values.reduce(apply_onto) do |memo, value|
    shorter, longer = [memo, value].sort_by(&:length).map(&:bytes).map(&:to_a)
    longer.each_with_index.map do |byte, index|
      byte.send(operation, shorter[index] || 0)
    end.pack('c*')
  end
end

def operator(operation)

def operator(operation)
  BIT_OPERATORS[operation.to_s.downcase]
end