factbase 0.0.24 → 0.0.26

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: 17e8ed984f9d03fcd9885a54fc01e555dc9c9dc561754e3e51fccbc39a44b846
4
- data.tar.gz: adb616eb6b3eb3793b8d9d4413f8504d6122bf1bc1c14d4d3b5a02c3722a6cd0
3
+ metadata.gz: 1be768141fbb97e4753b38b4b8c438a8cf870957744868af05ab325bec94582c
4
+ data.tar.gz: bcef0970b79fba877d7f677440e595382a64cab724b00d7df101a0a2bf66d146
5
5
  SHA512:
6
- metadata.gz: f52fb4f8f4ecfb4e9d72c02960f038e4b6cd539e64f17adb8866d556c7fa0fbd4f0ec897f4203f730736d819ecd3368c003d640704e790b2f8a202d13d9d8bdc
7
- data.tar.gz: 347ee42c1a93dc731281c4f8fa4026ba105fbb46c3a34886c8cadbd440becfc95ec01300cfbaa9ef0e9ea565c71e2357823fe4cdd3c0d24cf7966ec3fbe23a4e
6
+ metadata.gz: 2b705bad3bc10f08a9865217f015069c34e679c6718382f321926d6ae76b96db6e56dd4c76540eeec8fb0511a8e7a40077d7ac8092fbe6588d75cefaf9e5f4d1
7
+ data.tar.gz: 3e4c1a563194008beb1697f5a4e146a0a88713fb876c8414893bff69db34b33a10d812135f85cac8ef9655d50d40d7186a3b00aa4c863f5ce4ba4a52429d9c37
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.24'
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)
@@ -102,6 +96,7 @@ class Factbase::Inv
102
96
  end
103
97
 
104
98
  def each
99
+ return to_enum(__method__) unless block_given?
105
100
  @query.each do |f|
106
101
  yield Fact.new(f, @block)
107
102
  end
@@ -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'
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,26 @@ 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
+
119
136
  def arithmetic(op, fact)
120
137
  assert_args(2)
121
138
  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]
139
+ if o.is_a?(Factbase::Term)
140
+ v = o.eval(fact)
141
+ else
142
+ raise "A symbol expected by #{op}: #{o}" unless o.is_a?(Symbol)
143
+ k = o.to_s
144
+ v = fact[k]
145
+ end
125
146
  return false if v.nil?
126
147
  v = [v] unless v.is_a?(Array)
127
148
  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