diff options
Diffstat (limited to 'src/schema.rs')
-rw-r--r-- | src/schema.rs | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..ea36a70 --- /dev/null +++ b/src/schema.rs | |||
@@ -0,0 +1,223 @@ | |||
1 | // Common types used across API | ||
2 | |||
3 | use chrono::{NaiveDate, NaiveDateTime}; | ||
4 | use serde::{Deserialize, Serialize}; | ||
5 | use std::sync::Arc; | ||
6 | use tokio::sync::Mutex; | ||
7 | |||
8 | // use crate::validators; | ||
9 | |||
10 | pub fn ledger() -> Db { | ||
11 | // TODO: there was something simpler in one of the other tutorials? <07-04-21, yigit> // | ||
12 | |||
13 | Arc::new(Mutex::new(vec![ | ||
14 | Transaction { | ||
15 | source: String::from("Myself"), | ||
16 | target: String::from("Nobody"), | ||
17 | amount: 4, | ||
18 | timestamp: NaiveDate::from_ymd(2021, 4, 7).and_hms(00, 17, 00), | ||
19 | }, | ||
20 | ])) | ||
21 | } | ||
22 | |||
23 | |||
24 | // For presentation purposes keep mocked data in in-memory structure | ||
25 | // In real life scenario connection with regular database would be established | ||
26 | |||
27 | pub type Db = Arc<Mutex<Vec<Transaction>>>; | ||
28 | |||
29 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
30 | pub struct Transaction { | ||
31 | pub source: String, | ||
32 | pub target: String, | ||
33 | pub amount: i32, | ||
34 | pub timestamp: NaiveDateTime, | ||
35 | } | ||
36 | |||
37 | #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
38 | pub struct Block { | ||
39 | pub transaction_list: Vec<Transaction>, // [Transaction; N] | ||
40 | pub nonce: i32, | ||
41 | pub timestamp: NaiveDateTime, | ||
42 | pub hash: String, // future proof'd baby | ||
43 | } | ||
44 | |||
45 | // #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
46 | // #[serde(rename_all = "camelCase")] | ||
47 | // pub struct Game { | ||
48 | // pub id: u64, | ||
49 | // pub title: String, | ||
50 | // #[serde(with = "validators::validate_game_rating")] | ||
51 | // pub rating: u8, | ||
52 | // pub genre: Genre, | ||
53 | // pub description: Option<String>, | ||
54 | // pub release_date: NaiveDateTime, | ||
55 | // } | ||
56 | |||
57 | // #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] | ||
58 | // #[serde(rename_all = "SCREAMING_SNAKE_CASE")] | ||
59 | // pub enum Genre { | ||
60 | // RolePlaying, | ||
61 | // Strategy, | ||
62 | // Shooter, | ||
63 | // } | ||
64 | |||
65 | // #[derive(Deserialize, Debug, PartialEq)] | ||
66 | // pub struct ListOptions { | ||
67 | // pub offset: Option<usize>, | ||
68 | // pub limit: Option<usize>, | ||
69 | // } | ||
70 | |||
71 | // pub fn example_db() -> Db { | ||
72 | // Arc::new(Mutex::new( | ||
73 | // vec![ | ||
74 | // Game { | ||
75 | // id: 1, | ||
76 | // title: String::from("Dark Souls"), | ||
77 | // rating: 91, | ||
78 | // genre: Genre::RolePlaying, | ||
79 | // description: Some(String::from("Takes place in the fictional kingdom of Lordran, where players assume the role of a cursed undead character who begins a pilgrimage to discover the fate of their kind.")), | ||
80 | // release_date: NaiveDate::from_ymd(2011, 9, 22).and_hms(0, 0, 0), | ||
81 | // }, | ||
82 | // Game { | ||
83 | // id: 2, | ||
84 | // title: String::from("Dark Souls 2"), | ||
85 | // rating: 87, | ||
86 | // genre: Genre::RolePlaying, | ||
87 | // description: None, | ||
88 | // release_date: NaiveDate::from_ymd(2014, 3, 11).and_hms(0, 0, 0), | ||
89 | // }, | ||
90 | // Game { | ||
91 | // id: 3, | ||
92 | // title: String::from("Dark Souls 3"), | ||
93 | // rating: 89, | ||
94 | // genre: Genre::RolePlaying, | ||
95 | // description: Some(String::from("The latest chapter in the series with its trademark sword and sorcery combat and rewarding action RPG gameplay.")), | ||
96 | // release_date: NaiveDate::from_ymd(2016, 3, 24).and_hms(0, 0, 0), | ||
97 | // }, | ||
98 | // ] | ||
99 | // )) | ||
100 | // } | ||
101 | |||
102 | // #[cfg(test)] | ||
103 | // mod tests { | ||
104 | // use super::*; | ||
105 | |||
106 | // use serde_json::error::Error; | ||
107 | // use serde_test::{assert_tokens, Token}; | ||
108 | |||
109 | // #[test] | ||
110 | // fn game_serialize_correctly() { | ||
111 | // let game = Game { | ||
112 | // id: 1, | ||
113 | // title: String::from("Test"), | ||
114 | // rating: 90, | ||
115 | // genre: Genre::Shooter, | ||
116 | // description: None, | ||
117 | // release_date: NaiveDate::from_ymd(2019, 11, 12).and_hms(0, 0, 0), | ||
118 | // }; | ||
119 | |||
120 | // assert_tokens( | ||
121 | // &game, | ||
122 | // &[ | ||
123 | // Token::Struct { | ||
124 | // name: "Game", | ||
125 | // len: 6, | ||
126 | // }, | ||
127 | // Token::String("id"), | ||
128 | // Token::U64(1), | ||
129 | // Token::String("title"), | ||
130 | // Token::String("Test"), | ||
131 | // Token::String("rating"), | ||
132 | // Token::U8(90), | ||
133 | // Token::String("genre"), | ||
134 | // Token::UnitVariant { | ||
135 | // name: "Genre", | ||
136 | // variant: "SHOOTER", | ||
137 | // }, | ||
138 | // Token::String("description"), | ||
139 | // Token::None, | ||
140 | // Token::String("releaseDate"), | ||
141 | // Token::String("2019-11-12T00:00:00"), | ||
142 | // Token::StructEnd, | ||
143 | // ], | ||
144 | // ); | ||
145 | // } | ||
146 | |||
147 | // #[test] | ||
148 | // fn game_deserialize_correctly() { | ||
149 | // let data = r#"{"id":3,"title":"Another game","rating":65,"genre":"STRATEGY","description":null,"releaseDate":"2016-03-11T00:00:00"}"#; | ||
150 | // let game: Game = serde_json::from_str(data).unwrap(); | ||
151 | // let expected_game = Game { | ||
152 | // id: 3, | ||
153 | // title: String::from("Another game"), | ||
154 | // rating: 65, | ||
155 | // genre: Genre::Strategy, | ||
156 | // description: None, | ||
157 | // release_date: NaiveDate::from_ymd(2016, 3, 11).and_hms(0, 0, 0), | ||
158 | // }; | ||
159 | |||
160 | // assert_eq!(game, expected_game); | ||
161 | // } | ||
162 | |||
163 | // #[test] | ||
164 | // fn game_error_when_wrong_rating_passed() { | ||
165 | // let data = r#"{"id":3,"title":"Another game","rating":120,"genre":"STRATEGY","description":null,"releaseDate":"2016-03-11T00:00:00"}"#; | ||
166 | // let err: Error = serde_json::from_str::<Game>(data).unwrap_err(); | ||
167 | |||
168 | // assert_eq!(err.is_data(), true); | ||
169 | // } | ||
170 | |||
171 | // #[test] | ||
172 | // fn genre_serialize_correctly() { | ||
173 | // let genre = Genre::Shooter; | ||
174 | // assert_tokens( | ||
175 | // &genre, | ||
176 | // &[Token::UnitVariant { | ||
177 | // name: "Genre", | ||
178 | // variant: "SHOOTER", | ||
179 | // }], | ||
180 | // ); | ||
181 | |||
182 | // let genre = Genre::RolePlaying; | ||
183 | // assert_tokens( | ||
184 | // &genre, | ||
185 | // &[Token::UnitVariant { | ||
186 | // name: "Genre", | ||
187 | // variant: "ROLE_PLAYING", | ||
188 | // }], | ||
189 | // ); | ||
190 | |||
191 | // let genre = Genre::Strategy; | ||
192 | // assert_tokens( | ||
193 | // &genre, | ||
194 | // &[Token::UnitVariant { | ||
195 | // name: "Genre", | ||
196 | // variant: "STRATEGY", | ||
197 | // }], | ||
198 | // ); | ||
199 | // } | ||
200 | |||
201 | // #[test] | ||
202 | // fn genre_deserialize_correctly() { | ||
203 | // let data = r#""SHOOTER""#; | ||
204 | // let genre: Genre = serde_json::from_str(data).unwrap(); | ||
205 | // let expected_genre = Genre::Shooter; | ||
206 | |||
207 | // assert_eq!(genre, expected_genre); | ||
208 | |||
209 | // let data = r#""ROLE_PLAYING""#; | ||
210 | // let genre: Genre = serde_json::from_str(data).unwrap(); | ||
211 | // let expected_genre = Genre::RolePlaying; | ||
212 | |||
213 | // assert_eq!(genre, expected_genre); | ||
214 | // } | ||
215 | |||
216 | // #[test] | ||
217 | // fn genre_error_when_wrong_rating_passed() { | ||
218 | // let data = r#""SPORT""#; | ||
219 | // let err: Error = serde_json::from_str::<Genre>(data).unwrap_err(); | ||
220 | |||
221 | // assert_eq!(err.is_data(), true); | ||
222 | // } | ||
223 | // } | ||