datafusion_common/types/
field.rs

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
18use arrow::datatypes::{Field, Fields, UnionFields};
19use std::hash::{Hash, Hasher};
20use std::{ops::Deref, sync::Arc};
21
22use super::{LogicalTypeRef, NativeType};
23
24/// A record of a logical type, its name and its nullability.
25#[derive(Debug, Clone, Eq, PartialOrd, Ord)]
26pub struct LogicalField {
27    pub name: String,
28    pub logical_type: LogicalTypeRef,
29    pub nullable: bool,
30}
31
32impl PartialEq for LogicalField {
33    fn eq(&self, other: &Self) -> bool {
34        self.name == other.name
35            && self.logical_type.eq(&other.logical_type)
36            && self.nullable == other.nullable
37    }
38}
39
40impl Hash for LogicalField {
41    fn hash<H: Hasher>(&self, state: &mut H) {
42        self.name.hash(state);
43        self.logical_type.hash(state);
44        self.nullable.hash(state);
45    }
46}
47
48impl From<&Field> for LogicalField {
49    fn from(value: &Field) -> Self {
50        Self {
51            name: value.name().clone(),
52            logical_type: Arc::new(NativeType::from(value.data_type().clone())),
53            nullable: value.is_nullable(),
54        }
55    }
56}
57
58/// A reference counted [`LogicalField`].
59pub type LogicalFieldRef = Arc<LogicalField>;
60
61/// A cheaply cloneable, owned collection of [`LogicalFieldRef`].
62#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
63pub struct LogicalFields(Arc<[LogicalFieldRef]>);
64
65impl Deref for LogicalFields {
66    type Target = [LogicalFieldRef];
67
68    fn deref(&self) -> &Self::Target {
69        self.0.as_ref()
70    }
71}
72
73impl From<&Fields> for LogicalFields {
74    fn from(value: &Fields) -> Self {
75        value
76            .iter()
77            .map(|field| Arc::new(LogicalField::from(field.as_ref())))
78            .collect()
79    }
80}
81
82impl FromIterator<LogicalFieldRef> for LogicalFields {
83    fn from_iter<T: IntoIterator<Item = LogicalFieldRef>>(iter: T) -> Self {
84        Self(iter.into_iter().collect())
85    }
86}
87
88/// A cheaply cloneable, owned collection of [`LogicalFieldRef`] and their
89/// corresponding type ids.
90#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
91pub struct LogicalUnionFields(Arc<[(i8, LogicalFieldRef)]>);
92
93impl Deref for LogicalUnionFields {
94    type Target = [(i8, LogicalFieldRef)];
95
96    fn deref(&self) -> &Self::Target {
97        self.0.as_ref()
98    }
99}
100
101impl From<&UnionFields> for LogicalUnionFields {
102    fn from(value: &UnionFields) -> Self {
103        value
104            .iter()
105            .map(|(i, field)| (i, Arc::new(LogicalField::from(field.as_ref()))))
106            .collect()
107    }
108}
109
110impl FromIterator<(i8, LogicalFieldRef)> for LogicalUnionFields {
111    fn from_iter<T: IntoIterator<Item = (i8, LogicalFieldRef)>>(iter: T) -> Self {
112        Self(iter.into_iter().collect())
113    }
114}