Skip to main content

reifydb_core/value/column/data/
take.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::storage::DataBitVec;
5
6use crate::value::column::ColumnData;
7
8macro_rules! map_container {
9	($self:expr, |$c:ident| $body:expr) => {
10		match $self {
11			ColumnData::Bool($c) => ColumnData::Bool($body),
12			ColumnData::Float4($c) => ColumnData::Float4($body),
13			ColumnData::Float8($c) => ColumnData::Float8($body),
14			ColumnData::Int1($c) => ColumnData::Int1($body),
15			ColumnData::Int2($c) => ColumnData::Int2($body),
16			ColumnData::Int4($c) => ColumnData::Int4($body),
17			ColumnData::Int8($c) => ColumnData::Int8($body),
18			ColumnData::Int16($c) => ColumnData::Int16($body),
19			ColumnData::Uint1($c) => ColumnData::Uint1($body),
20			ColumnData::Uint2($c) => ColumnData::Uint2($body),
21			ColumnData::Uint4($c) => ColumnData::Uint4($body),
22			ColumnData::Uint8($c) => ColumnData::Uint8($body),
23			ColumnData::Uint16($c) => ColumnData::Uint16($body),
24			ColumnData::Utf8 {
25				container: $c,
26				max_bytes,
27			} => ColumnData::Utf8 {
28				container: $body,
29				max_bytes: *max_bytes,
30			},
31			ColumnData::Date($c) => ColumnData::Date($body),
32			ColumnData::DateTime($c) => ColumnData::DateTime($body),
33			ColumnData::Time($c) => ColumnData::Time($body),
34			ColumnData::Duration($c) => ColumnData::Duration($body),
35
36			ColumnData::IdentityId($c) => ColumnData::IdentityId($body),
37			ColumnData::DictionaryId($c) => ColumnData::DictionaryId($body),
38			ColumnData::Uuid4($c) => ColumnData::Uuid4($body),
39			ColumnData::Uuid7($c) => ColumnData::Uuid7($body),
40			ColumnData::Blob {
41				container: $c,
42				max_bytes,
43			} => ColumnData::Blob {
44				container: $body,
45				max_bytes: *max_bytes,
46			},
47			ColumnData::Int {
48				container: $c,
49				max_bytes,
50			} => ColumnData::Int {
51				container: $body,
52				max_bytes: *max_bytes,
53			},
54			ColumnData::Uint {
55				container: $c,
56				max_bytes,
57			} => ColumnData::Uint {
58				container: $body,
59				max_bytes: *max_bytes,
60			},
61			ColumnData::Decimal {
62				container: $c,
63				precision,
64				scale,
65			} => ColumnData::Decimal {
66				container: $body,
67				precision: *precision,
68				scale: *scale,
69			},
70			ColumnData::Any($c) => ColumnData::Any($body),
71			ColumnData::Option {
72				..
73			} => {
74				unreachable!(
75					"map_container! must not be called on Option variant directly; handle it explicitly"
76				)
77			}
78		}
79	};
80}
81
82impl ColumnData {
83	pub fn take(&self, num: usize) -> ColumnData {
84		match self {
85			ColumnData::Option {
86				inner,
87				bitvec,
88			} => {
89				let new_bitvec = DataBitVec::take(bitvec, num);
90				// If all bits in the taken bitvec are set (all defined),
91				// unwrap the Option and return the bare inner data.
92				if DataBitVec::count_ones(&new_bitvec) == DataBitVec::len(&new_bitvec)
93					&& DataBitVec::len(&new_bitvec) > 0
94				{
95					inner.take(num)
96				} else {
97					ColumnData::Option {
98						inner: Box::new(inner.take(num)),
99						bitvec: new_bitvec,
100					}
101				}
102			}
103			_ => map_container!(self, |c| c.take(num)),
104		}
105	}
106}