110 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
# A serializer for boolean values being stored in Redis.
 | 
						|
#
 | 
						|
# This is to ensure that booleans are stored in a consistent and
 | 
						|
# testable way when being stored as strings in Redis.
 | 
						|
#
 | 
						|
# Examples:
 | 
						|
#
 | 
						|
#     bool = Gitlab::Redis::Boolean.new(true)
 | 
						|
#     bool.to_s == "_b:1"
 | 
						|
#
 | 
						|
#     Gitlab::Redis::Boolean.encode(true)
 | 
						|
#     => "_b:1"
 | 
						|
#
 | 
						|
#     Gitlab::Redis::Boolean.decode("_b:1")
 | 
						|
#     => true
 | 
						|
#
 | 
						|
#     Gitlab::Redis::Boolean.true?("_b:1")
 | 
						|
#     => true
 | 
						|
#
 | 
						|
#     Gitlab::Redis::Boolean.true?("_b:0")
 | 
						|
#     => false
 | 
						|
 | 
						|
module Gitlab
 | 
						|
  module Redis
 | 
						|
    class Boolean
 | 
						|
      LABEL = "_b"
 | 
						|
      DELIMITER = ":"
 | 
						|
      TRUE_STR = "1"
 | 
						|
      FALSE_STR = "0"
 | 
						|
 | 
						|
      BooleanError = Class.new(StandardError)
 | 
						|
      NotABooleanError = Class.new(BooleanError)
 | 
						|
      NotAnEncodedBooleanStringError = Class.new(BooleanError)
 | 
						|
 | 
						|
      def initialize(value)
 | 
						|
        @value = value
 | 
						|
      end
 | 
						|
 | 
						|
      # @return [String] the encoded boolean
 | 
						|
      def to_s
 | 
						|
        self.class.encode(@value)
 | 
						|
      end
 | 
						|
 | 
						|
      class << self
 | 
						|
        # Turn a boolean into a string for storage in Redis
 | 
						|
        #
 | 
						|
        # @param value [Boolean] true or false
 | 
						|
        # @return [String] the encoded boolean
 | 
						|
        # @raise [NotABooleanError] if the value isn't true or false
 | 
						|
        def encode(value)
 | 
						|
          raise NotABooleanError, value unless bool?(value)
 | 
						|
 | 
						|
          [LABEL, to_string(value)].join(DELIMITER)
 | 
						|
        end
 | 
						|
 | 
						|
        # Decode a boolean string
 | 
						|
        #
 | 
						|
        # @param value [String] the stored boolean string
 | 
						|
        # @return [Boolean] true or false
 | 
						|
        # @raise [NotAnEncodedBooleanStringError] if the provided value isn't an encoded boolean
 | 
						|
        def decode(value)
 | 
						|
          raise NotAnEncodedBooleanStringError, value.class unless value.is_a?(String)
 | 
						|
 | 
						|
          label, bool_str = *value.split(DELIMITER, 2)
 | 
						|
 | 
						|
          raise NotAnEncodedBooleanStringError, label unless label == LABEL
 | 
						|
 | 
						|
          from_string(bool_str)
 | 
						|
        end
 | 
						|
 | 
						|
        # Decode a boolean string, then test if it's true
 | 
						|
        #
 | 
						|
        # @param value [String] the stored boolean string
 | 
						|
        # @return [Boolean] is the value true?
 | 
						|
        # @raise [NotAnEncodedBooleanStringError] if the provided value isn't an encoded boolean
 | 
						|
        def true?(encoded_value)
 | 
						|
          decode(encoded_value)
 | 
						|
        end
 | 
						|
 | 
						|
        # Decode a boolean string, then test if it's false
 | 
						|
        #
 | 
						|
        # @param value [String] the stored boolean string
 | 
						|
        # @return [Boolean] is the value false?
 | 
						|
        # @raise [NotAnEncodedBooleanStringError] if the provided value isn't an encoded boolean
 | 
						|
        def false?(encoded_value)
 | 
						|
          !true?(encoded_value)
 | 
						|
        end
 | 
						|
 | 
						|
        private
 | 
						|
 | 
						|
        def bool?(value)
 | 
						|
          [true, false].include?(value)
 | 
						|
        end
 | 
						|
 | 
						|
        def to_string(bool)
 | 
						|
          bool ? TRUE_STR : FALSE_STR
 | 
						|
        end
 | 
						|
 | 
						|
        def from_string(str)
 | 
						|
          raise NotAnEncodedBooleanStringError, str unless [TRUE_STR, FALSE_STR].include?(str)
 | 
						|
 | 
						|
          str == TRUE_STR
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |