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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct RfcGroup {
pub name: String,
#[serde(rename = "type")]
pub kind: String,
pub acronym: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct RfcAuthor {
pub name: String,
pub email: String,
pub affiliation: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct RfcRevision {
pub name: String,
pub rev: String,
pub published: DateTime<Utc>,
url: String,
}
impl RfcRevision {
pub fn url(&self) -> String {
format!("https://datatracker.ietf.org{}", self.url)
}
}
#[derive(Deserialize, Serialize, Debug)]
pub struct Rfc {
pub name: String,
pub rev: String,
pub pages: u32,
pub time: String,
pub group: RfcGroup,
pub expires: Option<String>,
pub title: String,
#[serde(rename = "abstract")]
pub description: String,
pub aliases: Vec<String>,
pub state: String,
pub intended_std_level: Option<String>,
pub std_level: String,
pub authors: Vec<RfcAuthor>,
pub shepherd: Option<String>,
pub ad: Option<String>,
pub iesg_state: String,
pub rfceditor_state: Option<String>,
pub iana_review_state: Option<String>,
pub iana_action_state: Option<String>,
pub stream: Option<String>,
}
impl Rfc {
pub fn get_txt_url(&self) -> String {
format!("https://www.rfc-editor.org/rfc/{}.txt", self.name)
}
pub fn get_pdf_url(&self) -> String {
format!("https://www.rfc-editor.org/rfc/{}.txt.pdf", self.name)
}
pub fn get_html_url(&self) -> String {
format!("https://www.rfc-editor.org/rfc/{}.html", self.name)
}
}
pub async fn query_rfc(number: u32) -> Result<Rfc, reqwest::Error> {
Ok(reqwest::get(format!(
"https://datatracker.ietf.org/doc/rfc{}/doc.json",
number
))
.await?
.json()
.await?)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_query_rfc_failure() {
tokio_test::block_on(async {
let rfc = query_rfc(9999999).await;
assert!(rfc.is_err());
})
}
}