lib/god_object/file_permissions/mode.rb
# encoding: UTF-8
=begin
Copyright GodObject Team <dev@godobject.net>, 2012-2016
This file is part of FilePermissions.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
=end
module GodObject
module FilePermissions
# Represents one component of the normal file mode in POSIX environments.
#
# The Mode is basically an immutable bit set consisting of the digits
# :read, :write and :execute.
class Mode
include BitSet
octal_mode = /(?<octal_mode>[0-7])/
digit_mode = /(?<digit_mode>(?:-|r|w|x){1,3})/
blank = /\p{Blank}*?/
# Regular expression for parsing a Mode from a String representation.
PATTERN = /^#{blank}(?:#{digit_mode}|#{octal_mode})#{blank}$/
# Configuration for the GodObject:::BitSet object which is used to handle
# the state internally.
BIT_SET_CONFIGURATION = Configuration.new(
read: 'r',
write: 'w',
execute: 'x'
)
extend Forwardable
include ModeMixin
include Comparable
class << self
# @!parse include ModeMixin::ClassMethods
# Creates a new Mode object by parsing a String representation.
#
# @param [String] string a String containing a mode
# @return [GodObject::FilePermissions::Mode] a new Mode object
def parse(string)
result = string.match(PATTERN)
case
when !result
raise ParserError, 'Invalid format'
when result[:octal_mode]
new(result[:octal_mode].to_i)
else
mode_components = []
result[:digit_mode].scan(/r|w|x/).each do |digit|
mode_components << :read if digit == 'r'
mode_components << :write if digit == 'w'
mode_components << :execute if digit == 'x'
end
if mode_components.uniq!
raise ParserError,
"Duplicate digit in: #{string.inspect}"
end
new(mode_components)
end
end
end
# Initializes a new Mode
#
# @return [void]
#
# @overload initialize(numeric)
# @param [Integer] numeric a numeric representation
#
# @overload initialize(enabled_digits)
# @param [Array<:read, :write, :execute>] enabled_digits a list of
# enabled digits
def initialize(*mode_components)
@bit_set = BIT_SET_CONFIGURATION.new(*mode_components)
end
# @!method enabled_digits
# @!attribute [r] enabled_digits
# @return [Set<:read, :write, :execute>] a list of all digits which are
# enabled
#
# @!method disabled_digits
# @!attribute [r] disabled_digits
# @return [Set<:read, :write, :execute>] a list of all digits which are
# disabled
#
# @!method state
# @!attribute [r] state
# @return [{(:read, :write, :execute) => true, false}] a table of all
# digits and their states
#
# @!parse alias attributes state
#
# @!method read?
# @!attribute [r] read?
# @return [true, false] the current state of the read digit
#
# @!parse alias read read?
#
# @!method write?
# @!attribute [r] write?
# @return [true, false] the current state of the write digit
#
# @!parse alias write write?
#
# @!method execute?
# @!attribute [r] execute?
# @return [true, false] the current state of the execute digit
#
# @!parse alias execute execute?
#
# @!method [](digit)
# @param [:read, :write, :execute, Integer] digit name or index of a
# digit
# @return [true, false] current state of the given digit
#
# @!method to_i
# Represents a Mode as a binary Integer.
# @return [Integer] an Integer representation
#
# @!method to_s(format)
# Represents a Mode as String.
# @param [:long, :short] format the String format
# @return [String] a String representation
#
# @!method hash
# @return (see Object#hash) identity hash for hash table usage
def_delegators :@bit_set,
:attributes, :state, :[], :enabled_digits, :disabled_digits,
:read?, :read, :write?, :write, :execute?, :execute,
:to_i, :to_s, :hash
end
end
end