1# Licensed to the Apache Software Foundation (ASF) under one
2# or more contributor license agreements.  See the NOTICE file
3# distributed with this work for additional information
4# regarding copyright ownership.  The ASF licenses this file
5# to you under the Apache License, Version 2.0 (the
6# "License"); you may not use this file except in compliance
7# with the License.  You may obtain a copy of the License at
8#
9#   http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing,
12# software distributed under the License is distributed on an
13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14# KIND, either express or implied.  See the License for the
15# specific language governing permissions and limitations
16# under the License.
17
18module Arrow
19  class StructDataType
20    include FieldContainable
21
22    alias_method :initialize_raw, :initialize
23    private :initialize_raw
24
25    # Creates a new {Arrow::StructDataType}.
26    #
27    # @overload initialize(fields)
28    #
29    #   @param fields [::Array<Arrow::Field, Hash>] The fields of the
30    #     struct data type. You can also specify field description as
31    #     a field. You can mix {Arrow::Field} and field description.
32    #
33    #     See {Arrow::Field.new} how to specify field description.
34    #
35    #   @example Create a struct data type with {Arrow::Field}s
36    #     visible_field = Arrow::Field.new("visible", :boolean)
37    #     count_field = Arrow::Field.new("count", :int32)
38    #     Arrow::StructDataType.new([visible_field, count_field])
39    #
40    #   @example Create a struct data type with field descriptions
41    #     field_descriptions = [
42    #       {name: "visible", type: :boolean},
43    #       {name: "count", type: :int32},
44    #     ]
45    #     Arrow::StructDataType.new(field_descriptions)
46    #
47    #   @example Create a struct data type with {Arrow::Field} and field description
48    #     fields = [
49    #       Arrow::Field.new("visible", :boolean),
50    #       {name: "count", type: :int32},
51    #     ]
52    #     Arrow::StructDataType.new(fields)
53    #
54    # @overload initialize(fields)
55    #
56    #   @param fields [Hash{String, Symbol => Arrow::DataType, Hash}]
57    #     The pairs of field name and field data type of the struct
58    #     data type. You can also specify data type description by
59    #     `Hash`. You can mix {Arrow::DataType} and data type description.
60    #
61    #     See {Arrow::DataType.resolve} how to specify data type
62    #     description.
63    #
64    #   @example Create a struct data type with {Arrow::DataType}s
65    #     fields = {
66    #       "visible" => Arrow::BooleanDataType.new,
67    #       "count" => Arrow::Int32DataType.new,
68    #     }
69    #     Arrow::StructDataType.new(fields)
70    #
71    #   @example Create a struct data type with data type descriptions
72    #     fields = {
73    #       "visible" => :boolean,
74    #       "count" => {type: :int32},
75    #     }
76    #     Arrow::StructDataType.new(fields)
77    #
78    #   @example Create a struct data type with {Arrow::DataType} and data type description
79    #     fields = {
80    #       "visible" => Arrow::BooleanDataType.new,
81    #       "count" => {type: :int32},
82    #     }
83    #     Arrow::StructDataType.new(fields)
84    #
85    # @overload initialize(description)
86    #
87    #   @param description [Hash] The description of the struct data
88    #     type. It must have `:fields` value.
89    #
90    #   @option description
91    #     [::Array<Arrow::Field, Hash>,
92    #      Hash{String, Symbol => Arrow::DataType, Hash, String, Symbol}]
93    #     :fields The fields of the struct data type.
94    #
95    #   @example Create a struct data type with {Arrow::Field} and field description
96    #     fields = [
97    #       Arrow::Field.new("visible", :boolean),
98    #       {name: "count", type: :int32},
99    #     ]
100    #     Arrow::StructDataType.new(fields: fields)
101    #
102    #   @example Create a struct data type with {Arrow::DataType} and data type description
103    #     fields = {
104    #       "visible" => Arrow::BooleanDataType.new,
105    #       "count" => {type: :int32},
106    #     }
107    #     Arrow::StructDataType.new(fields: fields)
108    def initialize(fields)
109      if fields.is_a?(Hash) and fields.key?(:fields)
110        description = fields
111        fields = description[:fields]
112      end
113      if fields.is_a?(Hash)
114        fields = fields.collect do |name, data_type|
115          Field.new(name, data_type)
116        end
117      else
118        fields = fields.collect do |field|
119          field = Field.new(field) unless field.is_a?(Field)
120          field
121        end
122      end
123      initialize_raw(fields)
124    end
125
126    alias_method :[], :find_field
127  end
128end
129