gonzedge/rambling-trie

View on GitHub
lib/rambling/trie/serializers/zip.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
# frozen_string_literal: true

module Rambling
  module Trie
    module Serializers
      # Zip file serializer. Dumps/loads contents from +.zip+ files.
      # Automatically detects if zip file contains a +.marshal+ or +.yml+ file,
      # or any other registered +:format => serializer+ combo.
      class Zip < Serializer
        # Creates a new Zip serializer.
        # @param [Configuration::Properties] properties the configuration
        #   properties set up so far.
        def initialize properties
          super()
          @properties = properties
        end

        # Unzip contents from specified filepath and load in contents from
        # unzipped files.
        # @param [String] filepath the filepath to load contents from.
        # @return [TContents] all contents of the unzipped loaded file.
        # @see https://github.com/rubyzip/rubyzip#reading-a-zip-file Zip
        #   reading a file
        def load filepath
          require 'zip'

          ::Zip::File.open filepath do |zip|
            entry = zip.entries.first
            return nil if entry.nil?

            entry_path = path entry.name
            entry.extract entry_path

            serializer = serializers.resolve entry.name
            serializer.load entry_path
          end
        end

        # Dumps contents and zips into a specified filepath.
        # @param [String] contents the contents to dump.
        # @param [String] filepath the filepath to dump the contents to.
        # @return [TContents] number of bytes written to disk.
        # @see https://github.com/rubyzip/rubyzip#basic-zip-archive-creation
        #   Zip archive creation
        def dump contents, filepath
          require 'zip'

          ::Zip::File.open filepath, ::Zip::File::CREATE do |zip|
            filename = ::File.basename filepath, '.zip'

            entry_path = path filename
            serializer = serializers.resolve filename
            serializer.dump contents, entry_path

            zip.add filename, entry_path
          end

          ::File.size filepath
        end

        private

        attr_reader :properties

        def serializers
          properties.serializers
        end

        def tmp_path
          properties.tmp_path
        end

        def path filename
          require 'securerandom'
          ::File.join tmp_path, "#{SecureRandom.uuid}-#{filename}"
        end
      end
    end
  end
end