about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2018-08-30 20:43:23 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2018-08-30 20:43:23 -0400
commit8584857578c3a2946a03de98ff3803431143297a (patch)
treee3cb3d9487a7b72a22e5dd50d91011d966a4ee15 /src
parenta9d33aa08df10102539e33c0c6d4334e9e99a470 (diff)
downloadlibtwittercpp-8584857578c3a2946a03de98ff3803431143297a.tar.gz
libtwittercpp-8584857578c3a2946a03de98ff3803431143297a.tar.bz2
libtwittercpp-8584857578c3a2946a03de98ff3803431143297a.zip
Refactored tweet and user classes
The only API-visible change is that these classes are no longer default constructible. Other than that, tweet now uses hatkirby::recptr to wrap its retweeted_status (tweet) and author (user) member objects, removing the need to implement the Rule of Five.
Diffstat (limited to 'src')
-rw-r--r--src/tweet.cpp101
-rw-r--r--src/tweet.h122
-rw-r--r--src/user.cpp31
-rw-r--r--src/user.h94
4 files changed, 138 insertions, 210 deletions
diff --git a/src/tweet.cpp b/src/tweet.cpp index 1003647..7f10a5c 100644 --- a/src/tweet.cpp +++ b/src/tweet.cpp
@@ -7,83 +7,48 @@
7 7
8namespace twitter { 8namespace twitter {
9 9
10 tweet::tweet(std::string data) try 10 tweet::tweet(std::string data)
11 : _valid(true)
12 { 11 {
13 auto json = nlohmann::json::parse(data); 12 try
14 _id = json["id"].get<tweet_id>();
15 _text = json["text"].get<std::string>();
16 _author = std::make_unique<user>(json["user"].dump());
17
18 std::tm ctt = { 0 };
19 std::stringstream createdAtStream;
20 createdAtStream << json["created_at"].get<std::string>();
21 createdAtStream >> std::get_time(&ctt, "%a %b %d %H:%M:%S +0000 %Y");
22 _created_at = twitter::timegm(&ctt);
23
24 if (!json["retweeted_status"].is_null())
25 { 13 {
26 _is_retweet = true; 14 auto json = nlohmann::json::parse(data);
15 _id = json["id"].get<tweet_id>();
16 _text = json["text"].get<std::string>();
17 _author = new user(json["user"].dump());
18
19 std::tm ctt = { 0 };
20 std::stringstream createdAtStream;
21 createdAtStream << json["created_at"].get<std::string>();
22 createdAtStream >> std::get_time(&ctt, "%a %b %d %H:%M:%S +0000 %Y");
23 _created_at = twitter::timegm(&ctt);
24
25 if (!json["retweeted_status"].is_null())
26 {
27 _is_retweet = true;
27 28
28 _retweeted_status = std::make_unique<tweet>(json["retweeted_status"].dump()); 29 _retweeted_status = new tweet(json["retweeted_status"].dump());
29 } 30 }
30 31
31 if (!json["entities"].is_null()) 32 if (!json["entities"].is_null())
32 {
33 auto entities = json["entities"];
34 if (!entities["user_mentions"].is_null())
35 { 33 {
36 for (auto mention : entities["user_mentions"]) 34 auto entities = json["entities"];
35 if (!entities["user_mentions"].is_null())
37 { 36 {
38 _mentions.push_back(std::make_pair(mention["id"].get<user_id>(), mention["screen_name"].get<std::string>())); 37 for (auto mention : entities["user_mentions"])
38 {
39 _mentions.emplace_back(
40 mention["id"].get<user_id>(),
41 mention["screen_name"].get<std::string>());
42 }
39 } 43 }
40 } 44 }
41 } 45 } catch (const std::invalid_argument& error)
42 } catch (const std::invalid_argument& error)
43 {
44 std::throw_with_nested(malformed_object("tweet", data));
45 } catch (const std::domain_error& error)
46 {
47 std::throw_with_nested(malformed_object("tweet", data));
48 }
49
50 tweet::tweet(const tweet& other)
51 {
52 _valid = other._valid;
53 _id = other._id;
54 _text = other._text;
55 _author = std::make_unique<user>(*other._author);
56 _is_retweet = other._is_retweet;
57
58 if (_is_retweet)
59 { 46 {
60 _retweeted_status = std::make_unique<tweet>(*other._retweeted_status); 47 std::throw_with_nested(malformed_object("tweet", data));
48 } catch (const std::domain_error& error)
49 {
50 std::throw_with_nested(malformed_object("tweet", data));
61 } 51 }
62
63 _mentions = other._mentions;
64 }
65
66 tweet::tweet(tweet&& other) : tweet()
67 {
68 swap(*this, other);
69 }
70
71 tweet& tweet::operator=(tweet other)
72 {
73 swap(*this, other);
74
75 return *this;
76 }
77
78 void swap(tweet& first, tweet& second)
79 {
80 std::swap(first._valid, second._valid);
81 std::swap(first._id, second._id);
82 std::swap(first._text, second._text);
83 std::swap(first._author, second._author);
84 std::swap(first._is_retweet, second._is_retweet);
85 std::swap(first._retweeted_status, second._retweeted_status);
86 std::swap(first._mentions, second._mentions);
87 } 52 }
88 53
89 std::string tweet::generateReplyPrefill(const user& me) const 54 std::string tweet::generateReplyPrefill(const user& me) const
@@ -104,8 +69,6 @@ namespace twitter {
104 69
105 std::string tweet::getURL() const 70 std::string tweet::getURL() const
106 { 71 {
107 assert(_valid);
108
109 std::ostringstream urlstr; 72 std::ostringstream urlstr;
110 urlstr << "https://twitter.com/"; 73 urlstr << "https://twitter.com/";
111 urlstr << _author->getScreenName(); 74 urlstr << _author->getScreenName();
diff --git a/src/tweet.h b/src/tweet.h index 71a27bd..23882e2 100644 --- a/src/tweet.h +++ b/src/tweet.h
@@ -4,94 +4,72 @@
4#include <string> 4#include <string>
5#include <vector> 5#include <vector>
6#include <utility> 6#include <utility>
7#include <cassert>
8#include <list>
9#include <memory>
10#include <ctime> 7#include <ctime>
8#include "../vendor/hkutil/hkutil/recptr.h"
11#include "user.h" 9#include "user.h"
12 10
13namespace twitter { 11namespace twitter {
14 12
15 class client;
16
17 typedef unsigned long long tweet_id; 13 typedef unsigned long long tweet_id;
18 14
19 class tweet { 15 class tweet {
20 public: 16 public:
21 17
22 tweet() {} 18 tweet(std::string data);
23 tweet(std::string data); 19
24 20 tweet_id getID() const
25 tweet(const tweet& other); 21 {
26 tweet(tweet&& other); 22 return _id;
27 23 }
28 tweet& operator=(tweet other); 24
29 25 std::string getText() const
30 friend void swap(tweet& first, tweet& second); 26 {
31 27 return _text;
32 tweet_id getID() const 28 }
29
30 const user& getAuthor() const
31 {
32 return *_author;
33 }
34
35 const std::time_t& getCreatedAt() const
36 {
37 return _created_at;
38 }
39
40 bool isRetweet() const
41 {
42 return _is_retweet;
43 }
44
45 const tweet& getRetweet() const
46 {
47 if (!_is_retweet)
33 { 48 {
34 assert(_valid); 49 throw std::logic_error("Tweet is not a retweet");
35
36 return _id;
37 } 50 }
38 51
39 std::string getText() const 52 return *_retweeted_status;
40 { 53 }
41 assert(_valid);
42 54
43 return _text; 55 const std::vector<std::pair<user_id, std::string>>& getMentions() const
44 } 56 {
45 57 return _mentions;
46 const user& getAuthor() const 58 }
47 {
48 assert(_valid);
49
50 return *_author;
51 }
52
53 const std::time_t& getCreatedAt() const
54 {
55 assert(_valid);
56
57 return _created_at;
58 }
59
60 bool isRetweet() const
61 {
62 assert(_valid);
63
64 return _is_retweet;
65 }
66
67 const tweet& getRetweet() const
68 {
69 assert(_valid && _is_retweet);
70
71 return *_retweeted_status;
72 }
73
74 const std::vector<std::pair<user_id, std::string>>& getMentions() const
75 {
76 assert(_valid);
77
78 return _mentions;
79 }
80 59
81 std::string generateReplyPrefill(const user& me) const; 60 std::string generateReplyPrefill(const user& me) const;
82 61
83 std::string getURL() const; 62 std::string getURL() const;
84 63
85 private: 64 private:
86 65
87 bool _valid = false; 66 tweet_id _id;
88 tweet_id _id; 67 std::string _text;
89 std::string _text; 68 hatkirby::recptr<user> _author;
90 std::unique_ptr<user> _author; 69 std::time_t _created_at;
91 std::time_t _created_at; 70 bool _is_retweet = false;
92 bool _is_retweet = false; 71 hatkirby::recptr<tweet> _retweeted_status;
93 std::unique_ptr<tweet> _retweeted_status; 72 std::vector<std::pair<user_id, std::string>> _mentions;
94 std::vector<std::pair<user_id, std::string>> _mentions;
95 }; 73 };
96 74
97}; 75};
diff --git a/src/user.cpp b/src/user.cpp index d2fa592..8109123 100644 --- a/src/user.cpp +++ b/src/user.cpp
@@ -1,24 +1,25 @@
1#include "user.h" 1#include "user.h"
2#include <json.hpp> 2#include <json.hpp>
3#include "codes.h" 3#include "codes.h"
4#include "client.h"
5 4
6namespace twitter { 5namespace twitter {
7 6
8 user::user(std::string data) try 7 user::user(std::string data)
9 : _valid(true)
10 { 8 {
11 auto json = nlohmann::json::parse(data); 9 try
12 _id = json["id"].get<user_id>(); 10 {
13 _screen_name = json["screen_name"].get<std::string>(); 11 auto json = nlohmann::json::parse(data);
14 _name = json["name"].get<std::string>(); 12 _id = json["id"].get<user_id>();
15 _protected = json["protected"].get<bool>(); 13 _screen_name = json["screen_name"].get<std::string>();
16 } catch (const std::invalid_argument& error) 14 _name = json["name"].get<std::string>();
17 { 15 _protected = json["protected"].get<bool>();
18 std::throw_with_nested(malformed_object("user", data)); 16 } catch (const std::invalid_argument& error)
19 } catch (const std::domain_error& error) 17 {
20 { 18 std::throw_with_nested(malformed_object("user", data));
21 std::throw_with_nested(malformed_object("user", data)); 19 } catch (const std::domain_error& error)
20 {
21 std::throw_with_nested(malformed_object("user", data));
22 }
22 } 23 }
23 24
24}; 25}
diff --git a/src/user.h b/src/user.h index acd62d0..b743074 100644 --- a/src/user.h +++ b/src/user.h
@@ -2,66 +2,52 @@
2#define USER_H_BF3AB38C 2#define USER_H_BF3AB38C
3 3
4#include <string> 4#include <string>
5#include <set>
6#include <cassert>
7 5
8namespace twitter { 6namespace twitter {
9 7
10 class client;
11
12 typedef unsigned long long user_id; 8 typedef unsigned long long user_id;
13 9
14 class user { 10 class user {
15 public: 11 public:
16 12
17 user() {} 13 user(std::string data);
18 user(std::string data); 14
19 15 user_id getID() const
20 user_id getID() const 16 {
21 { 17 return _id;
22 assert(_valid); 18 }
23 19
24 return _id; 20 std::string getScreenName() const
25 } 21 {
26 22 return _screen_name;
27 std::string getScreenName() const 23 }
28 { 24
29 assert(_valid); 25 std::string getName() const
30 26 {
31 return _screen_name; 27 return _name;
32 } 28 }
33 29
34 std::string getName() const 30 bool isProtected() const
35 { 31 {
36 assert(_valid); 32 return _protected;
37 33 }
38 return _name; 34
39 } 35 bool operator==(const user& other) const
40 36 {
41 bool isProtected() const 37 return _id == other._id;
42 { 38 }
43 assert(_valid); 39
44 40 bool operator!=(const user& other) const
45 return _protected; 41 {
46 } 42 return _id != other._id;
47 43 }
48 bool operator==(const user& other) const 44
49 { 45 private:
50 return _id == other._id; 46
51 } 47 user_id _id;
52 48 std::string _screen_name;
53 bool operator!=(const user& other) const 49 std::string _name;
54 { 50 bool _protected = false;
55 return _id != other._id;
56 }
57
58 private:
59
60 bool _valid = false;
61 user_id _id;
62 std::string _screen_name;
63 std::string _name;
64 bool _protected = false;
65 }; 51 };
66 52
67}; 53};