File: csv.ex

package info (click to toggle)
rabbitmq-server 4.0.5-8
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 37,972 kB
  • sloc: erlang: 257,835; javascript: 22,466; sh: 3,037; makefile: 2,517; python: 1,966; xml: 646; cs: 335; java: 244; ruby: 212; php: 100; perl: 63; awk: 13
file content (131 lines) | stat: -rw-r--r-- 2,907 bytes parent folder | download | duplicates (3)
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
129
130
131
## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at https://mozilla.org/MPL/2.0/.
##
## Copyright (c) 2007-2023 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.  All rights reserved.

alias RabbitMQ.CLI.Formatters.FormatterHelpers

defmodule RabbitMQ.CLI.Formatters.Csv do
  @behaviour RabbitMQ.CLI.FormatterBehaviour

  def format_stream(stream, _) do
    ## Flatten list_consumers
    Stream.flat_map(
      stream,
      fn
        [first | _] = element ->
          case FormatterHelpers.proplist?(first) or is_map(first) do
            true -> element
            false -> [element]
          end

        other ->
          [other]
      end
    )
    ## Add info_items names
    |> Stream.transform(
      :init,
      FormatterHelpers.without_errors_2(fn
        element, :init ->
          {
            case keys(element) do
              nil -> [values(element)]
              ks -> [ks, values(element)]
            end,
            :next
          }

        element, :next ->
          {[values(element)], :next}
      end)
    )
    |> CSV.encode(delimiter: "")
  end

  def format_output(output, _) do
    case keys(output) do
      nil -> [values(output)]
      ks -> [ks, values(output)]
    end
    |> CSV.encode()
    |> Enum.join()
  end

  def machine_readable?, do: true

  #
  # Implementation
  #

  defp keys(map) when is_map(map) do
    Map.keys(map)
  end

  defp keys(list) when is_list(list) do
    case FormatterHelpers.proplist?(list) do
      true -> Keyword.keys(list)
      false -> nil
    end
  end

  defp keys(_other) do
    nil
  end

  defp values(map) when is_map(map) do
    Map.values(map)
  end

  defp values([]) do
    []
  end

  defp values(list) when is_list(list) do
    case FormatterHelpers.proplist?(list) do
      true -> Keyword.values(list)
      false -> list
    end
  end

  defp values(other) do
    other
  end
end

# Elixir 1.15 compiler optimizations require that we explicitly
# add the csv code path
true = Code.append_path(Path.join(["_build", Atom.to_string(Mix.env()), "lib", "csv", "ebin"]))

defimpl CSV.Encode, for: PID do
  def encode(pid, env \\ []) do
    FormatterHelpers.format_info_item(pid)
    |> to_string
    |> CSV.Encode.encode(env)
  end
end

defimpl CSV.Encode, for: List do
  def encode(list, env \\ []) do
    FormatterHelpers.format_info_item(list)
    |> to_string
    |> CSV.Encode.encode(env)
  end
end

defimpl CSV.Encode, for: Tuple do
  def encode(tuple, env \\ []) do
    FormatterHelpers.format_info_item(tuple)
    |> to_string
    |> CSV.Encode.encode(env)
  end
end

defimpl CSV.Encode, for: Map do
  def encode(map, env \\ []) do
    FormatterHelpers.format_info_item(map)
    |> to_string
    |> CSV.Encode.encode(env)
  end
end