require "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