Skip to main content

twitch_oauth2/
types.rs

1#![allow(clippy::extra_unused_lifetimes)]
2//! Types used in OAUTH2 flow.
3
4use std::fmt;
5
6use base64::Engine;
7
8/// A Client Id
9#[aliri_braid::braid(serde)]
10pub struct ClientId;
11
12/// A Client Secret
13#[aliri_braid::braid(display = "owned", debug = "owned", serde)]
14pub struct ClientSecret;
15
16impl fmt::Debug for ClientSecretRef {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        f.write_str("[redacted client secret]")
19    }
20}
21impl fmt::Display for ClientSecretRef {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        f.write_str("[redacted client secret]")
24    }
25}
26
27/// An Access Token
28#[aliri_braid::braid(display = "owned", debug = "owned", serde)]
29pub struct AccessToken;
30
31impl fmt::Debug for AccessTokenRef {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        f.write_str("[redacted access token]")
34    }
35}
36impl fmt::Display for AccessTokenRef {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        f.write_str("[redacted access token]")
39    }
40}
41
42/// A Refresh Token
43#[aliri_braid::braid(display = "owned", debug = "owned", serde)]
44pub struct RefreshToken;
45
46impl fmt::Debug for RefreshTokenRef {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        f.write_str("[redacted refresh token]")
49    }
50}
51impl fmt::Display for RefreshTokenRef {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        f.write_str("[redacted refresh token]")
54    }
55}
56
57/// A Csrf Token
58#[aliri_braid::braid(display = "owned", debug = "owned", serde)]
59pub struct CsrfToken;
60
61impl fmt::Debug for CsrfTokenRef {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        f.write_str("[redacted csrf token]")
64    }
65}
66impl fmt::Display for CsrfTokenRef {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        f.write_str("[redacted csrf token]")
69    }
70}
71
72impl CsrfToken {
73    /// Make a new random CSRF token.
74    pub fn new_random() -> CsrfToken { Self::new_random_len(16) }
75
76    /// Make a new random CSRF token with given amount of bytes
77    pub fn new_random_len(len: u32) -> CsrfToken {
78        use rand::RngExt as _;
79
80        let mut random_bytes = vec![0u8; len as usize];
81        rand::rng().fill(&mut random_bytes);
82        CsrfToken::new(base64::engine::general_purpose::STANDARD.encode(random_bytes))
83    }
84}
85
86impl ClientSecretRef {
87    /// Get the secret from this string.
88    ///
89    /// This function is the same as [`ClientSecret::as_str`](ClientSecretRef::as_str), but has another name for searchability, prefer to use this function.
90    pub fn secret(&self) -> &str { self.as_str() }
91}
92
93impl AccessTokenRef {
94    /// Get the secret from this string.
95    ///
96    /// This function is the same as [`AccessToken::as_str`](AccessTokenRef::as_str), but has another name for searchability, prefer to use this function.
97    pub fn secret(&self) -> &str { self.as_str() }
98}
99impl RefreshTokenRef {
100    /// Get the secret from this string.
101    ///
102    /// This function is the same as [`RefreshToken::as_str`](RefreshTokenRef::as_str), but has another name for searchability, prefer to use this function.
103    pub fn secret(&self) -> &str { self.as_str() }
104}
105impl CsrfTokenRef {
106    /// Get the secret from this string.
107    ///
108    /// This function is the same as [`CsrfToken::as_str`](CsrfTokenRef::as_str), but has another name for searchability, prefer to use this function.
109    pub fn secret(&self) -> &str { self.as_str() }
110}