Skip to main content

dsc/api/
models.rs

1use serde::{Deserialize, Serialize};
2
3/// Response payload for site.json.
4#[derive(Debug, Deserialize)]
5pub struct SiteResponse {
6    pub site: SiteInfo,
7}
8
9/// Site metadata.
10#[derive(Debug, Deserialize)]
11pub struct SiteInfo {
12    pub title: String,
13}
14
15/// Response payload for about.json.
16#[derive(Debug, Deserialize)]
17pub struct AboutResponse {
18    pub about: AboutInfo,
19}
20
21/// About metadata.
22#[derive(Debug, Deserialize)]
23pub struct AboutInfo {
24    pub version: Option<String>,
25    pub installed_version: Option<String>,
26}
27
28/// Response payload for topic JSON.
29#[derive(Debug, Deserialize)]
30pub struct TopicResponse {
31    #[serde(default)]
32    pub title: Option<String>,
33    #[serde(default)]
34    pub slug: Option<String>,
35    pub post_stream: PostStream,
36}
37
38/// Topic post stream.
39#[derive(Debug, Deserialize, Default)]
40pub struct PostStream {
41    #[serde(default)]
42    pub posts: Vec<Post>,
43    /// Flat array of every post ID in the topic. Discourse includes this
44    /// on the first-page response only. Used to paginate the rest of the
45    /// thread via the batch-fetch endpoint.
46    #[serde(default)]
47    pub stream: Vec<u64>,
48}
49
50/// Topic post.
51#[derive(Debug, Deserialize)]
52pub struct Post {
53    pub id: u64,
54    #[serde(default)]
55    pub post_number: Option<u64>,
56    #[serde(default)]
57    pub username: Option<String>,
58    #[serde(default)]
59    pub raw: Option<String>,
60    #[serde(default)]
61    pub updated_at: Option<String>,
62    #[serde(default)]
63    pub created_at: Option<String>,
64}
65
66#[derive(Debug, Deserialize, Serialize)]
67pub struct CustomEmoji {
68    pub name: String,
69    pub url: String,
70}
71
72/// Response payload for category JSON.
73#[derive(Debug, Deserialize)]
74pub struct CategoryResponse {
75    #[serde(default)]
76    pub category: Option<CategoryInfo>,
77    pub topic_list: TopicList,
78}
79
80/// Category metadata.
81#[derive(Debug, Deserialize, Serialize, Clone)]
82pub struct CategoryInfo {
83    pub name: String,
84    pub slug: String,
85    #[serde(default)]
86    pub color: Option<String>,
87    #[serde(default)]
88    pub text_color: Option<String>,
89    pub id: Option<u64>,
90    #[serde(default)]
91    pub subcategory_list: Vec<CategoryInfo>,
92    #[serde(default)]
93    pub parent_category_id: Option<u64>,
94}
95
96/// One group's permission on a category, as returned in `group_permissions`.
97/// `permission_type`: 1 = full, 2 = create_post, 3 = readonly.
98#[derive(Debug, Deserialize, Serialize, Clone)]
99pub struct GroupPermission {
100    #[serde(default)]
101    pub group_name: Option<String>,
102    pub permission_type: u8,
103}
104
105/// The full definition of a category (from `/categories.json?show_permissions=true`).
106///
107/// Distinct from the sparse [`CategoryInfo`] used by `category list`: this carries
108/// the definition surface (description, permissions, topic template, tag rules,
109/// ordering) that `category def pull/push` and `category show/get/set` operate on.
110/// Every field beyond `name` is optional so partial payloads still deserialize.
111#[derive(Debug, Deserialize, Serialize, Clone, Default)]
112pub struct CategoryDefinition {
113    #[serde(default)]
114    pub id: Option<u64>,
115    pub name: String,
116    #[serde(default)]
117    pub slug: Option<String>,
118    #[serde(default)]
119    pub color: Option<String>,
120    #[serde(default)]
121    pub text_color: Option<String>,
122    #[serde(default)]
123    pub position: Option<i64>,
124    #[serde(default)]
125    pub parent_category_id: Option<u64>,
126    #[serde(default)]
127    pub read_restricted: Option<bool>,
128    #[serde(default)]
129    pub description: Option<String>,
130    /// Plain-text form of `description`. `description` itself is the *cooked*
131    /// excerpt of the category's auto-created "About" topic (HTML, and settles
132    /// asynchronously after creation), so definition sync reads this instead for
133    /// a stable, idempotent round-trip.
134    #[serde(default)]
135    pub description_text: Option<String>,
136    #[serde(default)]
137    pub topic_template: Option<String>,
138    #[serde(default)]
139    pub group_permissions: Option<Vec<GroupPermission>>,
140    #[serde(default)]
141    pub allowed_tags: Option<Vec<String>>,
142    #[serde(default)]
143    pub allowed_tag_groups: Option<Vec<String>>,
144    #[serde(default)]
145    pub minimum_required_tags: Option<u64>,
146    #[serde(default)]
147    pub sort_order: Option<String>,
148    #[serde(default)]
149    pub default_view: Option<String>,
150    #[serde(default)]
151    pub subcategory_list_style: Option<String>,
152    #[serde(default)]
153    pub num_featured_topics: Option<u64>,
154    #[serde(default)]
155    pub show_subcategory_list: Option<bool>,
156}
157
158/// Response payload for `/categories.json?show_permissions=true`.
159#[derive(Debug, Deserialize)]
160pub struct CategoryDefinitionsResponse {
161    pub category_list: CategoryDefinitionList,
162}
163
164/// Category definition listing.
165#[derive(Debug, Deserialize)]
166pub struct CategoryDefinitionList {
167    pub categories: Vec<CategoryDefinition>,
168}
169
170/// Response payload for categories.json.
171#[derive(Debug, Deserialize)]
172pub struct CategoriesResponse {
173    pub category_list: CategoryList,
174}
175
176/// Category listing.
177#[derive(Debug, Deserialize)]
178pub struct CategoryList {
179    pub categories: Vec<CategoryInfo>,
180}
181
182/// Topic list for a category.
183#[derive(Debug, Deserialize)]
184pub struct TopicList {
185    pub topics: Vec<TopicSummary>,
186}
187
188/// Topic summary.
189#[derive(Debug, Deserialize, Serialize)]
190pub struct TopicSummary {
191    pub id: u64,
192    pub title: String,
193    pub slug: String,
194}
195
196/// Group summary.
197#[derive(Debug, Deserialize, Serialize, Clone)]
198pub struct GroupSummary {
199    pub id: u64,
200    pub name: String,
201    #[serde(default)]
202    pub full_name: Option<String>,
203}
204
205/// Response payload for groups.json.
206#[derive(Debug, Deserialize)]
207pub struct GroupsResponse {
208    pub groups: Vec<GroupSummary>,
209}
210
211#[derive(Debug, Deserialize, Serialize, Clone)]
212pub struct GroupMember {
213    pub id: u64,
214    pub username: String,
215    #[serde(default)]
216    pub name: Option<String>,
217}
218
219#[derive(Debug, Deserialize)]
220pub struct GroupMembersResponse {
221    pub members: Vec<GroupMember>,
222}
223
224/// Response payload for group detail.
225#[derive(Debug, Deserialize)]
226pub struct GroupDetailResponse {
227    pub group: GroupDetail,
228}
229
230/// Group details with settings used for deep-copy.
231#[derive(Debug, Deserialize, Serialize, Clone)]
232pub struct GroupDetail {
233    pub id: u64,
234    pub name: String,
235    #[serde(default)]
236    pub full_name: Option<String>,
237    #[serde(default)]
238    pub title: Option<String>,
239    #[serde(default)]
240    pub grant_trust_level: Option<u64>,
241    #[serde(default)]
242    pub visibility_level: Option<u64>,
243    #[serde(default)]
244    pub mentionable_level: Option<u64>,
245    #[serde(default)]
246    pub messageable_level: Option<u64>,
247    #[serde(default)]
248    pub default_notification_level: Option<u64>,
249    #[serde(default)]
250    pub members_visibility_level: Option<u64>,
251    #[serde(default)]
252    pub primary_group: Option<bool>,
253    #[serde(default)]
254    pub public_admission: Option<bool>,
255    #[serde(default)]
256    pub public_exit: Option<bool>,
257    #[serde(default)]
258    pub allow_membership_requests: Option<bool>,
259    #[serde(default)]
260    pub automatic_membership_email_domains: Option<String>,
261    #[serde(default)]
262    pub automatic_membership_retroactive: Option<bool>,
263    #[serde(default)]
264    pub membership_request_template: Option<String>,
265    #[serde(default)]
266    pub flair_icon: Option<String>,
267    #[serde(default)]
268    pub flair_upload_id: Option<u64>,
269    #[serde(default)]
270    pub flair_color: Option<String>,
271    #[serde(default)]
272    pub flair_background_color: Option<String>,
273    #[serde(default)]
274    pub bio_raw: Option<String>,
275}
276
277/// Response payload for creating a post/topic.
278#[derive(Debug, Deserialize)]
279pub struct CreatePostResponse {
280    pub id: u64,
281    pub topic_id: u64,
282}
283
284/// Response payload for creating a category.
285#[derive(Debug, Deserialize)]
286pub struct CreateCategoryResponse {
287    pub category: CreatedCategory,
288}
289
290/// Created category payload.
291#[derive(Debug, Deserialize)]
292pub struct CreatedCategory {
293    pub id: u64,
294}
295
296/// Response payload for creating a group.
297#[derive(Debug, Deserialize)]
298pub struct CreateGroupResponse {
299    pub group: CreatedGroup,
300}
301
302/// Created group payload.
303#[derive(Debug, Deserialize)]
304pub struct CreatedGroup {
305    pub id: u64,
306}