lance_encoding/
version.rs1use std::str::FromStr;
5
6use lance_arrow::DataTypeExt;
7use lance_core::datatypes::Field;
8use lance_core::{Error, Result};
9
10pub const LEGACY_FORMAT_VERSION: &str = "0.1";
11pub const V2_FORMAT_2_0: &str = "2.0";
12pub const V2_FORMAT_2_1: &str = "2.1";
13pub const V2_FORMAT_2_2: &str = "2.2";
14pub const V2_FORMAT_2_3: &str = "2.3";
15
16#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Ord, PartialOrd, strum::EnumIter)]
18pub enum LanceFileVersion {
19 Legacy,
30 #[default]
31 V2_0,
32 Stable,
34 V2_1,
35 V2_2,
36 Next,
38 V2_3,
39}
40
41impl LanceFileVersion {
42 pub fn resolve(&self) -> Self {
44 match self {
45 Self::Stable => Self::V2_0,
46 Self::Next => Self::V2_3,
47 _ => *self,
48 }
49 }
50
51 pub fn is_unstable(&self) -> bool {
52 self >= &Self::Next
53 }
54
55 pub fn try_from_major_minor(major: u32, minor: u32) -> Result<Self> {
56 match (major, minor) {
57 (0, 0) => Ok(Self::Legacy),
58 (0, 1) => Ok(Self::Legacy),
59 (0, 2) => Ok(Self::Legacy),
60 (0, 3) => Ok(Self::V2_0),
61 (2, 0) => Ok(Self::V2_0),
62 (2, 1) => Ok(Self::V2_1),
63 (2, 2) => Ok(Self::V2_2),
64 (2, 3) => Ok(Self::V2_3),
65 _ => Err(Error::invalid_input_source(
66 format!("Unknown Lance storage version: {}.{}", major, minor).into(),
67 )),
68 }
69 }
70
71 pub fn to_numbers(&self) -> (u32, u32) {
72 match self {
73 Self::Legacy => (0, 2),
74 Self::V2_0 => (2, 0),
75 Self::V2_1 => (2, 1),
76 Self::V2_2 => (2, 2),
77 Self::V2_3 => (2, 3),
78 Self::Stable => self.resolve().to_numbers(),
79 Self::Next => self.resolve().to_numbers(),
80 }
81 }
82
83 pub fn iter_non_legacy() -> impl Iterator<Item = Self> {
84 use strum::IntoEnumIterator;
85
86 Self::iter().filter(|&v| v != Self::Stable && v != Self::Next && v != Self::Legacy)
87 }
88
89 pub fn support_add_sub_column(&self) -> bool {
90 self > &Self::V2_1
91 }
92
93 pub fn support_remove_sub_column(&self, field: &Field) -> bool {
94 if self <= &Self::V2_1 {
95 field.data_type().is_struct()
96 } else {
97 field.data_type().is_nested()
98 }
99 }
100}
101
102impl std::fmt::Display for LanceFileVersion {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 write!(
105 f,
106 "{}",
107 match self {
108 Self::Legacy => LEGACY_FORMAT_VERSION,
109 Self::V2_0 => V2_FORMAT_2_0,
110 Self::V2_1 => V2_FORMAT_2_1,
111 Self::V2_2 => V2_FORMAT_2_2,
112 Self::V2_3 => V2_FORMAT_2_3,
113 Self::Stable => "stable",
114 Self::Next => "next",
115 }
116 )
117 }
118}
119
120impl FromStr for LanceFileVersion {
121 type Err = Error;
122
123 fn from_str(value: &str) -> Result<Self> {
124 match value.to_lowercase().as_str() {
125 LEGACY_FORMAT_VERSION => Ok(Self::Legacy),
126 V2_FORMAT_2_0 => Ok(Self::V2_0),
127 V2_FORMAT_2_1 => Ok(Self::V2_1),
128 V2_FORMAT_2_2 => Ok(Self::V2_2),
129 V2_FORMAT_2_3 => Ok(Self::V2_3),
130 "stable" => Ok(Self::Stable),
131 "legacy" => Ok(Self::Legacy),
132 "next" => Ok(Self::Next),
133 "0.3" => Ok(Self::V2_0),
135 _ => Err(Error::invalid_input_source(
136 format!("Unknown Lance storage version: {}", value).into(),
137 )),
138 }
139 }
140}