headless_lms_server/domain/oauth/
resource_indicator.rs1use serde::{Deserialize, Deserializer, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
6#[serde(transparent)]
7pub struct ResourceIndicator(String);
8
9impl ResourceIndicator {
10 pub fn new(resource: &str) -> Self {
12 Self(resource.trim_end_matches('/').to_string())
13 }
14
15 pub fn as_str(&self) -> &str {
17 &self.0
18 }
19}
20
21impl<'de> Deserialize<'de> for ResourceIndicator {
22 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
23 String::deserialize(deserializer).map(|resource| Self::new(&resource))
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30
31 #[test]
32 fn trailing_slashes_are_dropped() {
33 assert_eq!(
34 ResourceIndicator::new("https://example.com/api/v0/mcp/").as_str(),
35 "https://example.com/api/v0/mcp"
36 );
37 }
38}