oauth2_core/device_authorization_grant/
device_authorization_response.rs1use core::time::Duration;
4
5use mime::Mime;
6use serde::{Deserialize, Serialize};
7use serde_json::{Map, Value};
8use url::Url;
9
10pub const CONTENT_TYPE: Mime = mime::APPLICATION_JSON;
11pub const INTERVAL_DEFAULT: usize = 5;
12pub type DeviceCode = String;
13pub type UserCode = String;
14pub type VerificationUri = Url;
15pub type VerificationUriComplete = Url;
16
17#[derive(Serialize, Deserialize, Debug, Clone)]
21pub struct SuccessfulBody {
22 pub device_code: DeviceCode,
23 pub user_code: UserCode,
24 #[serde(alias = "verification_url")]
26 pub verification_uri: VerificationUri,
27 #[serde(
28 alias = "verification_url_complete",
29 skip_serializing_if = "Option::is_none"
30 )]
31 pub verification_uri_complete: Option<VerificationUriComplete>,
32 pub expires_in: usize,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub interval: Option<usize>,
35
36 #[serde(flatten, skip_serializing_if = "Option::is_none")]
37 _extra: Option<Map<String, Value>>,
38}
39
40impl SuccessfulBody {
41 pub fn new(
42 device_code: DeviceCode,
43 user_code: UserCode,
44 verification_uri: VerificationUri,
45 verification_uri_complete: Option<VerificationUriComplete>,
46 expires_in: usize,
47 interval: Option<usize>,
48 ) -> Self {
49 Self {
50 device_code,
51 user_code,
52 verification_uri,
53 verification_uri_complete,
54 expires_in,
55 interval,
56 _extra: None,
57 }
58 }
59
60 pub fn interval(&self) -> Duration {
61 Duration::from_secs(self.interval.unwrap_or(INTERVAL_DEFAULT) as u64)
62 }
63
64 pub fn set_extra(&mut self, extra: Map<String, Value>) {
65 self._extra = Some(extra);
66 }
67 pub fn extra(&self) -> Option<&Map<String, Value>> {
68 self._extra.as_ref()
69 }
70}
71
72pub type ErrorBody = crate::access_token_response::ErrorBody;
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn de() {
83 let body_str = r#"
84 {
85 "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
86 "user_code": "WDJB-MJHT",
87 "verification_uri": "https://example.com/device",
88 "verification_uri_complete":
89 "https://example.com/device?user_code=WDJB-MJHT",
90 "expires_in": 1800,
91 "interval": 5
92 }
93 "#;
94 match serde_json::from_str::<SuccessfulBody>(body_str) {
95 Ok(_) => {}
96 Err(err) => panic!("{err}"),
97 }
98 }
99}