Chrome tabs & session snss file reading
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Convert from chrono to jiff timestamp library

rektide 13952941 6a8723ea

+111 -155
+57 -129
Cargo.lock
··· 12 12 ] 13 13 14 14 [[package]] 15 - name = "android_system_properties" 16 - version = "0.1.5" 17 - source = "registry+https://github.com/rust-lang/crates.io-index" 18 - checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 19 - dependencies = [ 20 - "libc", 21 - ] 22 - 23 - [[package]] 24 15 name = "anes" 25 16 version = "0.1.6" 26 17 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 81 72 checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" 82 73 83 74 [[package]] 84 - name = "cc" 85 - version = "1.2.50" 86 - source = "registry+https://github.com/rust-lang/crates.io-index" 87 - checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" 88 - dependencies = [ 89 - "find-msvc-tools", 90 - "shlex", 91 - ] 92 - 93 - [[package]] 94 75 name = "cfg-if" 95 76 version = "1.0.4" 96 77 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 103 84 checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 104 85 105 86 [[package]] 106 - name = "chrono" 107 - version = "0.4.42" 108 - source = "registry+https://github.com/rust-lang/crates.io-index" 109 - checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" 110 - dependencies = [ 111 - "iana-time-zone", 112 - "js-sys", 113 - "num-traits", 114 - "serde", 115 - "wasm-bindgen", 116 - "windows-link", 117 - ] 118 - 119 - [[package]] 120 87 name = "ciborium" 121 88 version = "0.2.2" 122 89 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 321 288 ] 322 289 323 290 [[package]] 324 - name = "core-foundation-sys" 325 - version = "0.8.7" 326 - source = "registry+https://github.com/rust-lang/crates.io-index" 327 - checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 328 - 329 - [[package]] 330 291 name = "core_affinity" 331 292 version = "0.8.3" 332 293 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 436 397 ] 437 398 438 399 [[package]] 439 - name = "find-msvc-tools" 440 - version = "0.1.5" 441 - source = "registry+https://github.com/rust-lang/crates.io-index" 442 - checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" 443 - 444 - [[package]] 445 400 name = "flume" 446 401 version = "0.11.1" 447 402 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 518 473 checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" 519 474 520 475 [[package]] 521 - name = "iana-time-zone" 522 - version = "0.1.64" 523 - source = "registry+https://github.com/rust-lang/crates.io-index" 524 - checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" 525 - dependencies = [ 526 - "android_system_properties", 527 - "core-foundation-sys", 528 - "iana-time-zone-haiku", 529 - "js-sys", 530 - "log", 531 - "wasm-bindgen", 532 - "windows-core", 533 - ] 534 - 535 - [[package]] 536 - name = "iana-time-zone-haiku" 537 - version = "0.1.2" 538 - source = "registry+https://github.com/rust-lang/crates.io-index" 539 - checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 540 - dependencies = [ 541 - "cc", 542 - ] 543 - 544 - [[package]] 545 476 name = "indexmap" 546 477 version = "2.12.1" 547 478 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 600 531 checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" 601 532 602 533 [[package]] 534 + name = "jiff" 535 + version = "0.2.18" 536 + source = "registry+https://github.com/rust-lang/crates.io-index" 537 + checksum = "e67e8da4c49d6d9909fe03361f9b620f58898859f5c7aded68351e85e71ecf50" 538 + dependencies = [ 539 + "jiff-static", 540 + "jiff-tzdb-platform", 541 + "log", 542 + "portable-atomic", 543 + "portable-atomic-util", 544 + "serde_core", 545 + "windows-sys 0.61.2", 546 + ] 547 + 548 + [[package]] 549 + name = "jiff-static" 550 + version = "0.2.18" 551 + source = "registry+https://github.com/rust-lang/crates.io-index" 552 + checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78" 553 + dependencies = [ 554 + "proc-macro2", 555 + "quote", 556 + "syn", 557 + ] 558 + 559 + [[package]] 560 + name = "jiff-tzdb" 561 + version = "0.1.5" 562 + source = "registry+https://github.com/rust-lang/crates.io-index" 563 + checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2" 564 + 565 + [[package]] 566 + name = "jiff-tzdb-platform" 567 + version = "0.1.3" 568 + source = "registry+https://github.com/rust-lang/crates.io-index" 569 + checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" 570 + dependencies = [ 571 + "jiff-tzdb", 572 + ] 573 + 574 + [[package]] 603 575 name = "js-sys" 604 576 version = "0.3.83" 605 577 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 744 716 ] 745 717 746 718 [[package]] 719 + name = "portable-atomic" 720 + version = "1.13.1" 721 + source = "registry+https://github.com/rust-lang/crates.io-index" 722 + checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" 723 + 724 + [[package]] 725 + name = "portable-atomic-util" 726 + version = "0.2.5" 727 + source = "registry+https://github.com/rust-lang/crates.io-index" 728 + checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" 729 + dependencies = [ 730 + "portable-atomic", 731 + ] 732 + 733 + [[package]] 747 734 name = "proc-macro-crate" 748 735 version = "3.4.0" 749 736 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 824 811 version = "0.1.0" 825 812 dependencies = [ 826 813 "byteorder", 827 - "chrono", 828 814 "compio", 829 815 "criterion", 830 816 "futures-util", 817 + "jiff", 831 818 "serde", 832 819 "serde_json", 833 820 ] ··· 920 907 "serde", 921 908 "serde_core", 922 909 ] 923 - 924 - [[package]] 925 - name = "shlex" 926 - version = "1.3.0" 927 - source = "registry+https://github.com/rust-lang/crates.io-index" 928 - checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 929 910 930 911 [[package]] 931 912 name = "slab" ··· 1128 1109 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1129 1110 1130 1111 [[package]] 1131 - name = "windows-core" 1132 - version = "0.62.2" 1133 - source = "registry+https://github.com/rust-lang/crates.io-index" 1134 - checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" 1135 - dependencies = [ 1136 - "windows-implement", 1137 - "windows-interface", 1138 - "windows-link", 1139 - "windows-result", 1140 - "windows-strings", 1141 - ] 1142 - 1143 - [[package]] 1144 - name = "windows-implement" 1145 - version = "0.60.2" 1146 - source = "registry+https://github.com/rust-lang/crates.io-index" 1147 - checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" 1148 - dependencies = [ 1149 - "proc-macro2", 1150 - "quote", 1151 - "syn", 1152 - ] 1153 - 1154 - [[package]] 1155 - name = "windows-interface" 1156 - version = "0.59.3" 1157 - source = "registry+https://github.com/rust-lang/crates.io-index" 1158 - checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" 1159 - dependencies = [ 1160 - "proc-macro2", 1161 - "quote", 1162 - "syn", 1163 - ] 1164 - 1165 - [[package]] 1166 1112 name = "windows-link" 1167 1113 version = "0.2.1" 1168 1114 source = "registry+https://github.com/rust-lang/crates.io-index" 1169 1115 checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 1170 - 1171 - [[package]] 1172 - name = "windows-result" 1173 - version = "0.4.1" 1174 - source = "registry+https://github.com/rust-lang/crates.io-index" 1175 - checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" 1176 - dependencies = [ 1177 - "windows-link", 1178 - ] 1179 - 1180 - [[package]] 1181 - name = "windows-strings" 1182 - version = "0.5.1" 1183 - source = "registry+https://github.com/rust-lang/crates.io-index" 1184 - checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" 1185 - dependencies = [ 1186 - "windows-link", 1187 - ] 1188 1116 1189 1117 [[package]] 1190 1118 name = "windows-sys"
+1 -1
Cargo.toml
··· 14 14 byteorder = "1.4" 15 15 serde = { version = "1.0", features = ["derive"] } 16 16 serde_json = "1.0" 17 - chrono = { version = "0.4", features = ["serde"] } 17 + jiff = { version = "0.2", features = ["serde"] } 18 18 19 19 [dev-dependencies] 20 20 criterion = "0.5"
+6 -4
src/command/pickle.rs
··· 1 1 use crate::common::{SnssError, Token}; 2 2 use crate::u16_convert::bytes_to_u16_le; 3 3 use byteorder::{LittleEndian, ReadBytesExt}; 4 - use chrono::{DateTime, TimeDelta, Utc}; 4 + use jiff::{Span, Timestamp, Zoned}; 5 5 use std::io::{Cursor, Read, Seek, SeekFrom}; 6 6 7 7 /// Reader for Chrome Pickle format ··· 87 87 String::from_utf16(&u16_data).map_err(|e| SnssError::PickleError(e.to_string())) 88 88 } 89 89 90 - pub fn read_datetime(&mut self) -> Result<DateTime<Utc>, SnssError> { 90 + pub fn read_datetime(&mut self) -> Result<Zoned, SnssError> { 91 91 let micros = self.read_uint64()?; 92 - let base = DateTime::from_timestamp(-11644473600, 0).unwrap(); // 1601-01-01 93 - Ok(base + TimeDelta::microseconds(micros as i64)) 92 + let base = Timestamp::from_second(-11644473600).unwrap(); // 1601-01-01 93 + let span = Span::new().microseconds(micros as i64); 94 + let timestamp = base.checked_add(span).unwrap(); 95 + Ok(timestamp.to_zoned(jiff::tz::TimeZone::UTC)) 94 96 } 95 97 96 98 pub fn read_token(&mut self) -> Result<Token, SnssError> {
+15 -7
src/command/session.rs
··· 2 2 use crate::common::NavigationEntry; 3 3 use crate::common::{TabGroupColor, Token, WindowShowState, WindowType}; 4 4 use byteorder::{ByteOrder, LittleEndian}; 5 - use chrono::{DateTime, TimeDelta, Utc}; 5 + use jiff::{Span, Timestamp, Zoned}; 6 6 use serde::Serialize; 7 7 use std::collections::HashMap; 8 8 ··· 74 74 #[derive(Debug, Serialize)] 75 75 pub struct ClosedPayload { 76 76 pub id: i32, 77 - pub close_time: DateTime<Utc>, 77 + pub close_time: Zoned, 78 78 } 79 79 80 80 #[derive(Debug, Serialize)] ··· 86 86 #[derive(Debug, Serialize)] 87 87 pub struct LastActiveTime { 88 88 pub tab_id: i32, 89 - pub last_active_time: DateTime<Utc>, 89 + pub last_active_time: Zoned, 90 90 } 91 91 92 92 #[derive(Debug, Serialize)] ··· 464 464 } 465 465 let id = LittleEndian::read_i32(&data[0..4]); 466 466 let close_time_micros = LittleEndian::read_i64(&data[4..12]); 467 - let base = DateTime::from_timestamp(-11644473600, 0).unwrap(); 468 - let close_time = base + TimeDelta::microseconds(close_time_micros); 467 + let base = Timestamp::from_second(-11644473600).unwrap(); 468 + let span = Span::new().microseconds(close_time_micros); 469 + let close_time = base 470 + .checked_add(span) 471 + .unwrap() 472 + .to_zoned(jiff::tz::TimeZone::UTC); 469 473 let payload = ClosedPayload { id, close_time }; 470 474 if is_tab { 471 475 SnssCommand::TabClosed(payload) ··· 603 607 } 604 608 let tab_id = LittleEndian::read_i32(&data[0..4]); 605 609 let time_micros = LittleEndian::read_i64(&data[4..12]); 606 - let base = DateTime::from_timestamp(-11644473600, 0).unwrap(); 607 - let last_active_time = base + TimeDelta::microseconds(time_micros); 610 + let base = Timestamp::from_second(-11644473600).unwrap(); 611 + let span = Span::new().microseconds(time_micros); 612 + let last_active_time = base 613 + .checked_add(span) 614 + .unwrap() 615 + .to_zoned(jiff::tz::TimeZone::UTC); 608 616 SnssCommand::LastActiveTime(LastActiveTime { 609 617 tab_id, 610 618 last_active_time,
+30 -12
src/command/tab.rs
··· 2 2 use crate::common::NavigationEntry; 3 3 use crate::common::{TabGroupColor, Token, WindowShowState, WindowType}; 4 4 use byteorder::{ByteOrder, LittleEndian}; 5 - use chrono::{DateTime, TimeDelta, Utc}; 5 + use jiff::{Span, Timestamp, Zoned}; 6 6 use serde::Serialize; 7 7 8 8 /// Command IDs from Chromium's tab_restore_service_impl.cc (for Tabs_* files) ··· 32 32 pub struct SelectedNavigationInTab { 33 33 pub tab_id: i32, 34 34 pub index: i32, 35 - pub timestamp: Option<DateTime<Utc>>, 35 + pub timestamp: Option<Zoned>, 36 36 } 37 37 38 38 #[derive(Debug, Serialize)] ··· 40 40 pub window_id: i32, 41 41 pub selected_tab_index: i32, 42 42 pub num_tabs: i32, 43 - pub timestamp: Option<DateTime<Utc>>, 43 + pub timestamp: Option<Zoned>, 44 44 pub x: Option<i32>, 45 45 pub y: Option<i32>, 46 46 pub width: Option<i32>, ··· 58 58 pub browser_id: i32, 59 59 pub title: String, 60 60 pub color: TabGroupColor, 61 - pub timestamp: Option<DateTime<Utc>>, 61 + pub timestamp: Option<Zoned>, 62 62 pub is_saved: bool, 63 63 pub saved_id: Option<String>, 64 64 } ··· 151 151 let index = LittleEndian::read_i32(&data[4..8]); 152 152 let timestamp = if data.len() >= 16 { 153 153 let time_micros = LittleEndian::read_i64(&data[8..16]); 154 - let base = DateTime::from_timestamp(-11644473600, 0).unwrap(); 155 - Some(base + TimeDelta::microseconds(time_micros)) 154 + let base = Timestamp::from_second(-11644473600).unwrap(); 155 + let span = Span::new().microseconds(time_micros); 156 + Some( 157 + base.checked_add(span) 158 + .unwrap() 159 + .to_zoned(jiff::tz::TimeZone::UTC), 160 + ) 156 161 } else { 157 162 None 158 163 }; ··· 175 180 let num_tabs = LittleEndian::read_i32(&data[8..12]); 176 181 let timestamp = if data.len() >= 20 { 177 182 let time_micros = LittleEndian::read_i64(&data[12..20]); 178 - let base = DateTime::from_timestamp(-11644473600, 0).unwrap(); 179 - Some(base + TimeDelta::microseconds(time_micros)) 183 + let base = Timestamp::from_second(-11644473600).unwrap(); 184 + let span = Span::new().microseconds(time_micros); 185 + Some( 186 + base.checked_add(span) 187 + .unwrap() 188 + .to_zoned(jiff::tz::TimeZone::UTC), 189 + ) 180 190 } else { 181 191 None 182 192 }; ··· 220 230 pickle.read_int32(), 221 231 pickle.read_string(), 222 232 ) { 223 - let base = DateTime::from_timestamp(-11644473600, 0).unwrap(); 224 - let timestamp = Some(base + TimeDelta::microseconds(timestamp_raw)); 233 + let base = Timestamp::from_second(-11644473600).unwrap(); 234 + let span = Span::new().microseconds(timestamp_raw); 235 + let timestamp = Some( 236 + base.checked_add(span) 237 + .unwrap() 238 + .to_zoned(jiff::tz::TimeZone::UTC), 239 + ); 225 240 let show_state = Some(match show_state_int { 226 241 1 => WindowShowState::Normal, 227 242 2 => WindowShowState::Minimized, ··· 387 402 None 388 403 }; 389 404 let timestamp = pickle.read_int64().ok().map(|t| { 390 - let base = DateTime::from_timestamp(-11644473600, 0).unwrap(); 391 - base + TimeDelta::microseconds(t) 405 + let base = Timestamp::from_second(-11644473600).unwrap(); 406 + let span = Span::new().microseconds(t); 407 + base.checked_add(span) 408 + .unwrap() 409 + .to_zoned(jiff::tz::TimeZone::UTC) 392 410 }); 393 411 return TabRestoreCommand::CreateGroup(TabRestoreGroup { 394 412 group_token,
+2 -2
src/common.rs
··· 1 - use chrono::{DateTime, Utc}; 1 + use jiff::Zoned; 2 2 use serde::Serialize; 3 3 use std::collections::HashMap; 4 4 ··· 147 147 pub referrer_url: Option<String>, 148 148 pub original_request_url: Option<String>, 149 149 pub is_overriding_user_agent: Option<bool>, 150 - pub timestamp: Option<DateTime<Utc>>, 150 + pub timestamp: Option<Zoned>, 151 151 pub http_status: Option<i32>, 152 152 pub referrer_policy: Option<i32>, 153 153 pub extended_map: Option<HashMap<String, String>>,