-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprogress.rs
98 lines (85 loc) · 2.25 KB
/
progress.rs
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
91
92
93
94
95
96
97
98
use futures::StreamExt;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::HashMap;
use stream_flatten_iters::TryStreamExt;
use vila::pagination::{
query::{QueryModifier, QueryPaginator},
PaginatedRequest,
};
use vila::{Client, Request, RequestData};
#[derive(Clone)]
struct Data {
page: usize,
}
impl From<Data> for QueryModifier {
fn from(s: Data) -> QueryModifier {
let mut data = HashMap::new();
data.insert("page".into(), s.page.to_string());
QueryModifier { data }
}
}
#[derive(Serialize)]
struct GetPassengers {
size: usize,
page: Option<usize>,
}
#[derive(Deserialize, Debug)]
struct Passenger {
name: Option<String>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct PassengersWrapper {
total_passengers: usize,
total_pages: usize,
data: Vec<Passenger>,
}
impl Request for GetPassengers {
type Data = Self;
type Response = PassengersWrapper;
fn endpoint(&self) -> Cow<str> {
"/v1/passenger".into()
}
fn data(&self) -> RequestData<&Self> {
RequestData::Query(self)
}
}
impl PaginatedRequest for GetPassengers {
type Data = Data;
type Paginator = QueryPaginator<Self::Response, Data>;
fn initial_page(&self) -> Option<Data> {
self.page.map(|page| Data { page })
}
fn paginator(&self) -> Self::Paginator {
QueryPaginator::new(|prev: Option<&Data>, res: &PassengersWrapper| {
let max_page = res.total_pages;
match prev {
None => Some(Data { page: 1 }),
Some(x) => {
if x.page == max_page {
None
} else {
Some(Data { page: x.page + 1 })
}
}
}
})
}
}
#[tokio::main]
pub async fn main() {
env_logger::init();
let client = Client::new("https://api.instantwebtools.net").show_progress();
let req = GetPassengers {
page: None,
size: 1,
};
client
.send_paginated(&req)
.map(|maybe_wrapper| maybe_wrapper.map(|wrapper| wrapper.data))
.try_flatten_iters()
.take(50)
.for_each(|_| async move {})
.await;
}