Module: Bootsnap::CompileCache::YAML

Defined in:
lib/bootsnap/compile_cache/yaml.rb

Defined Under Namespace

Modules: Patch

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.cache_dirObject

Returns the value of attribute cache_dir.



8
9
10
# File 'lib/bootsnap/compile_cache/yaml.rb', line 8

def cache_dir
  @cache_dir
end

.msgpack_factoryObject

Returns the value of attribute msgpack_factory.



8
9
10
# File 'lib/bootsnap/compile_cache/yaml.rb', line 8

def msgpack_factory
  @msgpack_factory
end

.supported_optionsObject

Returns the value of attribute supported_options.



8
9
10
# File 'lib/bootsnap/compile_cache/yaml.rb', line 8

def supported_options
  @supported_options
end

Class Method Details

.init!Object



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
# File 'lib/bootsnap/compile_cache/yaml.rb', line 44

def init!
  require('yaml')
  require('msgpack')
  require('date')

  # MessagePack serializes symbols as strings by default.
  # We want them to roundtrip cleanly, so we use a custom factory.
  # see: https://github.com/msgpack/msgpack-ruby/pull/122
  factory = MessagePack::Factory.new
  factory.register_type(0x00, Symbol)
  factory.register_type(
    MessagePack::Timestamp::TYPE, # or just -1
    Time,
    packer: MessagePack::Time::Packer,
    unpacker: MessagePack::Time::Unpacker
  )

  marshal_fallback = {
    packer: ->(value) { Marshal.dump(value) },
    unpacker: ->(payload) { Marshal.load(payload) },
  }
  {
    Date => 0x01,
    Regexp => 0x02,
  }.each do |type, code|
    factory.register_type(code, type, marshal_fallback)
  end

  self.msgpack_factory = factory

  self.supported_options = []
  params = ::YAML.method(:load).parameters
  if params.include?([:key, :symbolize_names])
    self.supported_options << :symbolize_names
  end
  if params.include?([:key, :freeze])
    if factory.load(factory.dump('yaml'), freeze: true).frozen?
      self.supported_options << :freeze
    end
  end
  self.supported_options.freeze
end

.input_to_output(data, kwargs) ⇒ Object



26
27
28
# File 'lib/bootsnap/compile_cache/yaml.rb', line 26

def input_to_output(data, kwargs)
  ::YAML.load(data, **(kwargs || {}))
end

.input_to_storage(contents, _) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/bootsnap/compile_cache/yaml.rb', line 10

def input_to_storage(contents, _)
  raise(Uncompilable) if contents.index("!ruby/object")
  obj = ::YAML.load(contents)
  msgpack_factory.dump(obj)
rescue NoMethodError, RangeError
  # The object included things that we can't serialize
  raise(Uncompilable)
end

.install!(cache_dir) ⇒ Object



38
39
40
41
42
# File 'lib/bootsnap/compile_cache/yaml.rb', line 38

def install!(cache_dir)
  self.cache_dir = cache_dir
  init!
  ::YAML.singleton_class.prepend(Patch)
end

.precompile(path, cache_dir: YAML.cache_dir) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/bootsnap/compile_cache/yaml.rb', line 30

def precompile(path, cache_dir: YAML.cache_dir)
  Bootsnap::CompileCache::Native.precompile(
    cache_dir,
    path.to_s,
    Bootsnap::CompileCache::YAML,
  )
end

.storage_to_output(data, kwargs) ⇒ Object



19
20
21
22
23
24
# File 'lib/bootsnap/compile_cache/yaml.rb', line 19

def storage_to_output(data, kwargs)
  if kwargs && kwargs.key?(:symbolize_names)
    kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
  end
  msgpack_factory.load(data, kwargs)
end