1use crate::*;
2
3#[derive(Clone, Copy)]
4pub struct Code {
6 pub id: u64,
8 pub ft: usize,
10}
11
12#[derive(Clone)]
13#[non_exhaustive]
18pub enum Value {
19 None,
21 RcBinary(Rc<Vec<u8>>),
23 ArcBinary(Arc<Vec<u8>>),
25 String(Rc<String>),
27 Int(i64),
29 Float(f64),
31 Bool(bool),
33 For(Rc<RefCell<run::ForState>>),
35 ForSort(Rc<RefCell<run::ForSortState>>),
37}
38
39impl Value {
40 pub fn default(t: DataType) -> Value {
42 match data_kind(t) {
43 DataKind::Bool => Value::Bool(false),
44 DataKind::Float => Value::Float(0.0),
45 DataKind::String => Value::String(Rc::new(String::new())),
46 DataKind::Binary => Value::RcBinary(Rc::new(Vec::new())),
47 _ => Value::Int(0),
48 }
49 }
50
51 pub fn load(db: &DB, typ: DataType, data: &[u8], off: usize) -> (Value, Code) {
53 let mut code = Code {
54 id: u64::MAX,
55 ft: 0,
56 };
57 let size = data_size(typ);
58 let val = match data_kind(typ) {
59 DataKind::Binary => {
60 let (bytes, u) = get_bytes(db, &data[off..], size);
61 code = u;
62 Value::RcBinary(Rc::new(bytes))
63 }
64 DataKind::String => {
65 let (bytes, u) = get_bytes(db, &data[off..], size);
66 code = u;
67 let str = String::from_utf8(bytes).unwrap();
68 Value::String(Rc::new(str))
69 }
70 DataKind::Bool => Value::Bool(data[off] != 0),
71 DataKind::Float => {
72 let f = if size == 4 {
73 util::getf32(data, off) as f64
74 } else {
75 util::getf64(data, off)
76 };
77 Value::Float(f)
78 }
79 _ => Value::Int(util::iget(data, off, size)),
80 };
81 (val, code)
82 }
83
84 pub fn save(&self, typ: DataType, data: &mut [u8], off: usize, code: Code) {
86 let size = data_size(typ);
87 match self {
88 Value::Bool(x) => {
89 data[off] = if *x { 1 } else { 0 };
90 }
91 Value::Int(x) => util::iset(data, off, *x, size),
92 Value::Float(x) => {
93 if size == 8 {
94 let bytes = (*x).to_le_bytes();
95 data[off..off + 8].copy_from_slice(&bytes);
96 } else {
97 debug_assert!(size == 4);
98 let val = *x as f32;
99 let bytes = val.to_le_bytes();
100 data[off..off + 4].copy_from_slice(&bytes);
101 }
102 }
103 Value::String(s) => {
104 save_bytes(s.as_bytes(), &mut data[off..], code, size);
105 }
106 Value::RcBinary(b) => {
107 save_bytes(b, &mut data[off..], code, size);
108 }
109 Value::ArcBinary(b) => {
110 save_bytes(b, &mut data[off..], code, size);
111 }
112 _ => {}
113 }
114 }
115
116 pub fn str(&self) -> Rc<String> {
118 match self {
119 Value::String(s) => s.clone(),
120 Value::Int(x) => Rc::new(x.to_string()),
121 Value::Bool(x) => Rc::new(x.to_string()),
122 Value::Float(x) => Rc::new(x.to_string()),
123 Value::RcBinary(x) => Rc::new(util::to_hex(x)),
124 Value::ArcBinary(x) => Rc::new(util::to_hex(x)),
125 _ => panic!("str not implemented"),
126 }
127 }
128
129 pub fn int(&self) -> i64 {
131 match self {
132 Value::Int(x) => *x,
133 _ => panic!(),
134 }
135 }
136
137 pub fn float(&self) -> f64 {
139 match self {
140 Value::Float(x) => *x,
141 _ => panic!(),
142 }
143 }
144
145 pub fn append(&mut self, val: &Value) {
147 if let Value::String(s) = self {
148 let val = val.str();
149 if let Some(ms) = Rc::get_mut(s) {
150 ms.push_str(&val);
151 } else {
152 let mut ns = String::with_capacity(s.len() + val.len());
153 ns.push_str(s);
154 ns.push_str(&val);
155 *self = Value::String(Rc::new(ns));
156 }
157 } else {
158 panic!()
159 }
160 }
161
162 pub fn inc(&mut self, val: &Value) {
164 match self {
165 Value::Int(x) => *x += val.int(),
166 Value::Float(x) => *x += val.float(),
167 _ => panic!(),
168 }
169 }
170
171 pub fn dec(&mut self, val: &Value) {
173 match self {
174 Value::Int(x) => *x -= val.int(),
175 Value::Float(x) => *x -= val.float(),
176 _ => panic!(),
177 }
178 }
179
180 pub fn bin(&self) -> Rc<Vec<u8>> {
182 match self {
183 Value::ArcBinary(x) => Rc::new(x.to_vec()),
184 Value::RcBinary(x) => x.clone(),
185 Value::String(s) => Rc::new(s.as_bytes().to_vec()),
186 Value::Float(x) => Rc::new(x.to_le_bytes().to_vec()),
187 Value::Int(x) => Rc::new(x.to_le_bytes().to_vec()),
188 _ => panic!("bin not implemented"),
189 }
190 }
191
192 pub fn bina(&self) -> &[u8] {
194 match self {
195 Value::RcBinary(data) => data,
196 Value::ArcBinary(data) => data,
197 _ => panic!(),
198 }
199 }
200}
201
202impl std::cmp::Ord for Value {
204 fn cmp(&self, other: &Self) -> Ordering {
205 match self {
206 Value::String(s1) => {
207 if let Value::String(s2) = other {
208 return s1.cmp(s2);
209 }
210 }
211 Value::Int(x1) => {
212 if let Value::Int(x2) = other {
213 return x1.cmp(x2);
214 }
215 }
216 Value::Float(x1) => {
217 if let Value::Float(x2) = other {
218 return x1.partial_cmp(x2).unwrap();
219 }
220 }
221 Value::RcBinary(b1) => {
222 if let Value::RcBinary(b2) = other {
223 return b1.cmp(b2);
224 }
225 }
226 _ => {}
227 }
228 panic!()
229 }
230}
231
232impl PartialOrd for Value {
233 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
234 Some(self.cmp(other))
235 }
236}
237
238impl PartialEq for Value {
239 fn eq(&self, other: &Self) -> bool {
240 if let Some(eq) = self.partial_cmp(other) {
241 eq == Ordering::Equal
242 } else {
243 false
244 }
245 }
246}
247
248impl Eq for Value {}
249
250pub fn get_bytes(db: &DB, data: &[u8], size: usize) -> (Vec<u8>, Code) {
252 let n = data[0] as usize;
253 if n < size {
254 let mut bytes = vec![0_u8; n];
255 bytes[0..n].copy_from_slice(&data[1..=n]);
256 (
257 bytes,
258 Code {
259 id: u64::MAX,
260 ft: 0,
261 },
262 )
263 } else {
264 let id = util::getu64(data, size - 8);
265 let ft = 255 - n;
266 let code = Code { id, ft };
267 let mut bytes = db.decode(code, size - 9);
268 bytes[0..size - 9].copy_from_slice(&data[1..size - 8]);
269 (bytes, code)
270 }
271}
272
273pub fn save_bytes(bytes: &[u8], data: &mut [u8], code: Code, size: usize) {
275 let n = bytes.len();
276 if n < size {
277 data[0] = n as u8;
278 data[1..=n].copy_from_slice(&bytes[0..n]);
279 } else {
280 data[0] = 255 - code.ft as u8;
282 data[1..size - 8].copy_from_slice(&bytes[0..size - 9]);
283 util::setu64(&mut data[size - 8..], code.id);
284 }
285}