lcode_config/config/
user_nested.rs

1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4
5const START_SLASH: &str = "// start /";
6const END_SLASH: &str = "// end /";
7const START_HASH: &str = "## start #";
8const END_HASH: &str = "## end #";
9const START_DASH: &str = "-- start -";
10const END_DASH: &str = "-- end -";
11
12macro_rules! skipfmt {
13    ($($code:tt)*) => { $($code)* }
14}
15
16macro_rules! lang_macro {
17    ($($struct_name:ident), *) => {
18        paste::paste! {
19            #[derive(Clone)]
20            #[derive(Debug)]
21            #[derive(Default)]
22            #[derive(PartialEq, Eq)]
23            #[derive(Serialize, Deserialize)]
24            pub struct SupportLang {
25                $(
26                    #[serde(default)]
27                    pub [<$struct_name:lower>]: $struct_name,
28                )*
29            }
30        }
31        $(
32            #[derive(Clone)]
33            #[derive(Debug)]
34            #[derive(PartialEq, Eq)]
35            #[derive(Serialize, Deserialize)]
36            pub struct $struct_name {
37                pub start: String,
38                pub end: String,
39                pub inject_start: String,
40                pub inject_end: String,
41            }
42            impl $struct_name {
43                /// (`start`, `end`, `inject_start`, `inject_end`)
44                pub fn return_info(&self) -> (String, String, String, String) {
45                    (
46                        self.start.to_owned(),
47                        self.end.to_owned(),
48                        self.inject_start.to_owned(),
49                        self.inject_end.to_owned(),
50                    )
51                }
52            }
53        )*
54    };
55}
56lang_macro!(
57    Bash, C, Cpp, Csharp, Dart, Elixir, Erlang, Golang, Java, Javascript, Kotlin, Mssql, Mysql,
58    Oraclesql, Postgresql, Php, Python, Python3, Racket, React, Ruby, Rust, Scala, Swift,
59    Typescript
60);
61macro_rules! defaults {
62    ($lang:ident, $start:expr, $end:expr, $inject_start:expr, $inject_end:expr) => {
63        impl Default for $lang {
64            fn default() -> Self {
65                Self {
66                    start: $start.to_owned(),
67                    end: $end.to_owned(),
68                    inject_start: $inject_start.to_owned(),
69                    inject_end: $inject_end.to_owned(),
70                }
71            }
72        }
73    };
74    ($lang:ident, $start:expr, $end:expr, $inject_start:expr) => {
75        impl Default for $lang {
76            fn default() -> Self {
77                Self {
78                    start: $start.to_owned(),
79                    end: $end.to_owned(),
80                    inject_start: $inject_start.to_owned(),
81                    inject_end: String::new(),
82                }
83            }
84        }
85    };
86    ($lang:ident, $start:expr, $end:expr, $inject_end:expr) => {
87        impl Default for $lang {
88            fn default() -> Self {
89                Self {
90                    start: $start.to_owned(),
91                    end: $end.to_owned(),
92                    inject_start: String::new(),
93                    inject_end: $inject_end.to_owned(),
94                }
95            }
96        }
97    };
98    ($lang:ident, $start:expr, $end:expr) => {
99        impl Default for $lang {
100            fn default() -> Self {
101                Self {
102                    start: $start.to_owned(),
103                    end: $end.to_owned(),
104                    inject_start: String::new(),
105                    inject_end: String::new(),
106                }
107            }
108        }
109    };
110}
111
112skipfmt!(
113defaults!(C         , START_SLASH , END_SLASH);
114defaults!(Cpp       , START_SLASH , END_SLASH);
115defaults!(Csharp    , START_SLASH , END_SLASH);
116defaults!(Dart      , START_SLASH , END_SLASH);
117defaults!(Golang    , START_SLASH , END_SLASH);
118defaults!(Java      , START_SLASH , END_SLASH);
119defaults!(Javascript, START_SLASH , END_SLASH);
120defaults!(Kotlin    , START_SLASH , END_SLASH);
121defaults!(Php       , START_SLASH , END_SLASH);
122defaults!(React     , START_SLASH , END_SLASH);
123defaults!(Scala     , START_SLASH , END_SLASH);
124defaults!(Swift     , START_SLASH , END_SLASH);
125defaults!(Typescript, START_SLASH , END_SLASH);
126
127defaults!(Bash      , START_HASH  , END_HASH );
128defaults!(Elixir    , START_HASH  , END_HASH );
129defaults!(Python    , START_HASH  , END_HASH );
130defaults!(Python3   , START_HASH  , END_HASH );
131defaults!(Ruby      , START_HASH  , END_HASH );
132
133defaults!(Mssql     , START_DASH  , END_DASH );
134defaults!(Mysql     , START_DASH  , END_DASH );
135defaults!(Oraclesql , START_DASH  , END_DASH );
136defaults!(Postgresql, START_DASH  , END_DASH );
137
138defaults!(Racket    , ";; start ;", ";; end ;");
139defaults!(Erlang    , "%% start %", "%% end %");
140);
141
142defaults!(
143    Rust,
144    START_SLASH,
145    END_SLASH,
146    "struct Solution;\n",
147    "
148fn main() {
149    let res = Solution::function(todo!());
150    dbg!(&res);
151    assert_eq!(res, todo!());
152}"
153);
154
155#[derive(Clone)]
156#[derive(Debug)]
157#[derive(PartialEq, Eq)]
158#[derive(Serialize, Deserialize)]
159pub struct Urls {
160    pub origin: String,
161    pub question_url: String,
162    pub graphql: String,
163    pub all_problem_api: String,
164    pub submit: String,
165    pub test: String,
166    pub submissions: String,
167    pub favorites: String,
168    pub points: String,
169}
170#[derive(Clone, Copy)]
171#[derive(Debug)]
172#[derive(Default)]
173#[derive(PartialEq, Eq)]
174pub enum Suffix {
175    Cn,
176    #[default]
177    Com,
178}
179
180impl Display for Suffix {
181    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182        match self {
183            Self::Cn => "cn",
184            Self::Com => "com",
185        }
186        .fmt(f)
187    }
188}
189
190impl Urls {
191    pub fn new(suffix: Suffix) -> Self {
192        let suffix = match suffix {
193            Suffix::Cn => "cn",
194            Suffix::Com => "com",
195        };
196        Self {
197            origin: format!("https://leetcode.{}", suffix),
198            graphql: format!("https://leetcode.{}/graphql", suffix),
199            question_url: format!("https://leetcode.{}/problems/$slug/", suffix),
200            all_problem_api: format!("https://leetcode.{}/api/problems/$category", suffix),
201            submit: format!("https://leetcode.{}/problems/$slug/submit/", suffix),
202            test: format!(
203                "https://leetcode.{}/problems/$slug/interpret_solution/",
204                suffix
205            ),
206            submissions: format!("https://leetcode.{}/submissions/detail/$id/check/", suffix),
207            favorites: format!("https://leetcode.{}/list/api/questions", suffix),
208            points: format!("https://leetcode.{}/points/api/total/", suffix),
209        }
210    }
211
212    pub fn mod_all_pb_api(&self, category: &str) -> String {
213        self.all_problem_api
214            .replace("$category", category)
215    }
216
217    pub fn mod_submit(&self, slug: &str) -> String {
218        self.submit.replace("$slug", slug)
219    }
220
221    pub fn mod_test(&self, slug: &str) -> String {
222        self.test.replace("$slug", slug)
223    }
224
225    pub fn mod_submissions(&self, id: &str) -> String {
226        self.submissions.replace("$id", id)
227    }
228    pub fn get_qs_url(&self, slug: &str) -> String {
229        self.question_url.replace("$slug", slug)
230    }
231}
232
233impl Default for Urls {
234    fn default() -> Self {
235        Self::new(Suffix::default())
236    }
237}