Class: UnixLikePermissions::PermissionSeries

Inherits:
Object
  • Object
show all
Defined in:
lib/unix_like_permissions/permission_series.rb

Constant Summary collapse

PermissionSeriesError =
Class.new(StandardError)
PERMISSIONS_MAP =
{
  read: 1,
  create: 2,
  update: 4,
  destroy: 8
}.freeze
TRUE_ID =
true.object_id
FALSE_ID =
false.object_id
ALL_TRUE =
PERMISSIONS_MAP.values.sum
ALL_FALSE =
0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ PermissionSeries

Returns a new instance of PermissionSeries.



19
20
21
# File 'lib/unix_like_permissions/permission_series.rb', line 19

def initialize(value)
  @value = value
end

Instance Attribute Details

#valueObject (readonly)

Returns the value of attribute value.



17
18
19
# File 'lib/unix_like_permissions/permission_series.rb', line 17

def value
  @value
end

Class Method Details

.define_getters!Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/unix_like_permissions/permission_series.rb', line 47

def self.define_getters!
  if defined?(PERMISSIONS_MAP_WAS)
    PERMISSIONS_MAP_WAS.keys.each do |permission|
      remove_method "#{permission.to_s.gsub(/[^\w]/, '_')}?"
    end
  end

  PERMISSIONS_MAP.keys.each do |permission|
    define_method "#{permission.to_s.gsub(/[^\w]/, '_')}?" do
      peek(permission)
    end
  end
rescue StandardError => e
  raise PermissionSeriesError, e.message
end

Instance Method Details

#peek(permission) ⇒ Object

Raises:

  • (ArgumentError)


63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/unix_like_permissions/permission_series.rb', line 63

def peek(permission)
  raise ArgumentError, "Unknown permission #{permission}" unless PERMISSIONS_MAP.key?(permission)

  # binary values for each permission
  #
  # |1   | |2     | |4     | |8      |
  # |0001| |0010  | |0100  | |1000   |
  # |read| |create| |update| |destroy|
  #
  # when we do binary & (and) operation with 0101 and 0010 we get 0000 which is considered as CREATE is false and is decimal 0 (5 & 2 = 0)
  # when we do binary & (and) operation with 0101 and 0100 we get 0100 which is considered as UPDATE is true and is decimal 4 (5 & 4 = 4)
  (self.to_i & PERMISSIONS_MAP[permission]) > 0
end

#set(values) ⇒ Object

Raises:

  • (ArgumentError)


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/unix_like_permissions/permission_series.rb', line 23

def set(values)
  raise ArgumentError, "Unknown permission #{values.keys - PERMISSIONS_MAP.keys}" unless values.keys.all? { |permission| PERMISSIONS_MAP.key?(permission) }
  raise ArgumentError, "Value must be boolean" unless values.values.all? { |value| value.object_id == FALSE_ID || value.object_id == TRUE_ID }

  # binary values for each permission
  #
  # |1   | |2     | |4     | |8      |
  # |0001| |0010  | |0100  | |1000   |
  # |read| |create| |update| |destroy|
  #
  # when we do binary | (or) operation with 0001 and 0100 we get 0101 which is considered as set CREATE to true and is decimal 5 (1 | 4 = 5)
  # when we do binary & (and) operation with 0101 and 1011(reverted: '~', 0100) we get 0001 which is considered as set CREATE to false and is decimal 1 (5 & ~4 = 1)
  values.each do |permission, value|
    if value
      @value = self.to_i | PERMISSIONS_MAP[permission]
    else
      @value = self.to_i & ~PERMISSIONS_MAP[permission]
    end
  end

  @stringified_permissions = nil
  @value
end

#set_all(value) ⇒ Object



77
78
79
80
81
# File 'lib/unix_like_permissions/permission_series.rb', line 77

def set_all(value)
  @value = value ? ALL_TRUE : ALL_FALSE
  @stringified_permissions = nil
  @value
end

#to_a(type = :str) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/unix_like_permissions/permission_series.rb', line 87

def to_a(type = :str)
  case type
  when :str
    stringified_permissions.chars
  when :int
    stringified_permissions.chars.map(&:to_i)
  when :bool
    stringified_permissions.chars.map { |action| action == '1' }
  else
    raise ArgumentError, "Unknown type #{type}"
  end
end

#to_h(type = :bool) ⇒ Object



100
101
102
# File 'lib/unix_like_permissions/permission_series.rb', line 100

def to_h(type = :bool)
  PERMISSIONS_MAP.keys.zip(self.to_a(type)).to_h
end

#to_iObject



83
84
85
# File 'lib/unix_like_permissions/permission_series.rb', line 83

def to_i
  @value.to_i
end

#to_sObject



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/unix_like_permissions/permission_series.rb', line 104

def to_s
  result = ''

  stringified_permissions.each_char.with_index do |action, i|
    if action == '1'
      result << ' ' unless i.zero?
      permissions = PERMISSIONS_MAP.keys
      result << permissions[i].to_s
    end
  end

  result
end