discord_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};
24use std::mem;
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 unsafe { ::std::mem::zeroed() }
49 }
50}
51
52#[derive(Debug)]
56pub struct UuidGen(*mut _UuidGen);
57unsafe impl Sync for UuidGen {}
58unsafe impl Send for UuidGen {}
59
60impl Drop for UuidGen {
61 fn drop(&mut self) {
62 unsafe { cass_uuid_gen_free(self.0) }
63 }
64}
65
66impl Debug for Uuid {
67 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
68 fmt::Display::fmt(self, f)
69 }
70}
71
72impl Display for Uuid {
73 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
74 unsafe {
75 let mut buf = [0u8; CASS_UUID_STRING_LENGTH];
77 cass_uuid_string(self.0, buf.as_mut_ptr() as *mut c_char);
78 let str = CStr::from_bytes_with_nul(&buf)
79 .map_err(|_| fmt::Error)?
80 .to_str()
81 .map_err(|_| fmt::Error)?;
82 fmt::Display::fmt(&str, f)
83 }
84 }
85}
86
87impl Uuid {
88 pub fn min_from_time(&mut self, time: u64) {
90 unsafe { cass_uuid_min_from_time(time, &mut self.0) }
91 }
92
93 pub fn max_from_time(&mut self, time: u64) {
95 unsafe { cass_uuid_max_from_time(time, &mut self.0) }
96 }
97
98 pub fn timestamp(&self) -> u64 {
100 unsafe { cass_uuid_timestamp(self.0) }
101 }
102
103 pub fn version(&self) -> u8 {
105 unsafe { cass_uuid_version(self.0) }
106 }
107}
108
109impl From<uuid::Uuid> for Uuid {
110 fn from(id: uuid::Uuid) -> Uuid {
111 let input = id.as_bytes();
114
115 let mut time_and_version = 0u64;
116 time_and_version |= input[3] as u64;
117 time_and_version |= (input[2] as u64) << 8;
118 time_and_version |= (input[1] as u64) << 16;
119 time_and_version |= (input[0] as u64) << 24;
120
121 time_and_version |= (input[5] as u64) << 32;
122 time_and_version |= (input[4] as u64) << 40;
123
124 time_and_version |= (input[7] as u64) << 48;
125 time_and_version |= (input[6] as u64) << 56;
126
127 let mut clock_seq_and_node = 0u64;
128 for i in 0..8 {
129 clock_seq_and_node |= (input[15 - i] as u64) << (8 * i);
130 }
131 Uuid(_Uuid {
132 time_and_version,
133 clock_seq_and_node,
134 })
135 }
136}
137
138impl From<Uuid> for uuid::Uuid {
139 fn from(id: Uuid) -> uuid::Uuid {
140 let mut output = [0u8; 16];
143 output[3] = id.0.time_and_version as u8;
144 output[2] = (id.0.time_and_version >> 8) as u8;
145 output[1] = (id.0.time_and_version >> 16) as u8;
146 output[0] = (id.0.time_and_version >> 24) as u8;
147
148 output[5] = (id.0.time_and_version >> 32) as u8;
149 output[4] = (id.0.time_and_version >> 40) as u8;
150
151 output[7] = (id.0.time_and_version >> 48) as u8;
152 output[6] = (id.0.time_and_version >> 56) as u8;
153
154 for i in 0..8 {
155 output[15 - i] = (id.0.clock_seq_and_node >> (8 * i)) as u8;
156 }
157 uuid::Uuid::from_bytes(output)
158 }
159}
160
161impl str::FromStr for Uuid {
162 type Err = Error;
163 fn from_str(str: &str) -> Result<Uuid> {
164 unsafe {
165 let mut uuid = mem::zeroed();
166 let str_ptr = str.as_ptr() as *const c_char;
167 cass_uuid_from_string_n(str_ptr, str.len(), &mut uuid)
168 .to_result(())
169 .and_then(|_| Ok(Uuid(uuid)))
170 }
171 }
172}
173
174impl PartialEq for Uuid {
175 fn eq(&self, other: &Uuid) -> bool {
176 self.0.time_and_version == other.0.time_and_version
177 && self.0.clock_seq_and_node == other.0.clock_seq_and_node
178 }
179}
180
181impl Eq for Uuid {}
182
183impl Ord for Uuid {
184 fn cmp(&self, other: &Uuid) -> Ordering {
185 self.0
186 .time_and_version
187 .cmp(&other.0.time_and_version)
188 .then(self.0.clock_seq_and_node.cmp(&other.0.clock_seq_and_node))
189 }
190}
191
192impl PartialOrd for Uuid {
193 fn partial_cmp(&self, other: &Uuid) -> Option<Ordering> {
194 Some(self.cmp(other))
195 }
196}
197
198impl Default for UuidGen {
199 fn default() -> Self {
201 unsafe { UuidGen(cass_uuid_gen_new()) }
202 }
203}
204
205impl UuidGen {
206 pub fn new_with_node(node: u64) -> UuidGen {
210 unsafe { UuidGen(cass_uuid_gen_new_with_node(node)) }
211 }
212
213 pub fn gen_time(&self) -> Uuid {
215 unsafe {
216 let mut output: _Uuid = mem::zeroed();
217 cass_uuid_gen_time(self.0, &mut output);
218 Uuid(output)
219 }
220 }
221
222 pub fn gen_random(&self) -> Uuid {
224 unsafe {
225 let mut output: _Uuid = mem::zeroed();
226 cass_uuid_gen_random(self.0, &mut output);
227 Uuid(output)
228 }
229 }
230
231 pub fn gen_from_time(&self, timestamp: u64) -> Uuid {
245 unsafe {
246 let mut output: _Uuid = mem::zeroed();
247 cass_uuid_gen_from_time(self.0, timestamp, &mut output);
248 Uuid(output)
249 }
250 }
251}
252
253#[test]
254#[allow(unused_variables)]
255fn test_uuid_display_gentime() {
256 let generator = UuidGen::default();
257 let uuid = generator.gen_from_time(1457486866742u64);
258 assert_eq!(uuid.timestamp(), 1457486866742u64);
259 let uuidstr = format!("{}", uuid); }
261
262#[test]
263#[allow(unused_variables)]
264fn test_uuid_debug_genrand() {
265 let generator = UuidGen::default();
266 let uuid = generator.gen_random();
267 let uuidstr = format!("{:?}", uuid); }