~singpolyma/sgx-jmp

ref: 8dd92b96258d14d431e9966d0534631c7fdc0214 sgx-jmp/lib/admin_action.rb -rw-r--r-- 2.1 KiB
8dd92b96Stephen Paul Weber Merge branch 'admin-actions' 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# frozen_string_literal: true

require "delegate"

class AdminAction
	class NoOp
		def to_s
			"NoOp"
		end
	end

	module Direction
		class InvalidDirection < StandardError; end

		def self.for(direction)
			{
				forward: Forward,
				reverse: Reverse,
				reforward: Reforward
			}.fetch(direction.to_sym) { raise InvalidDirection }
		end

		class Forward < SimpleDelegator
			def with(**kwargs)
				self.class.new(__getobj__.with(**kwargs))
			end

			def perform
				check_forward.then { forward }.then { |x| self.class.new(x) }
			end

			def to_h
				super.merge(direction: :forward)
			end

			def undo
				Reverse.new(__getobj__.with(parent_id: id))
			end
		end

		class Reverse < SimpleDelegator
			def with(**kwargs)
				self.class.new(__getobj__.with(**kwargs))
			end

			def perform
				check_reverse.then { reverse }.then { |x| self.class.new(x) }
			end

			def to_s
				"UNDO(#{parent_id}) #{super}"
			end

			def to_h
				super.merge(direction: :reverse)
			end

			def undo
				Reforward.new(__getobj__)
			end
		end

		class Reforward < Forward
			def with(**kwargs)
				self.class.new(__getobj__.with(**kwargs))
			end

			def to_s
				"REDO(#{parent_id}) #{super}"
			end

			def to_h
				super.merge(direction: :reforward)
			end

			def undo
				Reverse.new(__getobj__)
			end
		end
	end

	def self.for(**kwargs)
		Direction::Forward.new(new(**kwargs))
	end

	def initialize(**kwargs)
		@attributes = kwargs
	end

	def with(**kwargs)
		self.class.new(@attributes.merge(kwargs))
	end

	def id
		@attributes[:id]
	end

	def parent_id
		@attributes[:parent_id]
	end

	def actor_id
		@attributes[:actor_id]
	end

	def check_forward
		EMPromise.resolve(nil)
	end

	def forward
		EMPromise.resolve(self)
	end

	def check_reverse
		EMPromise.resolve(nil)
	end

	def reverse
		EMPromise.resolve(self)
	end

	def to_h
		@attributes.merge({
			class: self.class.to_s.delete_prefix("AdminAction::")
		}.compact)
	end

	module Isomorphic
		def check_reverse
			to_reverse.check_forward
		end

		def reverse
			# We don't want it to return the reversed one
			# We want it to return itself but with the reverse state
			to_reverse.forward.then { self }
		end
	end
end