factbase 0.0.25 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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