rust_mcp_sdk/auth/spec/
audience.rs

1use core::fmt;
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use serde_json::Value;
5
6/// Represents the audience claim, which can be a single string or a list of strings.
7#[derive(Debug, Clone)]
8pub enum Audience {
9    Single(String),
10    Multiple(Vec<String>),
11}
12
13impl Audience {
14    /// Converts the audience to a `Vec<String>` for uniform access.
15    pub fn to_vec(&self) -> Vec<String> {
16        match self {
17            Audience::Single(s) => vec![s.clone()],
18            Audience::Multiple(v) => v.clone(),
19        }
20    }
21}
22
23impl fmt::Display for Audience {
24    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25        match self {
26            Audience::Single(s) => write!(f, "{s}"),
27            Audience::Multiple(v) => {
28                let formatted = v.join(", ");
29                write!(f, "{formatted}")
30            }
31        }
32    }
33}
34
35impl PartialEq for Audience {
36    fn eq(&self, other: &Self) -> bool {
37        self.to_vec() == other.to_vec()
38    }
39}
40
41impl Eq for Audience {}
42
43impl Serialize for Audience {
44    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
45    where
46        S: Serializer,
47    {
48        match self {
49            // Serialize a single string directly as a JSON string
50            Audience::Single(s) => serializer.serialize_str(s),
51            // Serialize multiple strings as a JSON array
52            Audience::Multiple(v) => serializer.collect_seq(v),
53        }
54    }
55}
56
57impl<'de> Deserialize<'de> for Audience {
58    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59    where
60        D: Deserializer<'de>,
61    {
62        // Use a Value to handle both string and array cases
63        let value = Value::deserialize(deserializer)?;
64        match value {
65            Value::String(s) => Ok(Audience::Single(s)),
66            Value::Array(arr) => {
67                let strings = arr
68                    .into_iter()
69                    .map(|v| match v {
70                        Value::String(s) => Ok(s),
71                        _ => Err(serde::de::Error::custom(
72                            "audience array must contain strings",
73                        )),
74                    })
75                    .collect::<Result<Vec<String>, D::Error>>()?;
76                Ok(Audience::Multiple(strings))
77            }
78            _ => Err(serde::de::Error::custom(
79                "audience must be a string or an array of strings",
80            )),
81        }
82    }
83}
84
85// Allow converting from &str
86impl From<&str> for Audience {
87    fn from(s: &str) -> Self {
88        Audience::Single(s.to_string())
89    }
90}
91
92// Allow converting from String
93impl From<String> for Audience {
94    fn from(s: String) -> Self {
95        Audience::Single(s)
96    }
97}
98
99// Allow converting from Vec<String>
100impl From<Vec<String>> for Audience {
101    fn from(v: Vec<String>) -> Self {
102        Audience::Multiple(v)
103    }
104}
105
106// Allow converting from Vec<&str> for convenience
107impl From<Vec<&str>> for Audience {
108    fn from(v: Vec<&str>) -> Self {
109        Audience::Multiple(v.into_iter().map(|s| s.to_string()).collect())
110    }
111}