1use std::{
16 fmt::{Debug, Display},
17 ops::Deref,
18};
19
20use chrono::Datelike;
21
22use crate::{
23 ffi,
24 raw::{RawDate, RawDateTime, RawEdgeUid},
25};
26
27#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
29pub struct EdgeUid {
30 pub src: i64,
32 pub lid: u16,
34 pub tid: i64,
36 pub dst: i64,
38 pub eid: i64,
40}
41
42impl EdgeUid {
43 pub(crate) fn from_raw(raw: &RawEdgeUid) -> Self {
44 unsafe {
45 let (src, lid, tid, dst, eid) = (
46 ffi::lgraph_api_edge_euid_get_src(raw.as_ptr_mut()),
47 ffi::lgraph_api_edge_euid_get_lid(raw.as_ptr_mut()),
48 ffi::lgraph_api_edge_euid_get_tid(raw.as_ptr_mut()),
49 ffi::lgraph_api_edge_euid_get_dst(raw.as_ptr_mut()),
50 ffi::lgraph_api_edge_euid_get_eid(raw.as_ptr_mut()),
51 );
52
53 EdgeUid {
54 src,
55 lid,
56 tid,
57 dst,
58 eid,
59 }
60 }
61 }
62
63 pub(crate) fn as_raw(&self) -> RawEdgeUid {
64 unsafe {
65 let ptr =
66 ffi::lgraph_api_create_edge_euid(self.src, self.dst, self.lid, self.tid, self.eid);
67 RawEdgeUid::from_ptr(ptr)
68 }
69 }
70}
71
72impl Display for EdgeUid {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 write!(f, "{:?}", self)
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
80pub enum AccessLevel {
81 #[default]
83 None = ffi::lgraph_api_access_level_none as isize,
84 Read = ffi::lgraph_api_access_level_read as isize,
86 Write = ffi::lgraph_api_access_level_write as isize,
88 Full = ffi::lgraph_api_access_level_full as isize,
90}
91
92impl TryFrom<u32> for AccessLevel {
93 type Error = crate::Error;
94 fn try_from(value: u32) -> Result<Self, Self::Error> {
95 match value {
96 ffi::lgraph_api_access_level_none => Ok(Self::None),
97 ffi::lgraph_api_access_level_read => Ok(Self::Read),
98 ffi::lgraph_api_access_level_write => Ok(Self::Write),
99 ffi::lgraph_api_access_level_full => Ok(Self::Full),
100 _ => Err(crate::Error::new("Invalid parameter.".to_string())),
101 }
102 }
103}
104
105impl Display for AccessLevel {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 write!(f, "{:?}", self)
108 }
109}
110
111#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
115#[repr(transparent)]
116pub struct Date {
117 inner: chrono::NaiveDate,
118}
119
120impl Deref for Date {
121 type Target = chrono::NaiveDate;
122 fn deref(&self) -> &Self::Target {
123 &self.inner
124 }
125}
126
127impl AsRef<chrono::NaiveDate> for Date {
128 fn as_ref(&self) -> &chrono::NaiveDate {
129 &self.inner
130 }
131}
132
133impl Date {
134 pub fn from_native(native: chrono::NaiveDate) -> Self {
135 Date { inner: native }
136 }
137
138 pub(crate) fn from_raw_date(raw: &RawDate) -> Self {
139 Date {
140 inner: chrono::NaiveDate::from_num_days_from_ce_opt(raw.days_since_epoch()).unwrap(),
141 }
142 }
143
144 pub(crate) fn as_raw_date(&self) -> RawDate {
145 RawDate::from_days(self.num_days_from_ce())
146 }
147}
148
149impl Debug for Date {
150 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151 write!(f, "{:?}", self.inner)
152 }
153}
154
155impl Display for Date {
156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 write!(f, "{:?}", self)
158 }
159}
160
161#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Default)]
163#[repr(transparent)]
164pub struct DateTime {
165 inner: chrono::NaiveDateTime,
166}
167
168impl Deref for DateTime {
169 type Target = chrono::NaiveDateTime;
170 fn deref(&self) -> &Self::Target {
171 &self.inner
172 }
173}
174
175impl AsRef<chrono::NaiveDateTime> for DateTime {
176 fn as_ref(&self) -> &chrono::NaiveDateTime {
177 &self.inner
178 }
179}
180
181impl DateTime {
182 pub fn from_native(native: chrono::NaiveDateTime) -> Self {
197 DateTime { inner: native }
198 }
199
200 pub fn from_timestamp_opt(secs: i64) -> Option<Self> {
216 chrono::NaiveDateTime::from_timestamp_opt(secs, 0).map(Self::from_native)
217 }
218
219 pub(crate) fn from_raw_datetime(raw: &RawDateTime) -> Self {
220 DateTime {
221 inner: chrono::NaiveDateTime::from_timestamp_opt(raw.seconds_since_epoch(), 0).unwrap(),
222 }
223 }
224
225 pub(crate) fn as_raw_datetime(&self) -> RawDateTime {
226 RawDateTime::from_seconds_since_epoch(self.timestamp())
227 }
228}
229
230impl Debug for DateTime {
231 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232 write!(f, "{:?}", self.inner)
233 }
234}
235
236impl Display for DateTime {
237 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238 write!(f, "{:?}", self)
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use super::{AccessLevel, Date, DateTime, EdgeUid};
245 use chrono::Datelike;
246
247 #[test]
248 fn test_edge_uid() {
249 let euid = EdgeUid {
250 src: 1,
251 lid: 1,
252 tid: 1,
253 dst: 1,
254 eid: 1,
255 };
256 let raw_euid = euid.as_raw();
257 assert_eq!(raw_euid.src(), 1);
258 assert_eq!(raw_euid.lid(), 1);
259 assert_eq!(raw_euid.tid(), 1);
260 assert_eq!(raw_euid.dst(), 1);
261 assert_eq!(raw_euid.eid(), 1);
262 }
263
264 #[test]
265 fn test_access_level() {
266 let none: AccessLevel = libtugraph_sys::lgraph_api_access_level_none
267 .try_into()
268 .expect("faield to convert access_level_none");
269 assert!(matches!(none, AccessLevel::None));
270 let read: AccessLevel = libtugraph_sys::lgraph_api_access_level_read
271 .try_into()
272 .expect("faield to convert access_level_read");
273 assert!(matches!(read, AccessLevel::Read));
274 let write: AccessLevel = libtugraph_sys::lgraph_api_access_level_write
275 .try_into()
276 .expect("faield to convert access_level_write");
277 assert!(matches!(write, AccessLevel::Write));
278 let full: AccessLevel = libtugraph_sys::lgraph_api_access_level_full
279 .try_into()
280 .expect("faield to convert access_level_full");
281 assert!(matches!(full, AccessLevel::Full));
282 let invalid: Result<AccessLevel, _> = 4_u32.try_into();
283 assert!(invalid.is_err());
284 }
285
286 #[test]
287 fn test_date() {
288 let date = Date::from_native(chrono::NaiveDate::from_num_days_from_ce_opt(10000).unwrap());
289 let raw_date = date.as_raw_date();
290 assert_eq!(raw_date.days_since_epoch(), date.num_days_from_ce());
291 }
292
293 #[test]
294 fn test_datetime() {
295 let datetime = DateTime::from_native(
296 chrono::NaiveDateTime::from_timestamp_opt(1_000_000_000, 0).unwrap(),
297 );
298 let raw_datetime = datetime.as_raw_datetime();
299 assert_eq!(raw_datetime.seconds_since_epoch(), datetime.timestamp());
300 }
301}