~singpolyma/dhall-ruby

ref: 7f636a8e64f190fbca72ae31abb34f72632b57ea dhall-ruby/lib/dhall/util.rb -rw-r--r-- 2.0 KiB
7f636a8eStephen Paul Weber Allow as_dhall to be customised by encode_with 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# frozen_string_literal: true

module Dhall
	module Util
		class AllOf
			def initialize(*validators)
				@validators = validators
			end

			def ===(other)
				@validators.all? { |v| v === other }
			end
		end

		class ArrayOf < ValueSemantics::ArrayOf
			def initialize(element_validator, min: 0, max: Float::INFINITY)
				@min = min
				@max = max
				super(element_validator)
			end

			def ===(other)
				super && other.length >= @min && other.length <= @max
			end
		end

		class HashOf
			def initialize(
				key_validator,
				element_validator,
				min: 0,
				max: Float::INFINITY
			)
				@min = min
				@max = max
				@key_validator = key_validator
				@element_validator = element_validator
			end

			def ===(other)
				Hash === other &&
					other.keys.all? { |x| @key_validator === x } &&
					other.values.all? { |x| @element_validator === x } &&
					other.size >= @min && other.size <= @max
			end
		end

		module ArrayAllTheSame
			def self.===(other)
				Array === other && other.all? { |x| x == other.first }
			end
		end

		class Not
			def initialize(validator)
				@validator = validator
			end

			def ===(other)
				!(@validator === other)
			end
		end

		def self.match_results(xs=nil, ys=nil)
			Array(xs).each_with_index.map do |r, idx|
				yield r, ys[idx]
			end
		end

		def self.match_result_promises(xs=nil, ys=nil)
			match_results(yield(Array(xs)), ys) do |promise, promises|
				promises.each { |p| p.fulfill(promise) }
			end
		end

		def self.promise_all_hash(hash)
			keys, promises = hash.to_a.transpose

			return Promise.resolve(hash) unless keys

			Promise.all(promises).then do |values|
				Hash[Util.match_results(keys, values) do |k, v|
					[k, v]
				end]
			end
		end

		def self.psych_coder_from(tag, o)
			coder = Psych::Coder.new(tag)

			if o.respond_to?(:encode_with)
				o.encode_with(coder)
			else
				o.instance_variables.each do |ivar|
					coder[ivar.to_s[1..-1]] = o.instance_variable_get(ivar)
				end
			end

			coder
		end
	end
end