1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env rust
//! Tweeter archives as of 2023-08-31 have private data found under;
//!
//! twitter-<DATE>-<UID>.zip:data/following.js
//!
//! ## Example file reader
//!
//! ```no_build
//! use std::io::Read;
//! use std::{fs, path};
//! use zip::read::ZipArchive;
//!
//! use twitter_archive::structs::following;
//!
//! fn main() {
//! let input_file = "~/Downloads/twitter-archive.zip";
//!
//! let file_descriptor = fs::File::open(input_file).expect("Unable to read --input-file");
//! let mut zip_archive = ZipArchive::new(file_descriptor).unwrap();
//! let mut zip_file = zip_archive.by_name("data/following.js").unwrap();
//! let mut buff = String::new();
//! zip_file.read_to_string(&mut buff).unwrap();
//!
//! let json = buff.replacen("window.YTD.following.part0 = ", "", 1);
//! let data: Vec<following::FollowingObject> = serde_json::from_str(&json).expect("Unable to parse");
//!
//! for (index, object) in data.iter().enumerate() {
//! /* Do stuff with each `RegisteredDevices` entry */
//! println!("IP audit index: {index}");
//! println!("Account ID: {}", object.following.account_id);
//! println!("User link: {}", object.following.user_link);
//! }
//! }
//! ```
//!
//! ## Example `twitter-<DATE>-<UID>.zip:data/following.js` content
//!
//! ```javascript
//! window.YTD.following.part0 = [
//! {
//! "following" : {
//! "accountId" : "1111111111111111111",
//! "userLink" : "https://twitter.com/intent/user?user_id=1111111111111111111"
//! }
//! }
//! ]
//! ```
use Display;
use ;
use crateFollow;
/// ## Example
///
/// ```
/// use twitter_archive::structs::following::FollowingObject;
///
/// let json = r#"{
/// "following": {
/// "accountId": "1111111111111111111",
/// "userLink": "https://twitter.com/intent/user?user_id=1111111111111111111"
/// }
/// }"#;
///
/// let data: FollowingObject = serde_json::from_str(&json).unwrap();
///
/// // De-serialized properties
/// assert_eq!(data.following.account_id, "1111111111111111111");
/// assert_eq!(data.following.user_link, "https://twitter.com/intent/user?user_id=1111111111111111111");
///
/// // Re-serialize is equivalent to original data
/// assert_eq!(serde_json::to_string_pretty(&data).unwrap(), json);
/// ```