ankurah_core/value/
collatable.rs1use crate::collation::Collatable;
2use crate::value::Value;
3
4impl Collatable for Value {
6 fn to_bytes(&self) -> Vec<u8> {
7 match self {
8 Value::String(s) => s.as_bytes().to_vec(),
9 Value::I16(x) => (*x as i64).to_be_bytes().to_vec(),
11 Value::I32(x) => (*x as i64).to_be_bytes().to_vec(),
12 Value::I64(x) => x.to_be_bytes().to_vec(),
13 Value::F64(f) => {
14 let bits = if f.is_nan() {
15 u64::MAX } else {
17 let bits = f.to_bits();
18 if *f >= 0.0 {
19 bits ^ (1 << 63) } else {
21 !bits }
23 };
24 bits.to_be_bytes().to_vec()
25 }
26 Value::Bool(b) => vec![*b as u8],
27 Value::EntityId(entity_id) => entity_id.to_bytes().to_vec(),
28 Value::Object(bytes) | Value::Binary(bytes) => bytes.clone(),
30 Value::Json(json) => serde_json::to_vec(json).unwrap_or_default(),
32 }
33 }
34
35 fn successor_bytes(&self) -> Option<Vec<u8>> {
36 match self {
37 Value::String(s) => {
38 let mut bytes = s.as_bytes().to_vec();
39 bytes.push(0);
40 Some(bytes)
41 }
42 Value::I16(x) => {
43 if *x == i16::MAX {
44 None
45 } else {
46 Some(((*x as i64) + 1).to_be_bytes().to_vec())
47 }
48 }
49 Value::I32(x) => {
50 if *x == i32::MAX {
51 None
52 } else {
53 Some(((*x as i64) + 1).to_be_bytes().to_vec())
54 }
55 }
56 Value::I64(x) => {
57 if *x == i64::MAX {
58 None
59 } else {
60 Some((x + 1).to_be_bytes().to_vec())
61 }
62 }
63 Value::F64(f) => {
64 if f.is_nan() || (f.is_infinite() && *f > 0.0) {
65 None
66 } else {
67 let bits = if *f >= 0.0 { f.to_bits() ^ (1 << 63) } else { !f.to_bits() };
68 let next_bits = bits + 1;
69 Some(next_bits.to_be_bytes().to_vec())
70 }
71 }
72 Value::Bool(b) => {
73 if *b {
74 None
75 } else {
76 Some(vec![1])
77 }
78 }
79 Value::EntityId(entity_id) => {
80 let mut bytes = entity_id.to_bytes();
81 for i in (0..16).rev() {
83 if bytes[i] == 0xFF {
84 bytes[i] = 0;
85 } else {
86 bytes[i] += 1;
87 return Some(bytes.to_vec());
88 }
89 }
90 None }
92 Value::Object(_) | Value::Binary(_) | Value::Json(_) => None,
93 }
94 }
95
96 fn predecessor_bytes(&self) -> Option<Vec<u8>> {
97 match self {
98 Value::String(s) => {
99 let bytes = s.as_bytes();
100 if bytes.is_empty() {
101 None
102 } else {
103 Some(bytes[..bytes.len() - 1].to_vec())
104 }
105 }
106 Value::I16(x) => {
107 if *x == i16::MIN {
108 None
109 } else {
110 Some(((*x as i64) - 1).to_be_bytes().to_vec())
111 }
112 }
113 Value::I32(x) => {
114 if *x == i32::MIN {
115 None
116 } else {
117 Some(((*x as i64) - 1).to_be_bytes().to_vec())
118 }
119 }
120 Value::I64(x) => {
121 if *x == i64::MIN {
122 None
123 } else {
124 Some((x - 1).to_be_bytes().to_vec())
125 }
126 }
127 Value::F64(f) => {
128 if f.is_nan() || (f.is_infinite() && *f < 0.0) {
129 None
130 } else {
131 let bits = if *f >= 0.0 { f.to_bits() ^ (1 << 63) } else { !f.to_bits() };
132 let prev_bits = bits - 1;
133 Some(prev_bits.to_be_bytes().to_vec())
134 }
135 }
136 Value::Bool(b) => {
137 if *b {
138 Some(vec![0])
139 } else {
140 None
141 }
142 }
143 Value::EntityId(entity_id) => {
144 let mut bytes = entity_id.to_bytes();
145 if bytes == [0u8; 16] {
146 None } else {
148 for i in (0..16).rev() {
150 if bytes[i] == 0 {
151 bytes[i] = 0xFF;
152 } else {
153 bytes[i] -= 1;
154 return Some(bytes.to_vec());
155 }
156 }
157 None }
159 }
160 Value::Object(_) | Value::Binary(_) | Value::Json(_) => None,
161 }
162 }
163
164 fn is_minimum(&self) -> bool {
165 match self {
166 Value::String(s) => s.is_empty(),
167 Value::I16(x) => *x == i16::MIN,
168 Value::I32(x) => *x == i32::MIN,
169 Value::I64(x) => *x == i64::MIN,
170 Value::F64(f) => *f == f64::NEG_INFINITY,
171 Value::Bool(b) => !b,
172 Value::EntityId(entity_id) => entity_id.to_bytes() == [0u8; 16],
173 Value::Object(_) | Value::Binary(_) | Value::Json(_) => false,
174 }
175 }
176
177 fn is_maximum(&self) -> bool {
178 match self {
179 Value::String(_) => false, Value::I16(x) => *x == i16::MAX,
181 Value::I32(x) => *x == i32::MAX,
182 Value::I64(x) => *x == i64::MAX,
183 Value::F64(f) => *f == f64::INFINITY,
184 Value::Bool(b) => *b,
185 Value::EntityId(entity_id) => entity_id.to_bytes() == [0xFFu8; 16],
186 Value::Object(_) | Value::Binary(_) | Value::Json(_) => false,
187 }
188 }
189}