File: serializer.rb

package info (click to toggle)
ruby-solve 4.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,708 kB
  • sloc: ruby: 36,626; makefile: 3
file content (128 lines) | stat: -rw-r--r-- 3,423 bytes parent folder | download
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
require "json" unless defined?(JSON)
require_relative "../graph"

module Solve

  Problem = Struct.new(:graph, :demands)

  # Simple struct class that contains a #graph and #demands (in Array form)
  #
  # Can be serialized via Solver::Serializer to create a json representation of
  # a dependency solving problem.
  class Problem

    # Create a Problem from a given Solver.
    #
    # @param [Solve::GecodeSolver,Solve::RubySolver] dependency solver
    # @return [Problem]
    def self.from_solver(solver)
      demands_data = solver.demands.map do |demand|
        [ demand.name, demand.constraint.to_s ]
      end
      new(solver.graph, demands_data)
    end
  end

  class Solver
    class Serializer
      # @param [Solve::Problem] problem struct
      #
      # @return [String]
      def serialize(problem)
        graph = problem.graph
        demands = problem.demands

        graph_hash = format_graph(graph)
        demands_hash = format_demands(demands)

        problem_data = graph_hash.merge(demands_hash)
        problem_data.to_json
      end

      # @param [Hash, #to_s] solver a json string or a hash representing a solver
      #
      # @return [Solve::Problem]
      def deserialize(problem_data)
        unless problem_data.is_a?(Hash)
          problem_data = JSON.parse(problem_data.to_s)
        end

        graph_spec = problem_data["graph"]
        demands_spec = problem_data["demands"]

        graph = load_graph(graph_spec)
        demands = load_demands(demands_spec)

        Solve::Problem.new(graph, demands)
      end

      private

      def format_graph(graph)
        artifacts = graph.artifacts.inject([]) do |list, artifact|
          list << format_artifact(artifact)
        end
        { "graph" => artifacts }
      end

      def format_artifact(artifact)
        dependencies = artifact.dependencies.inject([]) do |list, dependency|
          list << format_dependency(dependency)
        end

        {
          "name" => artifact.name,
          "version" => artifact.version.to_s,
          "dependencies" => dependencies,
        }
      end

      def format_dependency(dependency)
        {
          "name" => dependency.name,
          "constraint" => dependency.constraint.to_s,
        }
      end

      def format_demands(demands)
        demands_list = demands.inject([]) do |list, demand|
          list << format_demand(demand)
        end
        { "demands" => demands_list }
      end

      def format_demand(demand)
        {
          "name" => demand[0],
          "constraint" => demand[1],
        }
      end

      def load_graph(artifacts_list)
        graph = Solve::Graph.new
        artifacts_list.each do |artifact_spec|
          load_artifact(graph, artifact_spec)
        end
        graph
      end

      def load_artifact(graph, artifact_spec)
        artifact = graph.artifact(artifact_spec["name"], artifact_spec["version"])
        artifact_spec["dependencies"].each do |dependency_spec|
          load_dependency(artifact, dependency_spec)
        end
        artifact
      end

      def load_dependency(artifact, dependency_spec)
        artifact.depends(dependency_spec["name"], dependency_spec["constraint"])
      end

      def load_demands(demand_specs)
        demand_specs.inject([]) do |list, demand_spec|
          list << [demand_spec["name"], demand_spec["constraint"]]
        end
      end
    end
  end
end