factbase 0.0.25 → 0.0.27

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9e0276640bc70144f57a3926e20b6e2d44063da6fe7236fb956867a06e102ba
4
- data.tar.gz: c7826200059da686fe4025aadae2aa1d83eda7e061e4e72c888e327a3d24adda
3
+ metadata.gz: 29134d600523642a5dd215f28aa9b48ec3337fec96d4dc41ea0500a3a4ee46c5
4
+ data.tar.gz: 2335e295a7b5dfe6f3cb1eb5ace692cfbc32d788c91906a6f609249b26c4da13
5
5
  SHA512:
6
- metadata.gz: 8362694429ca241aaa592d36f662b2939ddaec04017ae37326611db4c9a697ab95321f6b3d406a9f4d65be86f9f42ba019ca4c8ec0e8b3ec5c77967bf75107d2
7
- data.tar.gz: 7c96e521d770381536b956e43781c909f597d39b8098178b0c0b77e15e4733c2eaded65a91704ca81c42f214168ad89505f8cfe6830e84e994c247213ef138df
6
+ metadata.gz: bf293f3f8ce5b6f1a515a071f771f1a8d84149e0198b0f11073900ed55a6b218bc2d4dcc65ecc439b777fb8163bb13b2f5d24bea9f2600639276183218f2d9f5
7
+ data.tar.gz: ec4c0b3a780ea432b8560485b4a8c467d2b7fc165a1d29fd27b1e03d35f7f481cc11584b3f60100f4a63b308d84023304eb92f8f970cc105cff7e9eba06df0af
data/.rubocop.yml CHANGED
@@ -44,9 +44,13 @@ Metrics/CyclomaticComplexity:
44
44
  Max: 20
45
45
  Metrics/PerceivedComplexity:
46
46
  Max: 20
47
+ Metrics/ClassLength:
48
+ Enabled: false
47
49
  Layout/EmptyLineAfterGuardClause:
48
50
  Enabled: false
49
51
  Naming/MethodParameterName:
50
52
  MinNameLength: 2
51
53
  Layout/EndOfLine:
52
54
  EnforcedStyle: lf
55
+ Security/MarshalLoad:
56
+ Enabled: false
data/.rultor.yml CHANGED
@@ -31,8 +31,8 @@ release:
31
31
  [[ "${tag}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || exit -1
32
32
  bundle exec rake
33
33
  rm -rf *.gem
34
- sed -i "s/0\.0\.0/${tag}/g" factbase.gemspec
35
- git add factbase.gemspec
34
+ sed -i "s/0\.0\.0/${tag}/g" lib/factbase.rb
35
+ git add lib/factbase.rb
36
36
  git commit -m "version set to ${tag}"
37
37
  gem build factbase.gemspec
38
38
  chmod 0600 ../rubygems.yml
data/factbase.gemspec CHANGED
@@ -21,12 +21,13 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'English'
24
+ require_relative 'lib/factbase'
24
25
 
25
26
  Gem::Specification.new do |s|
26
27
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
27
28
  s.required_ruby_version = '>=2.3'
28
29
  s.name = 'factbase'
29
- s.version = '0.0.25'
30
+ s.version = Factbase::VERSION
30
31
  s.license = 'MIT'
31
32
  s.summary = 'Factbase'
32
33
  s.description = 'Fact base in memory and on disc'
data/lib/factbase/fact.rb CHANGED
@@ -46,6 +46,7 @@ class Factbase::Fact
46
46
  if k.end_with?('=')
47
47
  kk = k[0..-2]
48
48
  raise "Invalid prop name '#{kk}'" unless kk.match?(/^[a-z][_a-zA-Z0-9]*$/)
49
+ raise "Prohibited prop name '#{kk}'" if kk == 'to_s'
49
50
  v = args[1]
50
51
  raise "Prop value can't be nil" if v.nil?
51
52
  raise "Prop value can't be empty" if v == ''
data/lib/factbase/inv.rb CHANGED
@@ -20,6 +20,8 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+ require_relative '../factbase'
24
+
23
25
  # A decorator of a Factbase, that checks invariants on every set.
24
26
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
25
27
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
@@ -30,8 +32,8 @@ class Factbase::Inv
30
32
  @block = block
31
33
  end
32
34
 
33
- def empty?
34
- @fb.empty?
35
+ def dup
36
+ Factbase::Inv.new(@fb.dup, &@block)
35
37
  end
36
38
 
37
39
  def size
@@ -46,6 +48,10 @@ class Factbase::Inv
46
48
  Query.new(@fb.query(query), @block)
47
49
  end
48
50
 
51
+ def txn(this = self, &)
52
+ @fb.txn(this, &)
53
+ end
54
+
49
55
  def export
50
56
  @fb.export
51
57
  end
@@ -54,18 +60,6 @@ class Factbase::Inv
54
60
  @fb.import(bytes)
55
61
  end
56
62
 
57
- def to_json(opt = nil)
58
- @fb.to_json(opt)
59
- end
60
-
61
- def to_xml
62
- @fb.to_xml
63
- end
64
-
65
- def to_yaml
66
- @fb.to_yaml
67
- end
68
-
69
63
  # Fact decorator.
70
64
  class Fact
71
65
  def initialize(fact, block)
@@ -32,8 +32,8 @@ class Factbase::Looged
32
32
  @loog = loog
33
33
  end
34
34
 
35
- def empty?
36
- @fb.empty?
35
+ def dup
36
+ Factbase::Looged.new(@fb.dup, @loog)
37
37
  end
38
38
 
39
39
  def size
@@ -50,6 +50,10 @@ class Factbase::Looged
50
50
  Query.new(@fb.query(query), query, @loog)
51
51
  end
52
52
 
53
+ def txn(this = self, &)
54
+ @fb.txn(this, &)
55
+ end
56
+
53
57
  def export
54
58
  @fb.export
55
59
  end
@@ -58,18 +62,6 @@ class Factbase::Looged
58
62
  @fb.import(bytes)
59
63
  end
60
64
 
61
- def to_json(opt = nil)
62
- @fb.to_json(opt)
63
- end
64
-
65
- def to_xml
66
- @fb.to_xml
67
- end
68
-
69
- def to_yaml
70
- @fb.to_yaml
71
- end
72
-
73
65
  # Fact decorator.
74
66
  class Fact
75
67
  def initialize(fact, loog)
@@ -85,7 +77,9 @@ class Factbase::Looged
85
77
  r = @fact.method_missing(*args)
86
78
  k = args[0].to_s
87
79
  v = args[1]
88
- @loog.debug("Set '#{k[0..-2]}' to #{v.to_s.inspect} (#{v.class})") if k.end_with?('=')
80
+ s = v.is_a?(Time) ? v.utc.iso8601 : v.to_s
81
+ s = v.to_s.inspect if v.is_a?(String)
82
+ @loog.debug("Set '#{k[0..-2]}' to #{s} (#{v.class})") if k.end_with?('=')
89
83
  r
90
84
  end
91
85
 
data/lib/factbase/pre.rb CHANGED
@@ -21,6 +21,7 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'loog'
24
+ require_relative '../factbase'
24
25
 
25
26
  # A decorator of a Factbase, that runs a provided block on every +insert+.
26
27
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -32,8 +33,8 @@ class Factbase::Pre
32
33
  @block = block
33
34
  end
34
35
 
35
- def empty?
36
- @fb.empty?
36
+ def dup
37
+ Factbase::Pre.new(@fb.dup, &@block)
37
38
  end
38
39
 
39
40
  def size
@@ -50,6 +51,10 @@ class Factbase::Pre
50
51
  @fb.query(query)
51
52
  end
52
53
 
54
+ def txn(this = self, &)
55
+ @fb.txn(this, &)
56
+ end
57
+
53
58
  def export
54
59
  @fb.export
55
60
  end
@@ -57,16 +62,4 @@ class Factbase::Pre
57
62
  def import(bytes)
58
63
  @fb.import(bytes)
59
64
  end
60
-
61
- def to_json(opt = nil)
62
- @fb.to_json(opt)
63
- end
64
-
65
- def to_xml
66
- @fb.to_xml
67
- end
68
-
69
- def to_yaml
70
- @fb.to_yaml
71
- end
72
65
  end
@@ -44,7 +44,7 @@ class Factbase::Query
44
44
  yielded = 0
45
45
  @maps.each do |m|
46
46
  f = Factbase::Fact.new(@mutex, m)
47
- next unless term.matches?(f)
47
+ next unless term.eval(f)
48
48
  yield f
49
49
  yielded += 1
50
50
  end
@@ -59,7 +59,7 @@ class Factbase::Query
59
59
  @mutex.synchronize do
60
60
  @maps.delete_if do |m|
61
61
  f = Factbase::Fact.new(@mutex, m)
62
- if term.matches?(f)
62
+ if term.eval(f)
63
63
  deleted += 1
64
64
  true
65
65
  else
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require_relative '../factbase'
24
+
25
+ # A decorator of a Factbase, that checks rules on every set.
26
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
27
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
28
+ # License:: MIT
29
+ class Factbase::Rules
30
+ def initialize(fb, rules)
31
+ @fb = fb
32
+ @rules = rules
33
+ @check = Check.new(fb, @rules)
34
+ end
35
+
36
+ def dup
37
+ Factbase::Rules.new(@fb.dup, @rules)
38
+ end
39
+
40
+ def size
41
+ @fb.size
42
+ end
43
+
44
+ def insert
45
+ Fact.new(@fb.insert, @check)
46
+ end
47
+
48
+ def query(query)
49
+ Query.new(@fb.query(query), @check)
50
+ end
51
+
52
+ def txn(this = self, &)
53
+ @fb.txn(this, &)
54
+ end
55
+
56
+ def export
57
+ @fb.export
58
+ end
59
+
60
+ def import(bytes)
61
+ @fb.import(bytes)
62
+ end
63
+
64
+ # Fact decorator.
65
+ class Fact
66
+ def initialize(fact, check)
67
+ @fact = fact
68
+ @check = check
69
+ end
70
+
71
+ def to_s
72
+ @fact.to_s
73
+ end
74
+
75
+ def method_missing(*args)
76
+ r = @fact.method_missing(*args)
77
+ k = args[0].to_s
78
+ @check.it(self) if k.end_with?('=')
79
+ r
80
+ end
81
+
82
+ # rubocop:disable Style/OptionalBooleanParameter
83
+ def respond_to?(method, include_private = false)
84
+ # rubocop:enable Style/OptionalBooleanParameter
85
+ @fact.respond_to?(method, include_private)
86
+ end
87
+
88
+ def respond_to_missing?(method, include_private = false)
89
+ @fact.respond_to_missing?(method, include_private)
90
+ end
91
+ end
92
+
93
+ # Query decorator.
94
+ class Query
95
+ def initialize(query, check)
96
+ @query = query
97
+ @check = check
98
+ end
99
+
100
+ def each
101
+ return to_enum(__method__) unless block_given?
102
+ @query.each do |f|
103
+ yield Fact.new(f, @check)
104
+ end
105
+ end
106
+
107
+ def delete!
108
+ @query.delete!
109
+ end
110
+ end
111
+
112
+ # Check one fact.
113
+ class Check
114
+ def initialize(fb, expr)
115
+ @fb = fb
116
+ @expr = expr
117
+ end
118
+
119
+ def it(fact)
120
+ return if Factbase::Syntax.new(@expr).to_term.eval(fact)
121
+ raise "The fact is in invalid state: #{fact}"
122
+ end
123
+ end
124
+ end
data/lib/factbase/spy.rb CHANGED
@@ -37,6 +37,14 @@ class Factbase::Spy
37
37
  @caught
38
38
  end
39
39
 
40
+ def dup
41
+ Factbase::Spy.new(@fb.dup, @key)
42
+ end
43
+
44
+ def size
45
+ @fb.size
46
+ end
47
+
40
48
  def query(expr)
41
49
  scan(Factbase::Syntax.new(expr).to_term)
42
50
  @fb.query(expr)
@@ -50,12 +58,12 @@ class Factbase::Spy
50
58
  @fb.export
51
59
  end
52
60
 
53
- def import(data)
54
- @fb.import(data)
61
+ def txn(this = self, &)
62
+ @fb.txn(this, &)
55
63
  end
56
64
 
57
- def to_json(opt = nil)
58
- @fb.to_json(opt)
65
+ def import(data)
66
+ @fb.import(data)
59
67
  end
60
68
 
61
69
  # A fact that is spying.
@@ -20,6 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+ require 'time'
23
24
  require_relative '../factbase'
24
25
  require_relative 'fact'
25
26
  require_relative 'term'
@@ -42,6 +43,7 @@ class Factbase::Syntax
42
43
  @ast ||= to_ast(@tokens, 0)
43
44
  term = @ast[0]
44
45
  raise 'No terms found' if term.nil?
46
+ raise 'Not a term' unless term.is_a?(Factbase::Term)
45
47
  term
46
48
  end
47
49
 
@@ -80,7 +82,7 @@ class Factbase::Syntax
80
82
  list = []
81
83
  acc = ''
82
84
  string = false
83
- @query.to_s.chars.each do |c|
85
+ @query.to_s.gsub(/#.*$/, '').chars.each do |c|
84
86
  if ['\'', '"'].include?(c)
85
87
  if string && acc[acc.length - 1] == '\\'
86
88
  acc = acc[0..-2]
data/lib/factbase/term.rb CHANGED
@@ -41,7 +41,7 @@ class Factbase::Term
41
41
  # Does it match the fact?
42
42
  # @param [Factbase::Fact] fact The fact
43
43
  # @return [bool] TRUE if matches
44
- def matches?(fact)
44
+ def eval(fact)
45
45
  send(@op, fact)
46
46
  end
47
47
 
@@ -71,23 +71,30 @@ class Factbase::Term
71
71
 
72
72
  def not(fact)
73
73
  assert_args(1)
74
- !@operands[0].matches?(fact)
74
+ !@operands[0].eval(fact)
75
75
  end
76
76
 
77
77
  def or(fact)
78
78
  @operands.each do |o|
79
- return true if o.matches?(fact)
79
+ return true if o.eval(fact)
80
80
  end
81
81
  false
82
82
  end
83
83
 
84
84
  def and(fact)
85
85
  @operands.each do |o|
86
- return false unless o.matches?(fact)
86
+ return false unless o.eval(fact)
87
87
  end
88
88
  true
89
89
  end
90
90
 
91
+ def when(fact)
92
+ assert_args(2)
93
+ a = @operands[0]
94
+ b = @operands[1]
95
+ !a.eval(fact) || (a.eval(fact) && b.eval(fact))
96
+ end
97
+
91
98
  def exists(fact)
92
99
  assert_args(1)
93
100
  o = @operands[0]
@@ -116,12 +123,35 @@ class Factbase::Term
116
123
  arithmetic(:>, fact)
117
124
  end
118
125
 
126
+ def size(fact)
127
+ assert_args(1)
128
+ o = @operands[0]
129
+ raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
130
+ k = o.to_s
131
+ return 0 if fact[k].nil?
132
+ return 1 unless fact[k].is_a?(Array)
133
+ fact[k].size
134
+ end
135
+
136
+ def type(fact)
137
+ assert_args(1)
138
+ o = @operands[0]
139
+ raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
140
+ k = o.to_s
141
+ return 'nil' if fact[k].nil?
142
+ fact[k].class.to_s
143
+ end
144
+
119
145
  def arithmetic(op, fact)
120
146
  assert_args(2)
121
147
  o = @operands[0]
122
- raise "A symbol expected by #{op}: #{o}" unless o.is_a?(Symbol)
123
- k = o.to_s
124
- v = fact[k]
148
+ if o.is_a?(Factbase::Term)
149
+ v = o.eval(fact)
150
+ else
151
+ raise "A symbol expected by #{op}: #{o}" unless o.is_a?(Symbol)
152
+ k = o.to_s
153
+ v = fact[k]
154
+ end
125
155
  return false if v.nil?
126
156
  v = [v] unless v.is_a?(Array)
127
157
  v.any? do |vv|
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'json'
24
+ require 'time'
25
+ require_relative '../factbase'
26
+
27
+ # Factbase to JSON converter.
28
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
30
+ # License:: MIT
31
+ class Factbase::ToJSON
32
+ # Constructor.
33
+ def initialize(fb)
34
+ @fb = fb
35
+ end
36
+
37
+ # Convert the entire factbase into JSON.
38
+ # @return [String] The factbase in JSON format
39
+ def json
40
+ maps = Marshal.load(@fb.export)
41
+ maps.to_json
42
+ end
43
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'nokogiri'
24
+ require 'time'
25
+ require_relative '../factbase'
26
+
27
+ # Factbase to XML converter.
28
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
30
+ # License:: MIT
31
+ class Factbase::ToXML
32
+ # Constructor.
33
+ def initialize(fb)
34
+ @fb = fb
35
+ end
36
+
37
+ # Convert the entire factbase into XML.
38
+ # @return [String] The factbase in XML format
39
+ def xml
40
+ meta = {
41
+ factbase_version: Factbase::VERSION,
42
+ dob: Time.now.utc.iso8601
43
+ }
44
+ maps = Marshal.load(@fb.export)
45
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
46
+ xml.fb(meta) do
47
+ maps.each do |m|
48
+ xml.f_ do
49
+ m.each do |k, vv|
50
+ if vv.is_a?(Array)
51
+ xml.send(:"#{k}_") do
52
+ vv.each do |v|
53
+ xml.send(:v, to_str(v))
54
+ end
55
+ end
56
+ else
57
+ xml.send(:"#{k}_", to_str(vv))
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end.to_xml
64
+ end
65
+
66
+ private
67
+
68
+ def to_str(val)
69
+ if val.is_a?(Time)
70
+ val.utc.iso8601
71
+ else
72
+ val.to_s
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'yaml'
24
+ require 'time'
25
+ require_relative '../factbase'
26
+
27
+ # Factbase to YAML converter.
28
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
30
+ # License:: MIT
31
+ class Factbase::ToYAML
32
+ # Constructor.
33
+ def initialize(fb)
34
+ @fb = fb
35
+ end
36
+
37
+ # Convert the entire factbase into YAML.
38
+ # @return [String] The factbase in YAML format
39
+ def yaml
40
+ maps = Marshal.load(@fb.export)
41
+ YAML.dump({ 'facts' => maps })
42
+ end
43
+ end