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