1use crate::client::{QueryClient, CacheEntry, CacheStats};
2use crate::types::QueryKey;
3use crate::persistence::PersistenceManager;
4use crate::optimistic::{OptimisticManager, OptimisticStats};
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::sync::Arc;
8use std::time::{Duration, Instant};
9use parking_lot::RwLock;
10use uuid::Uuid;
11
12#[derive(Clone, Debug, Serialize, Deserialize)]
14pub struct DevToolsConfig {
15 pub enabled: bool,
17 pub port: Option<u16>,
19 pub max_history: usize,
21 pub capture_metrics: bool,
23 pub capture_network: bool,
25 pub capture_cache: bool,
27}
28
29impl Default for DevToolsConfig {
30 fn default() -> Self {
31 Self {
32 enabled: true,
33 port: Some(3001),
34 max_history: 1000,
35 capture_metrics: true,
36 capture_network: true,
37 capture_cache: true,
38 }
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct QueryMetrics {
45 pub key: QueryKey,
47 #[serde(with = "duration_serde")]
49 pub total_time: Duration,
50 pub execution_count: usize,
52 #[serde(with = "duration_serde")]
54 pub avg_time: Duration,
55 #[serde(with = "option_instant_serde")]
57 pub last_execution: Option<Instant>,
58 pub cache_hit_rate: f64,
60 pub error_count: usize,
62 pub success_count: usize,
64 pub total_requests: usize,
66 #[serde(with = "duration_serde")]
68 pub average_response_time: Duration,
69}
70
71impl QueryMetrics {
72 pub fn new(key: QueryKey) -> Self {
74 Self {
75 key,
76 total_time: Duration::ZERO,
77 execution_count: 0,
78 avg_time: Duration::ZERO,
79 last_execution: None,
80 cache_hit_rate: 0.0,
81 error_count: 0,
82 success_count: 0,
83 total_requests: 0,
84 average_response_time: Duration::ZERO,
85 }
86 }
87
88 pub fn record_execution(&mut self, duration: Duration, success: bool) {
90 self.total_time += duration;
91 self.execution_count += 1;
92 self.avg_time = self.total_time / self.execution_count as u32;
93 self.last_execution = Some(Instant::now());
94 self.total_requests += 1;
95 self.average_response_time = self.avg_time;
96
97 if success {
98 self.success_count += 1;
99 } else {
100 self.error_count += 1;
101 }
102 }
103
104 pub fn update_cache_hit_rate(&mut self, hits: usize, total: usize) {
106 if total > 0 {
107 self.cache_hit_rate = hits as f64 / total as f64;
108 }
109 }
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct NetworkRequest {
115 pub id: String,
117 pub key: QueryKey,
119 pub url: String,
121 pub method: String,
123 #[serde(with = "instant_serde")]
125 pub timestamp: Instant,
126 #[serde(with = "option_duration_serde")]
128 pub duration: Option<Duration>,
129 pub status: Option<u16>,
131 pub error: Option<String>,
133 pub headers: HashMap<String, String>,
135 pub body: Option<String>,
137 pub body_size: Option<usize>,
139 pub response_size: Option<usize>,
141}
142
143impl NetworkRequest {
144 pub fn new(key: QueryKey, url: String, method: String) -> Self {
146 Self {
147 id: Uuid::new_v4().to_string(),
148 key,
149 url,
150 method,
151 timestamp: Instant::now(),
152 duration: None,
153 status: None,
154 error: None,
155 headers: HashMap::new(),
156 body: None,
157 body_size: None,
158 response_size: None,
159 }
160 }
161
162 pub fn complete(&mut self, status: u16, duration: Duration, response_size: Option<usize>) {
164 self.status = Some(status);
165 self.duration = Some(duration);
166 self.response_size = response_size;
167 }
168
169 pub fn fail(&mut self, error: String, duration: Duration) {
171 self.error = Some(error);
172 self.duration = Some(duration);
173 }
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
178pub enum CacheOperation {
179 Set { key: QueryKey, size: usize, #[serde(with = "instant_serde")] timestamp: Instant },
181 Get { key: QueryKey, hit: bool, #[serde(with = "instant_serde")] timestamp: Instant },
183 Remove { key: QueryKey, #[serde(with = "instant_serde")] timestamp: Instant },
185 Clear { #[serde(with = "instant_serde")] timestamp: Instant },
187 Expire { key: QueryKey, #[serde(with = "instant_serde")] timestamp: Instant },
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize)]
193pub enum DevToolsEvent {
194 QueryStart { key: QueryKey, #[serde(with = "instant_serde")] timestamp: Instant },
196 QueryComplete { key: QueryKey, success: bool, #[serde(with = "duration_serde")] duration: Duration, #[serde(with = "instant_serde")] timestamp: Instant },
198 CacheOp { operation: CacheOperation },
200 NetworkRequest { request: NetworkRequest },
202 OptimisticUpdate { key: QueryKey, update_id: String, #[serde(with = "instant_serde")] timestamp: Instant },
204 OptimisticConfirm { key: QueryKey, update_id: String, #[serde(with = "instant_serde")] timestamp: Instant },
206 OptimisticRollback { key: QueryKey, update_id: String, #[serde(with = "instant_serde")] timestamp: Instant },
208 PersistenceOp { operation: String, key: Option<QueryKey>, #[serde(with = "instant_serde")] timestamp: Instant },
210 QueryError { key: QueryKey, error: String, #[serde(with = "instant_serde")] timestamp: Instant },
212 CacheOperation { operation: CacheOperation, #[serde(with = "instant_serde")] timestamp: Instant },
214}
215
216pub struct DevToolsManager {
218 config: DevToolsConfig,
220 metrics: Arc<RwLock<HashMap<QueryKey, QueryMetrics>>>,
222 network_history: Arc<RwLock<Vec<NetworkRequest>>>,
224 cache_history: Arc<RwLock<Vec<CacheOperation>>>,
226 event_history: Arc<RwLock<Vec<DevToolsEvent>>>,
228 active_queries: Arc<RwLock<HashMap<QueryKey, Instant>>>,
230}
231
232impl DevToolsManager {
233 pub fn new(config: DevToolsConfig) -> Self {
235 Self {
236 config,
237 metrics: Arc::new(RwLock::new(HashMap::new())),
238 network_history: Arc::new(RwLock::new(Vec::new())),
239 cache_history: Arc::new(RwLock::new(Vec::new())),
240 event_history: Arc::new(RwLock::new(Vec::new())),
241 active_queries: Arc::new(RwLock::new(HashMap::new())),
242 }
243 }
244
245 pub fn is_enabled(&self) -> bool {
247 self.config.enabled
248 }
249
250 pub fn start_server(&mut self, address: String) -> Result<DevToolsServer, String> {
252 if !self.config.enabled {
253 return Err("DevTools is not enabled".to_string());
254 }
255
256 let parts: Vec<&str> = address.split(':').collect();
258 if parts.len() != 2 {
259 return Err("Invalid address format. Expected 'host:port'".to_string());
260 }
261
262 let host = parts[0].to_string();
263 let port: u16 = parts[1].parse().map_err(|_| "Invalid port number".to_string())?;
264
265 let manager = Arc::new(DevToolsManager::new(self.config.clone()));
266 let config = DevToolsConfig::default();
267 Ok(DevToolsServer::new(manager, config))
268 }
269
270 pub fn record_query_start(&self, key: &QueryKey) {
272 if !self.config.capture_metrics {
273 return;
274 }
275
276 let mut active = self.active_queries.write();
277 active.insert(key.clone(), Instant::now());
278
279 let event = DevToolsEvent::QueryStart {
280 key: key.clone(),
281 timestamp: Instant::now(),
282 };
283 self.record_event(event);
284 }
285
286 pub fn record_query_complete(&self, key: &QueryKey, success: bool, duration: Duration) {
288 if !self.config.capture_metrics {
289 return;
290 }
291
292 let mut active = self.active_queries.write();
294 active.remove(key);
295
296 let mut metrics = self.metrics.write();
298 let query_metrics = metrics.entry(key.clone()).or_insert_with(|| QueryMetrics::new(key.clone()));
299 query_metrics.record_execution(duration, success);
300
301 let event = DevToolsEvent::QueryComplete {
302 key: key.clone(),
303 success,
304 duration,
305 timestamp: Instant::now(),
306 };
307 self.record_event(event);
308 }
309
310 pub fn record_query_success(&self, key: &QueryKey, duration: Duration) {
312 self.record_query_complete(key, true, duration);
313 }
314
315 pub fn record_query_error(&self, key: &QueryKey, error: &crate::retry::QueryError) {
317 if !self.config.capture_metrics {
318 return;
319 }
320
321 let mut active = self.active_queries.write();
323 active.remove(key);
324
325 let event = DevToolsEvent::QueryError {
326 key: key.clone(),
327 error: error.to_string(),
328 timestamp: Instant::now(),
329 };
330 self.record_event(event);
331 }
332
333 pub fn record_network_request(&self, _key: &QueryKey, request: NetworkRequest) {
335 if !self.config.capture_network {
336 return;
337 }
338
339 let mut history = self.network_history.write();
340 history.push(request.clone());
341
342 if history.len() > self.config.max_history {
344 history.remove(0);
345 }
346
347 let event = DevToolsEvent::NetworkRequest { request };
348 self.record_event(event);
349 }
350
351 pub fn record_cache_operation(&self, operation: CacheOperation, _key: &QueryKey, _data: Option<&impl Serialize>) {
353 if !self.config.capture_cache {
354 return;
355 }
356
357 let mut history = self.cache_history.write();
358 history.push(operation.clone());
359
360 if history.len() > self.config.max_history {
362 history.remove(0);
363 }
364
365 let event = DevToolsEvent::CacheOperation { operation, timestamp: std::time::Instant::now() };
366 self.record_event(event);
367 }
368
369 pub fn record_optimistic_update(&self, key: &QueryKey, update_id: &str) {
371 let event = DevToolsEvent::OptimisticUpdate {
372 key: key.clone(),
373 update_id: update_id.to_string(),
374 timestamp: Instant::now(),
375 };
376 self.record_event(event);
377 }
378
379 pub fn record_optimistic_confirm(&self, key: &QueryKey, update_id: &str) {
381 let event = DevToolsEvent::OptimisticConfirm {
382 key: key.clone(),
383 update_id: update_id.to_string(),
384 timestamp: Instant::now(),
385 };
386 self.record_event(event);
387 }
388
389 pub fn record_optimistic_rollback(&self, key: &QueryKey, update_id: &str) {
391 let event = DevToolsEvent::OptimisticRollback {
392 key: key.clone(),
393 update_id: update_id.to_string(),
394 timestamp: Instant::now(),
395 };
396 self.record_event(event);
397 }
398
399 pub fn record_persistence_operation(&self, operation: &str, key: Option<&QueryKey>) {
401 let event = DevToolsEvent::PersistenceOp {
402 operation: operation.to_string(),
403 key: key.cloned(),
404 timestamp: Instant::now(),
405 };
406 self.record_event(event);
407 }
408
409 fn record_event(&self, event: DevToolsEvent) {
411 let mut history = self.event_history.write();
412 history.push(event);
413
414 if history.len() > self.config.max_history {
416 history.remove(0);
417 }
418 }
419
420 pub fn get_query_metrics(&self, _key: &QueryKey) -> Option<QueryMetrics> {
422 let metrics = self.metrics.read();
424 metrics.values().next().cloned()
425 }
426
427 pub fn get_network_history(&self) -> Vec<NetworkRequest> {
429 let history = self.network_history.read();
430 history.clone()
431 }
432
433 pub fn get_cache_history(&self) -> Vec<CacheOperation> {
435 let history = self.cache_history.read();
436 history.clone()
437 }
438
439 pub fn get_event_history(&self) -> Vec<DevToolsEvent> {
441 let history = self.event_history.read();
442 history.clone()
443 }
444
445 pub fn get_active_queries(&self) -> Vec<ActiveQuery> {
447 let active = self.active_queries.read();
448 let now = Instant::now();
449 active
450 .iter()
451 .map(|(key, start_time)| ActiveQuery {
452 key: key.clone(),
453 duration: now.duration_since(*start_time),
454 })
455 .collect()
456 }
457
458 pub fn get_cache_stats(&self, client: &QueryClient) -> CacheStats {
460 client.cache_stats()
461 }
462
463 pub fn get_cache_entries(&self, client: &QueryClient) -> Vec<(QueryKey, CacheEntry)> {
465 client.get_cache_entries()
466 }
467
468 pub fn get_optimistic_stats(&self, manager: &OptimisticManager<String>) -> OptimisticStats {
470 manager.get_stats()
471 }
472
473 pub fn get_persistence_stats(&self, manager: &PersistenceManager) -> HashMap<String, usize> {
475 let mut stats = HashMap::new();
476 stats.insert("offline_queue_size".to_string(), manager.get_offline_queue().len());
477 stats.insert("cache_persisted".to_string(), if manager.is_cache_persisted() { 1 } else { 0 });
478 stats
479 }
480
481 pub fn clear_history(&self) {
483 let mut metrics = self.metrics.write();
484 let mut network = self.network_history.write();
485 let mut cache = self.cache_history.write();
486 let mut events = self.event_history.write();
487 let mut active = self.active_queries.write();
488
489 metrics.clear();
490 network.clear();
491 cache.clear();
492 events.clear();
493 active.clear();
494 }
495
496 pub fn export_data(&self) -> DevToolsExport {
498 DevToolsExport {
499 query_metrics: self.metrics.read().values().cloned().collect(),
500 network_requests: self.get_network_history(),
501 cache_operations: self.get_cache_history(),
502 event_history: self.get_event_history(),
503 active_queries: self.get_active_queries(),
504 timestamp: std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs(),
505 }
506 }
507
508 pub fn get_recent_events(&self, count: usize) -> Vec<DevToolsEvent> {
510 let history = self.event_history.read();
511 let start = if history.len() > count {
512 history.len() - count
513 } else {
514 0
515 };
516 history[start..].to_vec()
517 }
518
519 pub fn start_monitoring(&mut self) {
521 self.config.enabled = true;
524 }
525
526 pub fn stop_monitoring(&mut self) {
528 self.config.enabled = false;
531 }
532
533 pub fn is_monitoring(&self) -> bool {
535 self.config.enabled
536 }
537
538 pub fn get_performance_stats(&self) -> PerformanceStats {
540 let metrics = self.metrics.read();
541 let mut total_queries = 0;
542 let mut total_time = Duration::ZERO;
543 let mut max_time = Duration::ZERO;
544 let mut min_time = Duration::from_secs(u64::MAX);
545
546 for query_metrics in metrics.values() {
547 total_queries += query_metrics.execution_count;
548 total_time += query_metrics.total_time;
549 if query_metrics.total_time > max_time {
550 max_time = query_metrics.total_time;
551 }
552 if query_metrics.total_time < min_time {
553 min_time = query_metrics.total_time;
554 }
555 }
556
557 let average_time = if total_queries > 0 {
558 total_time / total_queries as u32
559 } else {
560 Duration::ZERO
561 };
562
563 PerformanceStats {
564 total_queries,
565 average_response_time: average_time,
566 max_response_time: max_time,
567 min_response_time: if min_time == Duration::from_secs(u64::MAX) { Duration::ZERO } else { min_time },
568 }
569 }
570
571 pub fn get_error_stats(&self) -> ErrorStats {
573 let events = self.event_history.read();
574 let mut total_errors = 0;
575 let mut total_events = events.len();
576
577 for event in events.iter() {
578 if matches!(event, DevToolsEvent::QueryError { .. }) {
579 total_errors += 1;
580 }
581 }
582
583 let error_rate = if total_events > 0 {
584 total_errors as f64 / total_events as f64
585 } else {
586 0.0
587 };
588
589 ErrorStats {
590 total_errors,
591 error_rate,
592 }
593 }
594
595 pub fn import_data(&self, data: DevToolsExport) {
597 let mut metrics = self.metrics.write();
598 let mut network = self.network_history.write();
599 let mut cache = self.cache_history.write();
600 let mut events = self.event_history.write();
601
602 for metric in data.query_metrics {
604 metrics.insert(metric.key.clone(), metric);
605 }
606
607 network.extend(data.network_requests);
609
610 cache.extend(data.cache_operations);
612
613 events.extend(data.event_history);
615 }
616}
617
618#[derive(Debug, Clone, Serialize, Deserialize)]
620pub struct ActiveQuery {
621 pub key: QueryKey,
623 #[serde(with = "duration_serde")]
625 pub duration: Duration,
626}
627
628#[derive(Debug, Clone, Serialize, Deserialize)]
630pub struct DevToolsExport {
631 pub query_metrics: Vec<QueryMetrics>,
633 pub network_requests: Vec<NetworkRequest>,
635 pub cache_operations: Vec<CacheOperation>,
637 pub event_history: Vec<DevToolsEvent>,
639 pub active_queries: Vec<ActiveQuery>,
641 pub timestamp: u64,
643}
644
645pub struct DevToolsServer {
647 #[allow(dead_code)]
649 manager: Arc<DevToolsManager>,
650 #[allow(dead_code)]
652 config: DevToolsConfig,
653}
654
655impl DevToolsServer {
656 pub fn new(manager: Arc<DevToolsManager>, config: DevToolsConfig) -> Self {
658 Self { manager, config }
659 }
660
661 pub async fn start(&self) -> Result<(), Box<dyn std::error::Error>> {
663 Ok(())
666 }
667
668 pub async fn stop(&self) -> Result<(), Box<dyn std::error::Error>> {
670 Ok(())
671 }
672
673 pub fn port(&self) -> u16 {
674 3001 }
676
677 pub fn host(&self) -> &str {
678 "localhost" }
680}
681
682#[derive(Debug, Clone, Serialize, Deserialize)]
684pub struct PerformanceStats {
685 pub total_queries: usize,
686 pub average_response_time: Duration,
687 pub max_response_time: Duration,
688 pub min_response_time: Duration,
689}
690
691#[derive(Debug, Clone, Serialize, Deserialize)]
693pub struct ErrorStats {
694 pub total_errors: usize,
695 pub error_rate: f64,
696}
697
698#[cfg(test)]
699mod tests {
700 use super::*;
701 use crate::types::QueryKey;
702
703 #[test]
704 fn test_devtools_manager_creation() {
705 let config = DevToolsConfig::default();
706 let manager = DevToolsManager::new(config);
707
708 let key = QueryKey::new(&["test"]);
709 assert!(manager.get_query_metrics(&key).is_none());
710 assert_eq!(manager.get_network_history().len(), 0);
711 assert_eq!(manager.get_cache_history().len(), 0);
712 }
713
714 #[test]
715 fn test_query_metrics_recording() {
716 let config = DevToolsConfig::default();
717 let manager = DevToolsManager::new(config);
718
719 let key = QueryKey::from("test");
720 manager.record_query_start(&key);
721 manager.record_query_complete(&key, true, Duration::from_millis(100));
722
723 let metrics = manager.get_query_metrics(&key);
724 assert!(metrics.is_some());
725 let metrics = metrics.unwrap();
726 assert_eq!(metrics.execution_count, 1);
727 assert_eq!(metrics.success_count, 1);
728 }
729
730 #[test]
731 fn test_network_request_recording() {
732 let config = DevToolsConfig::default();
733 let manager = DevToolsManager::new(config);
734
735 let key = QueryKey::from("test");
736 let request = NetworkRequest::new(key, "https://api.example.com/data".to_string(), "GET".to_string());
737 let key = QueryKey::new(&["test"]);
738 manager.record_network_request(&key, request);
739
740 let history = manager.get_network_history();
741 assert_eq!(history.len(), 1);
742 assert_eq!(history[0].method, "GET");
743 }
744
745 #[test]
746 fn test_cache_operation_recording() {
747 let config = DevToolsConfig::default();
748 let manager = DevToolsManager::new(config);
749
750 let key = QueryKey::from("test");
751 let operation = CacheOperation::Set {
752 key: key.clone(),
753 size: 1024,
754 timestamp: Instant::now(),
755 };
756 let key = QueryKey::new(&["test"]);
757 manager.record_cache_operation(operation, &key, None::<&String>);
758
759 let history = manager.get_cache_history();
760 assert_eq!(history.len(), 1);
761 }
762
763 #[test]
764 fn test_history_limits() {
765 let mut config = DevToolsConfig::default();
766 config.max_history = 5;
767 let manager = DevToolsManager::new(config);
768
769 for i in 0..10 {
771 let key = QueryKey::from(format!("test{}", i));
772 manager.record_query_start(&key);
773 }
774
775 let events = manager.get_event_history();
777 assert_eq!(events.len(), 5);
778 }
779
780 #[test]
781 fn test_export_import() {
782 let config = DevToolsConfig::default();
783 let manager = DevToolsManager::new(config);
784
785 let key = QueryKey::from("test");
786 manager.record_query_start(&key);
787 manager.record_query_complete(&key, true, Duration::from_millis(100));
788
789 let export = manager.export_data();
790 assert_eq!(export.query_metrics.len(), 1);
791
792 manager.clear_history();
794 let key = QueryKey::new(&["test"]);
795 assert!(manager.get_query_metrics(&key).is_none());
796
797 manager.import_data(export);
798 let key = QueryKey::new(&["test"]);
799 assert!(manager.get_query_metrics(&key).is_some());
800 }
801}
802
803mod instant_serde {
805 use serde::{Deserialize, Deserializer, Serialize, Serializer};
806 use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
807
808 pub fn serialize<S>(instant: &Instant, serializer: S) -> Result<S::Ok, S::Error>
809 where
810 S: Serializer,
811 {
812 let system_time = SystemTime::now() - instant.elapsed();
814 let duration = system_time.duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO);
815 duration.serialize(serializer)
816 }
817
818 pub fn deserialize<'de, D>(deserializer: D) -> Result<Instant, D::Error>
819 where
820 D: Deserializer<'de>,
821 {
822 let duration = Duration::deserialize(deserializer)?;
823 let system_time = UNIX_EPOCH + duration;
824 let now = SystemTime::now();
825 let elapsed = now.duration_since(system_time).unwrap_or(Duration::ZERO);
826 Ok(Instant::now() - elapsed)
827 }
828}
829
830mod duration_serde {
832 use serde::{Deserialize, Deserializer, Serialize, Serializer};
833 use std::time::Duration;
834
835 pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
836 where
837 S: Serializer,
838 {
839 duration.as_secs().serialize(serializer)
840 }
841
842 pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
843 where
844 D: Deserializer<'de>,
845 {
846 let secs = u64::deserialize(deserializer)?;
847 Ok(Duration::from_secs(secs))
848 }
849}
850
851mod option_duration_serde {
853 use serde::{Deserialize, Deserializer, Serialize, Serializer};
854 use std::time::Duration;
855
856 pub fn serialize<S>(duration: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
857 where
858 S: Serializer,
859 {
860 match duration {
861 Some(d) => d.as_secs().serialize(serializer),
862 None => serializer.serialize_none(),
863 }
864 }
865
866 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
867 where
868 D: Deserializer<'de>,
869 {
870 let secs = Option::<u64>::deserialize(deserializer)?;
871 Ok(secs.map(Duration::from_secs))
872 }
873}
874
875mod option_instant_serde {
877 use serde::{Deserialize, Deserializer, Serialize, Serializer};
878 use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
879
880 pub fn serialize<S>(instant: &Option<Instant>, serializer: S) -> Result<S::Ok, S::Error>
881 where
882 S: Serializer,
883 {
884 match instant {
885 Some(inst) => {
886 let system_time = SystemTime::now() - inst.elapsed();
887 let duration = system_time.duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO);
888 duration.serialize(serializer)
889 }
890 None => serializer.serialize_none(),
891 }
892 }
893
894 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Instant>, D::Error>
895 where
896 D: Deserializer<'de>,
897 {
898 let duration = Option::<Duration>::deserialize(deserializer)?;
899 Ok(duration.map(|d| {
900 let system_time = UNIX_EPOCH + d;
901 let now = SystemTime::now();
902 let elapsed = now.duration_since(system_time).unwrap_or(Duration::ZERO);
903 Instant::now() - elapsed
904 }))
905 }
906}