cassandra_cpp/cassandra/
uuid.rs1use crate::cassandra::error::*;
2use crate::cassandra::util::{Protected, ProtectedInner};
3
4use crate::cassandra_sys::cass_uuid_from_string_n;
5use crate::cassandra_sys::cass_uuid_gen_free;
6use crate::cassandra_sys::cass_uuid_gen_from_time;
7use crate::cassandra_sys::cass_uuid_gen_new;
8use crate::cassandra_sys::cass_uuid_gen_new_with_node;
9use crate::cassandra_sys::cass_uuid_gen_random;
10use crate::cassandra_sys::cass_uuid_gen_time;
11use crate::cassandra_sys::cass_uuid_max_from_time;
12use crate::cassandra_sys::cass_uuid_min_from_time;
13use crate::cassandra_sys::cass_uuid_string;
14use crate::cassandra_sys::cass_uuid_timestamp;
15use crate::cassandra_sys::cass_uuid_version;
16use crate::cassandra_sys::CassUuid as _Uuid;
17use crate::cassandra_sys::CassUuidGen as _UuidGen;
18
19use std::cmp::Ordering;
20use std::ffi::CStr;
21use std::fmt;
22use std::fmt::Formatter;
23use std::fmt::{Debug, Display};
24
25use std::os::raw::c_char;
26use std::str;
27
28const CASS_UUID_STRING_LENGTH: usize = 37;
29
30#[derive(Copy, Clone)]
31pub struct Uuid(_Uuid);
33
34impl ProtectedInner<_Uuid> for Uuid {
35 fn inner(&self) -> _Uuid {
36 self.0
37 }
38}
39
40impl Protected<_Uuid> for Uuid {
41 fn build(inner: _Uuid) -> Self {
42 Uuid(inner)
43 }
44}
45
46impl Default for Uuid {
47 fn default() -> Uuid {
48 Uuid(_Uuid {
49 time_and_version: 0,
50 clock_seq_and_node: 0,
51 })
52 }
53}
54
55#[derive(Debug)]
59pub struct UuidGen(*mut _UuidGen);
60unsafe impl Sync for UuidGen {}
61unsafe impl Send for UuidGen {}
62
63impl Drop for UuidGen {
64 fn drop(&mut self) {
65 unsafe { cass_uuid_gen_free(self.0) }
66 }
67}
68
69impl Debug for Uuid {
70 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
71 fmt::Display::fmt(self, f)
72 }
73}
74
75impl Display for Uuid {
76 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
77 unsafe {
78 let mut buf = [0u8; CASS_UUID_STRING_LENGTH];
80 cass_uuid_string(self.0, buf.as_mut_ptr() as *mut c_char);
81 let str = CStr::from_bytes_with_nul(&buf)
82 .map_err(|_| fmt::Error)?
83 .to_str()
84 .map_err(|_| fmt::Error)?;
85 fmt::Display::fmt(&str, f)
86 }
87 }
88}
89
90impl Uuid {
91 pub fn min_from_time(&mut self, time: u64) {
93 unsafe { cass_uuid_min_from_time(time, &mut self.0) }
94 }
95
96 pub fn max_from_time(&mut self, time: u64) {
98 unsafe { cass_uuid_max_from_time(time, &mut self.0) }
99 }
100
101 pub fn timestamp(&self) -> u64 {
103 unsafe { cass_uuid_timestamp(self.0) }
104 }
105
106 pub fn version(&self) -> u8 {
108 unsafe { cass_uuid_version(self.0) }
109 }
110}
111
112impl From<uuid::Uuid> for Uuid {
113 fn from(id: uuid::Uuid) -> Uuid {
114 let input = id.as_bytes();
117
118 let mut time_and_version = 0u64;
119 time_and_version |= input[3] as u64;
120 time_and_version |= (input[2] as u64) << 8;
121 time_and_version |= (input[1] as u64) << 16;
122 time_and_version |= (input[0] as u64) << 24;
123
124 time_and_version |= (input[5] as u64) << 32;
125 time_and_version |= (input[4] as u64) << 40;
126
127 time_and_version |= (input[7] as u64) << 48;
128 time_and_version |= (input[6] as u64) << 56;
129
130 let mut clock_seq_and_node = 0u64;
131 for i in 0..8 {
132 clock_seq_and_node |= (input[15 - i] as u64) << (8 * i);
133 }
134 Uuid(_Uuid {
135 time_and_version,
136 clock_seq_and_node,
137 })
138 }
139}
140
141impl From<Uuid> for uuid::Uuid {
142 fn from(id: Uuid) -> uuid::Uuid {
143 let mut output = [0u8; 16];
146 output[3] = id.0.time_and_version as u8;
147 output[2] = (id.0.time_and_version >> 8) as u8;
148 output[1] = (id.0.time_and_version >> 16) as u8;
149 output[0] = (id.0.time_and_version >> 24) as u8;
150
151 output[5] = (id.0.time_and_version >> 32) as u8;
152 output[4] = (id.0.time_and_version >> 40) as u8;
153
154 output[7] = (id.0.time_and_version >> 48) as u8;
155 output[6] = (id.0.time_and_version >> 56) as u8;
156
157 for i in 0..8 {
158 output[15 - i] = (id.0.clock_seq_and_node >> (8 * i)) as u8;
159 }
160 uuid::Uuid::from_bytes(output)
161 }
162}
163
164impl str::FromStr for Uuid {
165 type Err = Error;
166 fn from_str(str: &str) -> Result<Uuid> {
167 let str_ptr = str.as_ptr() as *const c_char;
168 let mut uuid = _Uuid {
169 time_and_version: 0,
170 clock_seq_and_node: 0,
171 };
172 unsafe {
173 cass_uuid_from_string_n(str_ptr, str.len(), &mut uuid)
174 .to_result(())
175 .map(|_| Uuid(uuid))
176 }
177 }
178}
179
180impl PartialEq for Uuid {
181 fn eq(&self, other: &Uuid) -> bool {
182 self.0.time_and_version == other.0.time_and_version
183 && self.0.clock_seq_and_node == other.0.clock_seq_and_node
184 }
185}
186
187impl Eq for Uuid {}
188
189impl Ord for Uuid {
190 fn cmp(&self, other: &Uuid) -> Ordering {
191 self.0
192 .time_and_version
193 .cmp(&other.0.time_and_version)
194 .then(self.0.clock_seq_and_node.cmp(&other.0.clock_seq_and_node))
195 }
196}
197
198impl PartialOrd for Uuid {
199 fn partial_cmp(&self, other: &Uuid) -> Option<Ordering> {
200 Some(self.cmp(other))
201 }
202}
203
204impl Default for UuidGen {
205 fn default() -> Self {
207 unsafe { UuidGen(cass_uuid_gen_new()) }
208 }
209}
210
211impl UuidGen {
212 pub fn new_with_node(node: u64) -> UuidGen {
216 unsafe { UuidGen(cass_uuid_gen_new_with_node(node)) }
217 }
218
219 pub fn gen_time(&self) -> Uuid {
221 let mut output = _Uuid {
222 time_and_version: 0,
223 clock_seq_and_node: 0,
224 };
225 unsafe {
226 cass_uuid_gen_time(self.0, &mut output);
227 Uuid(output)
228 }
229 }
230
231 pub fn gen_random(&self) -> Uuid {
233 let mut output = _Uuid {
234 time_and_version: 0,
235 clock_seq_and_node: 0,
236 };
237 unsafe {
238 cass_uuid_gen_random(self.0, &mut output);
239 Uuid(output)
240 }
241 }
242
243 pub fn gen_from_time(&self, timestamp: u64) -> Uuid {
257 let mut output = _Uuid {
258 time_and_version: 0,
259 clock_seq_and_node: 0,
260 };
261 unsafe {
262 cass_uuid_gen_from_time(self.0, timestamp, &mut output);
263 Uuid(output)
264 }
265 }
266}
267
268#[test]
269#[allow(unused_variables)]
270fn test_uuid_display_gentime() {
271 let generator = UuidGen::default();
272 let uuid = generator.gen_from_time(1457486866742u64);
273 assert_eq!(uuid.timestamp(), 1457486866742u64);
274 let uuidstr = format!("{}", uuid); }
276
277#[test]
278#[allow(unused_variables)]
279fn test_uuid_debug_genrand() {
280 let generator = UuidGen::default();
281 let uuid = generator.gen_random();
282 let uuidstr = format!("{:?}", uuid); }