polars_arrow/datatypes/
field.rs

1use std::sync::Arc;
2
3use polars_utils::pl_str::PlSmallStr;
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7use super::{ArrowDataType, Metadata};
8
9pub static DTYPE_ENUM_VALUES: &str = "_PL_ENUM_VALUES";
10pub static DTYPE_CATEGORICAL: &str = "_PL_CATEGORICAL";
11
12/// Represents Arrow's metadata of a "column".
13///
14/// A [`Field`] is the closest representation of the traditional "column": a logical type
15/// ([`ArrowDataType`]) with a name and nullability.
16/// A Field has optional [`Metadata`] that can be used to annotate the field with custom metadata.
17///
18/// Almost all IO in this crate uses [`Field`] to represent logical information about the data
19/// to be serialized.
20#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22pub struct Field {
23    /// Its name
24    pub name: PlSmallStr,
25    /// Its logical [`ArrowDataType`]
26    pub dtype: ArrowDataType,
27    /// Its nullability
28    pub is_nullable: bool,
29    /// Additional custom (opaque) metadata.
30    pub metadata: Option<Arc<Metadata>>,
31}
32
33/// Support for `ArrowSchema::from_iter([field, ..])`
34impl From<Field> for (PlSmallStr, Field) {
35    fn from(value: Field) -> Self {
36        (value.name.clone(), value)
37    }
38}
39
40impl Field {
41    /// Creates a new [`Field`].
42    pub fn new(name: PlSmallStr, dtype: ArrowDataType, is_nullable: bool) -> Self {
43        Field {
44            name,
45            dtype,
46            is_nullable,
47            metadata: Default::default(),
48        }
49    }
50
51    /// Creates a new [`Field`] with metadata.
52    #[inline]
53    pub fn with_metadata(self, metadata: Metadata) -> Self {
54        if metadata.is_empty() {
55            return self;
56        }
57        Self {
58            name: self.name,
59            dtype: self.dtype,
60            is_nullable: self.is_nullable,
61            metadata: Some(Arc::new(metadata)),
62        }
63    }
64
65    /// Returns the [`Field`]'s [`ArrowDataType`].
66    #[inline]
67    pub fn dtype(&self) -> &ArrowDataType {
68        &self.dtype
69    }
70
71    pub fn is_enum(&self) -> bool {
72        if let Some(md) = &self.metadata {
73            md.get(DTYPE_ENUM_VALUES).is_some()
74        } else {
75            false
76        }
77    }
78
79    pub fn is_categorical(&self) -> bool {
80        if let Some(md) = &self.metadata {
81            md.get(DTYPE_CATEGORICAL).is_some()
82        } else {
83            false
84        }
85    }
86}