state_step 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c02c4955910af627a8d6b175ba2f1f4cd464a20ddfe201efea1279552ef68ee2
4
+ data.tar.gz: f3d4d2b160258ba314f61bbdd2208a2d9a04fe1a958c200fb10466ed17e7ded1
5
+ SHA512:
6
+ metadata.gz: 3e799f54f69c8208649a0dd793b78ecef250f9d84a84b1ac38e1df6341ac4b8f4e781a695b1e775525921529af35d9db80abfdafad46e038a483a21aa5fcf5e1
7
+ data.tar.gz: 896b95e55acd3c7fd103dbe55fe1288080627f3f180a25512344d59f82d7efdd4d6e5f55ee5ea52ccf964422b91822f802c59d42f5cbe9637af31a9559b31d18
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # StateStep
2
+
3
+ TODO: Delete this and the text below, and describe your gem
4
+
5
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/state_step`. To experiment with that code, run `bin/console` for an interactive prompt.
6
+
7
+ ## Installation
8
+
9
+ TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10
+
11
+ Install the gem and add to the application's Gemfile by executing:
12
+
13
+ $ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
14
+
15
+ If bundler is not being used to manage dependencies, install the gem by executing:
16
+
17
+ $ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Development
24
+
25
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
26
+
27
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
28
+
29
+ ## Contributing
30
+
31
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/state_step.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
9
+ require 'release/gem'
@@ -0,0 +1,123 @@
1
+
2
+ require_relative 'state_trans'
3
+
4
+ module StateStep
5
+
6
+ class IncompleteStateSpec < StandardError; end
7
+ class ActionNotDefined < StandardError; end
8
+
9
+ class StateProfile
10
+ include TR::CondUtils
11
+
12
+ attr_reader :default_state, :state_attr
13
+
14
+ def parse_init(&block)
15
+ self.instance_eval(&block)
16
+ end
17
+
18
+ ## DSL
19
+ def default(st)
20
+ @default_state = st
21
+ end
22
+ alias_method :default_status, :default
23
+
24
+ def state_field(field)
25
+ @state_attr = field
26
+ end
27
+ alias_method :status_field, :state_field
28
+
29
+ def state(st, &block)
30
+ trans = st[:trans]
31
+ raise IncompleteStateSpec, "State transfer 'from' => 'to' state is not given" if is_empty?(trans)
32
+
33
+ from = trans.keys.first
34
+ to = trans.values.first
35
+ act = st[:action]
36
+
37
+ str = StateTrans.new(from, to, act, &block)
38
+
39
+ states[from] = {} if states[from].nil?
40
+ states[from][to] = str
41
+
42
+ next_states[from] = [] if next_states[from].nil?
43
+ next_states[from] << to
44
+
45
+ actions[act] = str
46
+
47
+ st
48
+ end
49
+
50
+ def trigger_action(act)
51
+ if actions.keys.include?(act)
52
+ actions[act].trigger
53
+
54
+ else
55
+ raise ActionNotDefined, "Active '#{act}' to trigger not defined"
56
+
57
+ end
58
+ end
59
+
60
+ ## DSL
61
+
62
+ def next_actions
63
+ if @next_actions.nil?
64
+ @next_actions = { }
65
+
66
+ states.each do |from, tos|
67
+ next_actions[from] = [] if next_actions[from].nil?
68
+
69
+ tos.each do |to, val|
70
+ next_actions[from] << val.action_name
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+
77
+ @next_actions
78
+ end
79
+
80
+ def defined_states
81
+
82
+ if @_allStates.nil?
83
+ @_allStates = []
84
+ states.each do |k,v|
85
+ @_allStates << k.to_s
86
+ v.each do |vk, vv|
87
+ @_allStates << vk.to_s
88
+ end
89
+ end
90
+ @_allStates = @_allStates.uniq
91
+ end
92
+ @_allStates
93
+ end
94
+
95
+
96
+ private
97
+ def states
98
+ if @states.nil?
99
+ @states = { }
100
+ end
101
+
102
+ @states
103
+ end
104
+
105
+ def actions
106
+ if @actions.nil?
107
+ @actions = { }
108
+ end
109
+
110
+ @actions
111
+ end
112
+
113
+ def next_states
114
+ if @next_states.nil?
115
+ @next_states = { }
116
+ end
117
+
118
+ @next_states
119
+ end
120
+
121
+
122
+ end
123
+ end
@@ -0,0 +1,28 @@
1
+
2
+
3
+
4
+ module StateStep
5
+ class StateTrans
6
+
7
+ attr_reader :stFrom, :stTo, :action_name
8
+ def initialize(from, to, name, &block)
9
+ @stFrom = from
10
+ @stTo = to
11
+ @action_name = name
12
+ @callback = block
13
+ end
14
+
15
+ def trigger
16
+ st = @callback.call
17
+ StateStep.logger.debug "st.nil? : #{st.nil?} / st = '#{st}'"
18
+ if st.nil? or st == true
19
+ StateStep.logger.debug "Status changed!"
20
+ @stTo
21
+ else
22
+ StateStep.logger.debug "Status reverted!"
23
+ @stFrom
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StateStep
4
+ VERSION = "0.1.1"
5
+ end
data/lib/state_step.rb ADDED
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'toolrack'
4
+ require 'teLogger'
5
+
6
+ require_relative "state_step/version"
7
+ require_relative "state_step/state_profile"
8
+
9
+ module StateStep
10
+ include TR::CondUtils
11
+
12
+ class Error < StandardError; end
13
+ # Your code goes here...
14
+
15
+ def self.logger(tag = nil, &block)
16
+ if @_logger.nil?
17
+ @_logger = TeLogger::Tlogger.new
18
+ end
19
+
20
+ if block
21
+ if not_empty?(tag)
22
+ @_logger.with_tag(tag, &block)
23
+ else
24
+ @_logger.with_tag(@_logger.tag, &block)
25
+ end
26
+ else
27
+ if is_empty?(tag)
28
+ @_logger.tag = :state_step
29
+ @_logger
30
+ else
31
+ # no block but tag is given? hmm
32
+ @_logger.tag = tag
33
+ @_logger
34
+ end
35
+ end
36
+
37
+ end # def logger
38
+
39
+
40
+ ## class methods
41
+ module ClassMethods
42
+
43
+ def status_init(&block)
44
+ profile.parse_init(&block)
45
+ end
46
+ alias_method :states_init, :status_init
47
+
48
+ def profile
49
+ if @profile.nil?
50
+ @profile = StateProfile.new
51
+ end
52
+ @profile
53
+ end
54
+
55
+ def defined_states
56
+ profile.defined_states
57
+ end
58
+ alias_method :defined_status, :defined_states
59
+ end
60
+ def self.included(klass)
61
+ klass.extend(ClassMethods)
62
+ end
63
+ ## End class methods
64
+
65
+ ##
66
+ # Instance methods
67
+ ##
68
+ def default_status
69
+ self.class.profile.default_state
70
+ end
71
+
72
+ def init_default_status
73
+ if status_field_exist?
74
+ self.send("#{state_field_name}=", default_status)
75
+ else
76
+ # raise here because the init is manual
77
+ # manual means user IS expecting some status changed
78
+ # Default here is not appropriate
79
+ StateStep.logger.debug "Status field '#{state_field_name}' does not exist on #{self}"
80
+ raise Error, "Status field '#{state_field_name}' does not exist on '#{self}'"
81
+ end
82
+ end
83
+
84
+ def is_current_status?(st)
85
+ if status_field_exist?
86
+ self.send("#{state_field_name}") == st.to_s
87
+ else
88
+ raise Error, "Status field name '#{state_field_name}' not defined"
89
+ end
90
+ end
91
+ alias_method :is_current_state?, :is_current_status?
92
+
93
+ def state_field_name
94
+ self.class.profile.state_attr
95
+ end
96
+
97
+ def state_trigger_action(action, raise_if_not_found = false)
98
+
99
+ if status_field_exist?
100
+ begin
101
+ nst = self.class.profile.trigger_action(action)
102
+ self.send("#{self.class.profile.state_attr}=", nst)
103
+ true
104
+ rescue ActionNotDefined => e
105
+ if raise_if_not_found == true
106
+ raise e
107
+ else
108
+ false
109
+ end
110
+ end
111
+
112
+ else
113
+
114
+ StateStep.logger.debug "Status field '#{state_field_name}' does not exist"
115
+
116
+ end
117
+
118
+ end
119
+
120
+ def next_actions
121
+ currAction = self.send("#{state_field_name}")
122
+ currAction = currAction.to_sym if not_empty?(currAction)
123
+
124
+ res = self.class.profile.next_actions[currAction] || []
125
+ res
126
+ end
127
+
128
+ private
129
+ def status_field_exist?
130
+ self.respond_to?(state_field_name) and self.respond_to?("#{state_field_name}=")
131
+ end
132
+
133
+ end
@@ -0,0 +1,4 @@
1
+ module StateStep
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: state_step
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-10-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: toolrack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: teLogger
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: release-gem
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: ''
56
+ email:
57
+ - chris@antrapol.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".rspec"
63
+ - README.md
64
+ - Rakefile
65
+ - lib/state_step.rb
66
+ - lib/state_step/state_profile.rb
67
+ - lib/state_step/state_trans.rb
68
+ - lib/state_step/version.rb
69
+ - sig/state_step.rbs
70
+ homepage: ''
71
+ licenses: []
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 2.6.0
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubygems_version: 3.4.6
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: ''
92
+ test_files: []