1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11#[allow(unused_imports)]
12use core::marker::PhantomData;
13use jacquard_common::CowStr;
14
15#[allow(unused_imports)]
16use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
17use jacquard_common::types::collection::{Collection, RecordError};
18use jacquard_common::types::string::{AtUri, Cid, Datetime};
19use jacquard_common::types::uri::{RecordUri, UriError};
20use jacquard_common::xrpc::XrpcResp;
21use jacquard_derive::{IntoStatic, lexicon};
22use jacquard_lexicon::lexicon::LexiconDoc;
23use jacquard_lexicon::schema::LexiconSchema;
24
25#[allow(unused_imports)]
26use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
27use serde::{Serialize, Deserialize};
28use crate::app_bsky::richtext::facet::Facet;
29
30#[lexicon]
31#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
32#[serde(
33 rename_all = "camelCase",
34 rename = "network.slices.tools.bug.response",
35 tag = "$type"
36)]
37pub struct Response<'a> {
38 #[serde(borrow)]
40 pub bug: AtUri<'a>,
41 pub created_at: Datetime,
42 #[serde(skip_serializing_if = "Option::is_none")]
44 #[serde(borrow)]
45 pub message: Option<CowStr<'a>>,
46 #[serde(skip_serializing_if = "Option::is_none")]
48 #[serde(borrow)]
49 pub message_facets: Option<Vec<Facet<'a>>>,
50 #[serde(borrow)]
51 pub status: ResponseStatus<'a>,
52}
53
54
55#[derive(Debug, Clone, PartialEq, Eq, Hash)]
56pub enum ResponseStatus<'a> {
57 Acknowledged,
58 Fixed,
59 Wontfix,
60 Duplicate,
61 Invalid,
62 Other(CowStr<'a>),
63}
64
65impl<'a> ResponseStatus<'a> {
66 pub fn as_str(&self) -> &str {
67 match self {
68 Self::Acknowledged => "acknowledged",
69 Self::Fixed => "fixed",
70 Self::Wontfix => "wontfix",
71 Self::Duplicate => "duplicate",
72 Self::Invalid => "invalid",
73 Self::Other(s) => s.as_ref(),
74 }
75 }
76}
77
78impl<'a> From<&'a str> for ResponseStatus<'a> {
79 fn from(s: &'a str) -> Self {
80 match s {
81 "acknowledged" => Self::Acknowledged,
82 "fixed" => Self::Fixed,
83 "wontfix" => Self::Wontfix,
84 "duplicate" => Self::Duplicate,
85 "invalid" => Self::Invalid,
86 _ => Self::Other(CowStr::from(s)),
87 }
88 }
89}
90
91impl<'a> From<String> for ResponseStatus<'a> {
92 fn from(s: String) -> Self {
93 match s.as_str() {
94 "acknowledged" => Self::Acknowledged,
95 "fixed" => Self::Fixed,
96 "wontfix" => Self::Wontfix,
97 "duplicate" => Self::Duplicate,
98 "invalid" => Self::Invalid,
99 _ => Self::Other(CowStr::from(s)),
100 }
101 }
102}
103
104impl<'a> core::fmt::Display for ResponseStatus<'a> {
105 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
106 write!(f, "{}", self.as_str())
107 }
108}
109
110impl<'a> AsRef<str> for ResponseStatus<'a> {
111 fn as_ref(&self) -> &str {
112 self.as_str()
113 }
114}
115
116impl<'a> serde::Serialize for ResponseStatus<'a> {
117 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
118 where
119 S: serde::Serializer,
120 {
121 serializer.serialize_str(self.as_str())
122 }
123}
124
125impl<'de, 'a> serde::Deserialize<'de> for ResponseStatus<'a>
126where
127 'de: 'a,
128{
129 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
130 where
131 D: serde::Deserializer<'de>,
132 {
133 let s = <&'de str>::deserialize(deserializer)?;
134 Ok(Self::from(s))
135 }
136}
137
138impl<'a> Default for ResponseStatus<'a> {
139 fn default() -> Self {
140 Self::Other(Default::default())
141 }
142}
143
144impl jacquard_common::IntoStatic for ResponseStatus<'_> {
145 type Output = ResponseStatus<'static>;
146 fn into_static(self) -> Self::Output {
147 match self {
148 ResponseStatus::Acknowledged => ResponseStatus::Acknowledged,
149 ResponseStatus::Fixed => ResponseStatus::Fixed,
150 ResponseStatus::Wontfix => ResponseStatus::Wontfix,
151 ResponseStatus::Duplicate => ResponseStatus::Duplicate,
152 ResponseStatus::Invalid => ResponseStatus::Invalid,
153 ResponseStatus::Other(v) => ResponseStatus::Other(v.into_static()),
154 }
155 }
156}
157
158#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
161#[serde(rename_all = "camelCase")]
162pub struct ResponseGetRecordOutput<'a> {
163 #[serde(skip_serializing_if = "Option::is_none")]
164 #[serde(borrow)]
165 pub cid: Option<Cid<'a>>,
166 #[serde(borrow)]
167 pub uri: AtUri<'a>,
168 #[serde(borrow)]
169 pub value: Response<'a>,
170}
171
172impl<'a> Response<'a> {
173 pub fn uri(
174 uri: impl Into<CowStr<'a>>,
175 ) -> Result<RecordUri<'a, ResponseRecord>, UriError> {
176 RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
177 }
178}
179
180#[derive(Debug, Serialize, Deserialize)]
183pub struct ResponseRecord;
184impl XrpcResp for ResponseRecord {
185 const NSID: &'static str = "network.slices.tools.bug.response";
186 const ENCODING: &'static str = "application/json";
187 type Output<'de> = ResponseGetRecordOutput<'de>;
188 type Err<'de> = RecordError<'de>;
189}
190
191impl From<ResponseGetRecordOutput<'_>> for Response<'_> {
192 fn from(output: ResponseGetRecordOutput<'_>) -> Self {
193 use jacquard_common::IntoStatic;
194 output.value.into_static()
195 }
196}
197
198impl Collection for Response<'_> {
199 const NSID: &'static str = "network.slices.tools.bug.response";
200 type Record = ResponseRecord;
201}
202
203impl Collection for ResponseRecord {
204 const NSID: &'static str = "network.slices.tools.bug.response";
205 type Record = ResponseRecord;
206}
207
208impl<'a> LexiconSchema for Response<'a> {
209 fn nsid() -> &'static str {
210 "network.slices.tools.bug.response"
211 }
212 fn def_name() -> &'static str {
213 "main"
214 }
215 fn lexicon_doc() -> LexiconDoc<'static> {
216 lexicon_doc_network_slices_tools_bug_response()
217 }
218 fn validate(&self) -> Result<(), ConstraintError> {
219 if let Some(ref value) = self.message {
220 #[allow(unused_comparisons)]
221 if <str>::len(value.as_ref()) > 3000usize {
222 return Err(ConstraintError::MaxLength {
223 path: ValidationPath::from_field("message"),
224 max: 3000usize,
225 actual: <str>::len(value.as_ref()),
226 });
227 }
228 }
229 if let Some(ref value) = self.message {
230 {
231 let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
232 if count > 1000usize {
233 return Err(ConstraintError::MaxGraphemes {
234 path: ValidationPath::from_field("message"),
235 max: 1000usize,
236 actual: count,
237 });
238 }
239 }
240 }
241 Ok(())
242 }
243}
244
245pub mod response_state {
246
247 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
248 #[allow(unused)]
249 use ::core::marker::PhantomData;
250 mod sealed {
251 pub trait Sealed {}
252 }
253 pub trait State: sealed::Sealed {
255 type Bug;
256 type Status;
257 type CreatedAt;
258 }
259 pub struct Empty(());
261 impl sealed::Sealed for Empty {}
262 impl State for Empty {
263 type Bug = Unset;
264 type Status = Unset;
265 type CreatedAt = Unset;
266 }
267 pub struct SetBug<S: State = Empty>(PhantomData<fn() -> S>);
269 impl<S: State> sealed::Sealed for SetBug<S> {}
270 impl<S: State> State for SetBug<S> {
271 type Bug = Set<members::bug>;
272 type Status = S::Status;
273 type CreatedAt = S::CreatedAt;
274 }
275 pub struct SetStatus<S: State = Empty>(PhantomData<fn() -> S>);
277 impl<S: State> sealed::Sealed for SetStatus<S> {}
278 impl<S: State> State for SetStatus<S> {
279 type Bug = S::Bug;
280 type Status = Set<members::status>;
281 type CreatedAt = S::CreatedAt;
282 }
283 pub struct SetCreatedAt<S: State = Empty>(PhantomData<fn() -> S>);
285 impl<S: State> sealed::Sealed for SetCreatedAt<S> {}
286 impl<S: State> State for SetCreatedAt<S> {
287 type Bug = S::Bug;
288 type Status = S::Status;
289 type CreatedAt = Set<members::created_at>;
290 }
291 #[allow(non_camel_case_types)]
293 pub mod members {
294 pub struct bug(());
296 pub struct status(());
298 pub struct created_at(());
300 }
301}
302
303pub struct ResponseBuilder<'a, S: response_state::State> {
305 _state: PhantomData<fn() -> S>,
306 _fields: (
307 Option<AtUri<'a>>,
308 Option<Datetime>,
309 Option<CowStr<'a>>,
310 Option<Vec<Facet<'a>>>,
311 Option<ResponseStatus<'a>>,
312 ),
313 _lifetime: PhantomData<&'a ()>,
314}
315
316impl<'a> Response<'a> {
317 pub fn new() -> ResponseBuilder<'a, response_state::Empty> {
319 ResponseBuilder::new()
320 }
321}
322
323impl<'a> ResponseBuilder<'a, response_state::Empty> {
324 pub fn new() -> Self {
326 ResponseBuilder {
327 _state: PhantomData,
328 _fields: (None, None, None, None, None),
329 _lifetime: PhantomData,
330 }
331 }
332}
333
334impl<'a, S> ResponseBuilder<'a, S>
335where
336 S: response_state::State,
337 S::Bug: response_state::IsUnset,
338{
339 pub fn bug(
341 mut self,
342 value: impl Into<AtUri<'a>>,
343 ) -> ResponseBuilder<'a, response_state::SetBug<S>> {
344 self._fields.0 = Option::Some(value.into());
345 ResponseBuilder {
346 _state: PhantomData,
347 _fields: self._fields,
348 _lifetime: PhantomData,
349 }
350 }
351}
352
353impl<'a, S> ResponseBuilder<'a, S>
354where
355 S: response_state::State,
356 S::CreatedAt: response_state::IsUnset,
357{
358 pub fn created_at(
360 mut self,
361 value: impl Into<Datetime>,
362 ) -> ResponseBuilder<'a, response_state::SetCreatedAt<S>> {
363 self._fields.1 = Option::Some(value.into());
364 ResponseBuilder {
365 _state: PhantomData,
366 _fields: self._fields,
367 _lifetime: PhantomData,
368 }
369 }
370}
371
372impl<'a, S: response_state::State> ResponseBuilder<'a, S> {
373 pub fn message(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
375 self._fields.2 = value.into();
376 self
377 }
378 pub fn maybe_message(mut self, value: Option<CowStr<'a>>) -> Self {
380 self._fields.2 = value;
381 self
382 }
383}
384
385impl<'a, S: response_state::State> ResponseBuilder<'a, S> {
386 pub fn message_facets(mut self, value: impl Into<Option<Vec<Facet<'a>>>>) -> Self {
388 self._fields.3 = value.into();
389 self
390 }
391 pub fn maybe_message_facets(mut self, value: Option<Vec<Facet<'a>>>) -> Self {
393 self._fields.3 = value;
394 self
395 }
396}
397
398impl<'a, S> ResponseBuilder<'a, S>
399where
400 S: response_state::State,
401 S::Status: response_state::IsUnset,
402{
403 pub fn status(
405 mut self,
406 value: impl Into<ResponseStatus<'a>>,
407 ) -> ResponseBuilder<'a, response_state::SetStatus<S>> {
408 self._fields.4 = Option::Some(value.into());
409 ResponseBuilder {
410 _state: PhantomData,
411 _fields: self._fields,
412 _lifetime: PhantomData,
413 }
414 }
415}
416
417impl<'a, S> ResponseBuilder<'a, S>
418where
419 S: response_state::State,
420 S::Bug: response_state::IsSet,
421 S::Status: response_state::IsSet,
422 S::CreatedAt: response_state::IsSet,
423{
424 pub fn build(self) -> Response<'a> {
426 Response {
427 bug: self._fields.0.unwrap(),
428 created_at: self._fields.1.unwrap(),
429 message: self._fields.2,
430 message_facets: self._fields.3,
431 status: self._fields.4.unwrap(),
432 extra_data: Default::default(),
433 }
434 }
435 pub fn build_with_data(
437 self,
438 extra_data: BTreeMap<
439 jacquard_common::deps::smol_str::SmolStr,
440 jacquard_common::types::value::Data<'a>,
441 >,
442 ) -> Response<'a> {
443 Response {
444 bug: self._fields.0.unwrap(),
445 created_at: self._fields.1.unwrap(),
446 message: self._fields.2,
447 message_facets: self._fields.3,
448 status: self._fields.4.unwrap(),
449 extra_data: Some(extra_data),
450 }
451 }
452}
453
454fn lexicon_doc_network_slices_tools_bug_response() -> LexiconDoc<'static> {
455 #[allow(unused_imports)]
456 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
457 use jacquard_lexicon::lexicon::*;
458 use alloc::collections::BTreeMap;
459 LexiconDoc {
460 lexicon: Lexicon::Lexicon1,
461 id: CowStr::new_static("network.slices.tools.bug.response"),
462 defs: {
463 let mut map = BTreeMap::new();
464 map.insert(
465 SmolStr::new_static("main"),
466 LexUserType::Record(LexRecord {
467 key: Some(CowStr::new_static("tid")),
468 record: LexRecordRecord::Object(LexObject {
469 required: Some(
470 vec![
471 SmolStr::new_static("bug"), SmolStr::new_static("status"),
472 SmolStr::new_static("createdAt")
473 ],
474 ),
475 properties: {
476 #[allow(unused_mut)]
477 let mut map = BTreeMap::new();
478 map.insert(
479 SmolStr::new_static("bug"),
480 LexObjectProperty::String(LexString {
481 description: Some(
482 CowStr::new_static("Reference to the bug report"),
483 ),
484 format: Some(LexStringFormat::AtUri),
485 ..Default::default()
486 }),
487 );
488 map.insert(
489 SmolStr::new_static("createdAt"),
490 LexObjectProperty::String(LexString {
491 format: Some(LexStringFormat::Datetime),
492 ..Default::default()
493 }),
494 );
495 map.insert(
496 SmolStr::new_static("message"),
497 LexObjectProperty::String(LexString {
498 description: Some(
499 CowStr::new_static("Optional explanation or link to fix"),
500 ),
501 max_length: Some(3000usize),
502 max_graphemes: Some(1000usize),
503 ..Default::default()
504 }),
505 );
506 map.insert(
507 SmolStr::new_static("messageFacets"),
508 LexObjectProperty::Array(LexArray {
509 description: Some(
510 CowStr::new_static(
511 "Annotations of message (mentions and links)",
512 ),
513 ),
514 items: LexArrayItem::Ref(LexRef {
515 r#ref: CowStr::new_static("app.bsky.richtext.facet"),
516 ..Default::default()
517 }),
518 ..Default::default()
519 }),
520 );
521 map.insert(
522 SmolStr::new_static("status"),
523 LexObjectProperty::String(LexString {
524 ..Default::default()
525 }),
526 );
527 map
528 },
529 ..Default::default()
530 }),
531 ..Default::default()
532 }),
533 );
534 map
535 },
536 ..Default::default()
537 }
538}