aiscript_directive/route/
mod.rs1use docs::Docs;
2use serde_json::Value;
3
4mod docs;
5use crate::{Directive, FromDirective};
6
7#[derive(Debug, Clone, Default)]
8pub struct RouteAnnotation {
9 pub auth: Auth,
10 pub docs: Option<Docs>,
11 pub sso_provider: Option<SsoProvider>,
12}
13
14#[derive(Debug, Copy, Clone, Default)]
15pub enum Auth {
16 Jwt,
17 Basic,
18 #[default]
19 None,
20}
21
22#[derive(Debug, Copy, Clone)]
23pub enum SsoProvider {
24 Facebook,
25 Google,
26 Discord,
27 GitHub,
28}
29
30impl SsoProvider {
31 pub fn as_str(&self) -> &'static str {
32 match self {
33 SsoProvider::Facebook => "facebook",
34 SsoProvider::Google => "google",
35 SsoProvider::Discord => "discord",
36 SsoProvider::GitHub => "github",
37 }
38 }
39}
40
41impl TryFrom<&String> for SsoProvider {
42 type Error = String;
43
44 fn try_from(value: &String) -> Result<Self, Self::Error> {
45 match value.as_ref() {
46 "facebook" => Ok(Self::Facebook),
47 "google" => Ok(Self::Google),
48 "discord" => Ok(Self::Discord),
49 "github" => Ok(Self::GitHub),
50 _ => Err(format!("Invalid SSO provider: `{value}`")),
51 }
52 }
53}
54
55impl RouteAnnotation {
56 pub fn is_auth_required(&self) -> bool {
57 match self.auth {
58 Auth::Jwt | Auth::Basic => true,
59 Auth::None => false,
60 }
61 }
62
63 pub fn is_jwt_auth(&self) -> bool {
64 matches!(self.auth, Auth::Jwt)
65 }
66
67 pub fn or(mut self, other: &RouteAnnotation) -> Self {
68 if matches!(self.auth, Auth::None) {
69 self.auth = other.auth;
70 }
71 if self.docs.is_none() {
72 self.docs = other.docs.clone()
73 }
74 self
75 }
76}
77
78impl FromDirective for Auth {
79 fn from_directive(directive: Directive) -> Result<Self, String> {
80 match directive.name.as_str() {
81 "auth" => Ok(Auth::Jwt),
82 "basic_auth" => Ok(Auth::Basic),
83 _ => Ok(Auth::None),
84 }
85 }
86}
87
88impl RouteAnnotation {
89 pub fn parse_directive(&mut self, directive: Directive) -> Result<(), String> {
90 match directive.name.as_str() {
91 "auth" | "basic_auth" => {
92 if matches!(self.auth, Auth::None) {
93 self.auth = Auth::from_directive(directive)?;
94 } else {
95 return Err("Duplicate auth directive".into());
96 }
97 }
98 "docs" => {
99 if self.docs.is_some() {
100 return Err("Duplicate @docs directive".into());
101 } else {
102 self.docs = Some(Docs::from_directive(directive)?);
103 }
104 }
105 "sso" => {
106 if let Some(Value::String(provider)) = directive.get_arg_value("provider") {
107 self.sso_provider = Some(SsoProvider::try_from(provider)?);
108 } else {
109 return Err("@sso required 'provider' argument.".into());
110 }
111 }
112 _ => {
113 return Err(format!("Invalid directive: @{}", directive.name));
114 }
115 }
116 Ok(())
117 }
118}