kxi 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ # Created by Matyáš Pokorný on 2017-12-29.
2
+
3
+ module KXI
4
+ module Collections
5
+ # Makes hash enumerable.
6
+ # Every key-value pair of hash is represented by {KXI::Collections::HashCollection::HashEnumerator::KeyValuePair} class
7
+ class HashCollection < KXI::Collections::Enumerable
8
+ # Instantiates the {KXI::Collections::HashCollection} class
9
+ # @param hash [Hash] Hash for enumeration
10
+ def initialize(hash)
11
+ super()
12
+ @hash = hash
13
+ end
14
+
15
+ # Creates a new {KXI::Collections::Enumerator} bound to this instance
16
+ # @return [KXI::Collections::Enumerator] Enumerator bound to this instance
17
+ def create_enumerator
18
+ HashEnumerator.new(@hash)
19
+ end
20
+
21
+ # Gets value from hash at given key
22
+ # @param key [Object] Key of value to obtain
23
+ # @return [Object] Obtained value
24
+ def [](key)
25
+ lock do
26
+ return @hash[key]
27
+ end
28
+ end
29
+
30
+ # Sets value to hash at given key
31
+ # @param key [Object] Key of pair to set
32
+ # @param value [Object] Value to set the pair to
33
+ # @return [Object] Given value
34
+ def []=(key, value)
35
+ lock(true) do
36
+ @hash[key] = value
37
+ end
38
+ return value
39
+ end
40
+
41
+ # Enumerates hash as key-value pairs represented by the {KXI::Collections::HashCollection::HashEnumerator::KeyValuePair} class
42
+ class HashEnumerator < KXI::Collections::Enumerator
43
+ # Instantiates the {KXI::Collections::HashCollection::HashEnumerator} class
44
+ # @param hash [Hash] Hash for enumeration
45
+ def initialize(hash)
46
+ @hash = hash
47
+ @keys = hash.keys
48
+ @current = 0
49
+ end
50
+
51
+ # Selects first item in collection
52
+ # @return [Bool] True if collection contains elements; otherwise false
53
+ def rewind
54
+ @current = 0
55
+ return @keys.length > 0
56
+ end
57
+
58
+ # Advances enumerator to next item
59
+ # @return [Bool] True if item is available; false otherwise
60
+ # @raise [KXI::Exceptions::AbstractException] When method is not implemented in superclass
61
+ def next
62
+ @current += 1
63
+ return @keys.length > @current
64
+ end
65
+
66
+ # Returns current item
67
+ # @return [Object] Current item
68
+ # @raise [KXI::Exceptions::AbstractException] When method is not implemented in superclass
69
+ def current
70
+ k = @keys[@current]
71
+ KeyValuePair.new(k, @hash[k])
72
+ end
73
+
74
+ # Represents a key-value pair
75
+ class KeyValuePair
76
+ # Returns the key of pair
77
+ # @return [Object] Key of pair
78
+ def key
79
+ @key
80
+ end
81
+
82
+ # Returns the value of pair
83
+ # @return [Object] Value of pair
84
+ def value
85
+ @val
86
+ end
87
+
88
+ # Instantiates the {KXI::Collections::HashCollection::HashEnumerator::KeyValuePair} class
89
+ # @param k [Object] Key of pair
90
+ # @param v [Object] Value of pair
91
+ def initialize(k, v)
92
+ @key = k
93
+ @val = v
94
+ end
95
+ end
96
+ end
97
+
98
+ protected :create_enumerator
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,20 @@
1
+ # Created by Matyáš Pokorný on 2018-01-20.
2
+
3
+ module KXI
4
+ module Collections
5
+ class ProtectedCollection < KXI::Collections::Enumerable
6
+ # Instantiates the {KXI::Collections::ArrayCollection} class
7
+ # @param enum [KXI::Collections::Enumerable] Protected enumerable
8
+ def initialize(enum = [])
9
+ super()
10
+ @enum = enum
11
+ end
12
+
13
+ # Creates a new {KXI::Collections::Enumerator} bound to this instance
14
+ # @return [KXI::Collections::Enumerator] Enumerator bound to this instance
15
+ def create_enumerator
16
+ @enum.create_enumerator
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ # Created by Matyáš Pokorný on 2017-12-28.
2
+ module KXI
3
+ module Exceptions
4
+ # Raised when method that was supposed to be implemented by super class wasn't
5
+ class AbstractException < Exception
6
+ # Returns the abstract class
7
+ # @return [Class] Abstract class
8
+ def class
9
+ @class
10
+ end
11
+
12
+ # Returns the file that contains the abstract class
13
+ # @return [String] Path of file that contains the abstract class
14
+ def file
15
+ @file
16
+ end
17
+
18
+ # Returns name of the abstract method
19
+ # @return [String] Name of the abstract method
20
+ def method
21
+ @mtd
22
+ end
23
+
24
+ # Instantiates the {KXI::Exceptions::AbstractException} class
25
+ # @param cl [Class] Abstract class
26
+ def initialize(cl)
27
+ frame = Reflection::StackFrame.callstack(3).first
28
+ @file = frame.file
29
+ @mtd = frame.method
30
+ super("Abstract method #{cl.name}##{@mtd} wasn't implemented!")
31
+ @class = cl
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ # Created by Matyáš Pokorný on 2018-01-20.
2
+
3
+ module KXI
4
+ module Exceptions
5
+ # Raised when command-line parser encounters an error
6
+ class ArgumentException < Exception
7
+ # Get the name of argument
8
+ # @return [String] Name of argument
9
+ def argument
10
+ @arg
11
+ end
12
+
13
+ # Instantiates the {KXI::Exceptions::ArgumentException} class
14
+ # @param arg [String] Name of argument
15
+ # @param msg [String] Error message
16
+ def initialize(arg, msg)
17
+ super("<#{arg}> #{msg}")
18
+ @arg = arg
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ # Created by Matyáš Pokorný on 2017-12-28.
2
+
3
+ module KXI
4
+ module Exceptions
5
+ # Raised when collection encounters an error
6
+ class CollectionException < Exception
7
+ # Instantiates the {KXI::Exceptions::CollectionException} class
8
+ # @param msg [String] Exception message
9
+ def initialize(msg)
10
+ super(msg)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ # Created by Matyáš Pokorný on 2017-12-30.
2
+
3
+ module KXI
4
+ module Exceptions
5
+ # Raised when some value is of unexpected type
6
+ class InvalidTypeException < Exception
7
+ # Returns expected types
8
+ # @return [Array<Class>] Expected types
9
+ def expected
10
+ @exp
11
+ end
12
+
13
+ # Returns actual type
14
+ # @return [Class] Actual type
15
+ def actual
16
+ @act
17
+ end
18
+
19
+ # Instantiates the [KXI::Exceptions::InvalidTypeException] class
20
+ # @param exp [Array<Class>] Expected types
21
+ # @param act [Class] Actual type
22
+ def initialize(act, *exp)
23
+ if exp.length == 1
24
+ super("Value is of unexpected type! Expected <#{exp[0].name}> got <#{act.name}>")
25
+ else
26
+ super("Value is of unexpected type! Expected { #{exp.collect {|i| "<#{i}>"}.join(', ')} } got <#{act.name}>")
27
+ end
28
+ @exp = exp
29
+ @act = act
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ # Created by Matyáš Pokorný on 2018-01-21.
2
+
3
+ module KXI
4
+ module Exceptions
5
+ # Raised when argument value has no binding argument
6
+ class NoArgumentException < Exception
7
+ # Gets the erroneous value
8
+ # @return [String] Erroneous value
9
+ def value
10
+ @val
11
+ end
12
+
13
+ # Instantiates the {KXI::Exceptions::NoArgumentException} class
14
+ # @param val [String] Erroneous value
15
+ def initialize(val)
16
+ super("Value '#{val}' has no argument to bind to!")
17
+ @val = val
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ # Created by Matyáš Pokorný on 2017-12-29.
2
+
3
+ module KXI
4
+ module Exceptions
5
+ # Raised when given part of code isn't yet implemented
6
+ class NotImplementedException < Exception
7
+ # Instantiates the {KXI::Exceptions::NotImplementedException} class
8
+ def initialize
9
+ super('Code not implemented yet!')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ # Created by Matyáš Pokorný on 2017-12-29.
2
+
3
+ module KXI
4
+ module Exceptions
5
+ # Raised when certain value is out of range
6
+ class OutOfRangeException < Exception
7
+ # Returns erroneous value
8
+ # @return [Object] Erroneous value
9
+ def value
10
+ @val
11
+ end
12
+
13
+ # Returns minimal expected value
14
+ # @return [Object, nil] Minimal expected value; nil if there is no minimum
15
+ def minimum
16
+ @min
17
+ end
18
+
19
+ # Returns maximal expected value
20
+ # @return [Object, nil] Maximal expected value; nil if there is no maximum
21
+ def maximum
22
+ @max
23
+ end
24
+
25
+ # Instantiates the {KXI::Exceptions::OutOfRangeException} class
26
+ # @param val [Object] Erroneous value
27
+ # @param min [Object, nil] Minimal expected value; nil if there is no minimum
28
+ # @param max [Object, nil] Maximal expected value; nil if there is no maximum
29
+ # @note If both min and max are nil, then range is empty set
30
+ def initialize(val, min = nil, max = nil)
31
+ if min == nil and max == nil
32
+ super("Value '#{val}' is out of range {}!")
33
+ elsif min == max
34
+ super("Value '#{val}' is out of range {#{min}}!")
35
+ else
36
+ super("Value '#{val}' is out of range #{(min == nil ? '(-∞' : "<#{min}")};#{(max == nil ? '∞)' : "#{max}>")}!")
37
+ end
38
+ @val = val
39
+ @min = min
40
+ @max = max
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ # Created by Matyáš Pokorný on 2018-01-21.
2
+
3
+ module KXI
4
+ module Exceptions
5
+ # Raised when specific verb was expected
6
+ class VerbExpectedException < Exception
7
+ # Gets array of verbs that were expected
8
+ # @return [Array<String>] Expected verbs
9
+ def verbs
10
+ @verbs
11
+ end
12
+
13
+ # Instantiates the {KXI::CLI::VerbExpectedException} class
14
+ # @param verbs [Array<String>] Expected verbs
15
+ def initialize(verbs)
16
+ super("Expected verb! (#{verbs.join(', ')})")
17
+ @verbs = verbs
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,81 @@
1
+ # Created by Matyáš Pokorný on 2017-12-28.
2
+ module KXI
3
+ module Reflection
4
+ # Represents frame of call stack
5
+ class StackFrame
6
+ # Returns the file of frame
7
+ # @return [String] File of frame
8
+ def file
9
+ @file
10
+ end
11
+
12
+ # Returns the line number of frame
13
+ # @return [Number] Line number of frame
14
+ def line
15
+ @line
16
+ end
17
+
18
+ # Returns the context of frame
19
+ # @return [String] Context of frame
20
+ def context
21
+ @context
22
+ end
23
+
24
+ # Indicates whether frame is block
25
+ # @return [Bool] True if stack frame represents call to block; false otherwise
26
+ def block?
27
+ @block != nil
28
+ end
29
+
30
+ # Returns containing method of frame; nil if none
31
+ # @return [String, nil] Name of method that the stack frame represents
32
+ def method
33
+ return nil if @block != nil and @block[0] == '<' and @block[@block.length - 1] == '>'
34
+ return @block unless @block == nil
35
+ return nil if @context[0] == '<' and @context[@context.length - 1] == '>'
36
+ @context
37
+ end
38
+
39
+ # Instantiates the {KXI::Reflection::StackFrame} class
40
+ # @param file [String] File of frame
41
+ # @param line [Number] Line number of frame
42
+ # @param context [String, nil] Context of frame
43
+ def initialize(file, line, context = nil)
44
+ @file = file
45
+ @line = line
46
+ @context = context
47
+ if context == nil
48
+ @block = nil
49
+ else
50
+ mt = /^block (\((?'levels'\d+) levels\) )?in (?'method'.+)$/mi.match(context)
51
+ @block = mt == nil ? nil : mt['method']
52
+ end
53
+ end
54
+
55
+ # Converts class to string
56
+ # @return [String] Equivalent string
57
+ def to_s
58
+ "#{@file}:#{@line}#{(@context != nil ? ": in `#{@context}'" : '')}"
59
+ end
60
+
61
+ # Parses callstack into array of {KXI::Reflection::StackFrame}
62
+ # @param skip [Number] Number of callstack records to ignore
63
+ # @return [Array<KXI::Reflection::StackFrame>] Equivalent array of stack frames
64
+ def self.callstack(skip = 1)
65
+ ret = []
66
+ caller(skip).each do |bt|
67
+ ret.push(from_backtrace(bt))
68
+ end
69
+ return ret
70
+ end
71
+
72
+ # Parses backtrace line into {KXI::Reflection::StackFrame}
73
+ # @param bt [String] Backtrace line
74
+ # @return [KXI::Reflection::StackFrame] Equivalent stack frame
75
+ def self.from_backtrace(bt)
76
+ mt = /(?'file'.+?):(?'line'\d+)(:\s*in\s*`(?'context'.+?)')?/.match(bt)
77
+ StackFrame.new(mt['file'], mt['line'].to_i, mt['context'])
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,4 @@
1
+ module KXI
2
+ # Version of KXI
3
+ VERSION = '1.0.0'
4
+ end
data/lib/kxi.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'kxi/version'
2
+ require 'kxi/exceptions/abstract_exception'
3
+ require 'kxi/exceptions/collection_exception'
4
+ require 'kxi/exceptions/out_of_range_exception'
5
+ require 'kxi/exceptions/not_implemented_exception'
6
+ require 'kxi/exceptions/argument_exception'
7
+ require 'kxi/exceptions/no_argument_exception'
8
+ require 'kxi/exceptions/verb_expected_exception'
9
+ require 'kxi/exceptions/invalid_type_exception'
10
+ require 'kxi/reflection/stack_frame'
11
+ require 'kxi/collections/enumerator'
12
+ require 'kxi/collections/enumerable'
13
+ require 'kxi/collections/array_collection'
14
+ require 'kxi/collections/hash_collection'
15
+ require 'kxi/collections/protected_collection'
16
+ require 'kxi/cli/argument'
17
+ require 'kxi/cli/explicit_argument'
18
+ require 'kxi/cli/anonymous_argument'
19
+ require 'kxi/cli/flag_argument'
20
+ require 'kxi/cli/named_argument'
21
+ require 'kxi/cli/argument_values'
22
+ require 'kxi/cli/verb'
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kxi
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matyáš Pokorný
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-01-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.15'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.15'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
111
+ description: A collection of classes to help with development of Ruby applications
112
+ email:
113
+ - matyaspoko@live.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - lib/kxi.rb
119
+ - lib/kxi/cli/anonymous_argument.rb
120
+ - lib/kxi/cli/argument.rb
121
+ - lib/kxi/cli/argument_values.rb
122
+ - lib/kxi/cli/explicit_argument.rb
123
+ - lib/kxi/cli/flag_argument.rb
124
+ - lib/kxi/cli/named_argument.rb
125
+ - lib/kxi/cli/verb.rb
126
+ - lib/kxi/collections/array_collection.rb
127
+ - lib/kxi/collections/enumerable.rb
128
+ - lib/kxi/collections/enumerator.rb
129
+ - lib/kxi/collections/hash_collection.rb
130
+ - lib/kxi/collections/protected_collection.rb
131
+ - lib/kxi/exceptions/abstract_exception.rb
132
+ - lib/kxi/exceptions/argument_exception.rb
133
+ - lib/kxi/exceptions/collection_exception.rb
134
+ - lib/kxi/exceptions/invalid_type_exception.rb
135
+ - lib/kxi/exceptions/no_argument_exception.rb
136
+ - lib/kxi/exceptions/not_implemented_exception.rb
137
+ - lib/kxi/exceptions/out_of_range_exception.rb
138
+ - lib/kxi/exceptions/verb_expected_exception.rb
139
+ - lib/kxi/reflection/stack_frame.rb
140
+ - lib/kxi/version.rb
141
+ homepage: https://github.com/cryocz/kxi
142
+ licenses:
143
+ - MIT
144
+ metadata: {}
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 2.6.13
162
+ signing_key:
163
+ specification_version: 4
164
+ summary: Classes for Ruby survival
165
+ test_files: []