Skip to main content

jacquard_api/sh_weaver/edit/
diff.rs

1// @generated by jacquard-lexicon. DO NOT EDIT.
2//
3// Lexicon: sh.weaver.edit.diff
4//
5// This file was automatically generated from Lexicon schemas.
6// Any manual changes will be overwritten on the next regeneration.
7
8#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11#[allow(unused_imports)]
12use core::marker::PhantomData;
13use jacquard_common::CowStr;
14use jacquard_common::deps::bytes::Bytes;
15
16#[allow(unused_imports)]
17use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
18use jacquard_common::types::blob::BlobRef;
19use jacquard_common::types::collection::{Collection, RecordError};
20use jacquard_common::types::string::{AtUri, Cid, Datetime};
21use jacquard_common::types::uri::{RecordUri, UriError};
22use jacquard_common::xrpc::XrpcResp;
23use jacquard_derive::{IntoStatic, lexicon};
24use jacquard_lexicon::lexicon::LexiconDoc;
25use jacquard_lexicon::schema::LexiconSchema;
26
27#[allow(unused_imports)]
28use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
29use serde::{Serialize, Deserialize};
30use crate::com_atproto::repo::strong_ref::StrongRef;
31use crate::sh_weaver::edit::DocRef;
32/// An edit record for a notebook.
33
34#[lexicon]
35#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
36#[serde(rename_all = "camelCase", rename = "sh.weaver.edit.diff", tag = "$type")]
37pub struct Diff<'a> {
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub created_at: Option<Datetime>,
40    #[serde(borrow)]
41    pub doc: DocRef<'a>,
42    ///An inline diff for for small edit batches. Either this or snapshot must be present to be valid
43    #[serde(skip_serializing_if = "Option::is_none")]
44    #[serde(default, with = "jacquard_common::opt_serde_bytes_helper")]
45    pub inline_diff: Option<Bytes>,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    #[serde(borrow)]
48    pub prev: Option<StrongRef<'a>>,
49    #[serde(borrow)]
50    pub root: StrongRef<'a>,
51    ///Diff from previous diff. Either this or inlineDiff must be present to be valid
52    #[serde(skip_serializing_if = "Option::is_none")]
53    #[serde(borrow)]
54    pub snapshot: Option<BlobRef<'a>>,
55}
56
57/// Typed wrapper for GetRecord response with this collection's record type.
58
59#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
60#[serde(rename_all = "camelCase")]
61pub struct DiffGetRecordOutput<'a> {
62    #[serde(skip_serializing_if = "Option::is_none")]
63    #[serde(borrow)]
64    pub cid: Option<Cid<'a>>,
65    #[serde(borrow)]
66    pub uri: AtUri<'a>,
67    #[serde(borrow)]
68    pub value: Diff<'a>,
69}
70
71impl<'a> Diff<'a> {
72    pub fn uri(
73        uri: impl Into<CowStr<'a>>,
74    ) -> Result<RecordUri<'a, DiffRecord>, UriError> {
75        RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
76    }
77}
78
79/// Marker type for deserializing records from this collection.
80
81#[derive(Debug, Serialize, Deserialize)]
82pub struct DiffRecord;
83impl XrpcResp for DiffRecord {
84    const NSID: &'static str = "sh.weaver.edit.diff";
85    const ENCODING: &'static str = "application/json";
86    type Output<'de> = DiffGetRecordOutput<'de>;
87    type Err<'de> = RecordError<'de>;
88}
89
90impl From<DiffGetRecordOutput<'_>> for Diff<'_> {
91    fn from(output: DiffGetRecordOutput<'_>) -> Self {
92        use jacquard_common::IntoStatic;
93        output.value.into_static()
94    }
95}
96
97impl Collection for Diff<'_> {
98    const NSID: &'static str = "sh.weaver.edit.diff";
99    type Record = DiffRecord;
100}
101
102impl Collection for DiffRecord {
103    const NSID: &'static str = "sh.weaver.edit.diff";
104    type Record = DiffRecord;
105}
106
107impl<'a> LexiconSchema for Diff<'a> {
108    fn nsid() -> &'static str {
109        "sh.weaver.edit.diff"
110    }
111    fn def_name() -> &'static str {
112        "main"
113    }
114    fn lexicon_doc() -> LexiconDoc<'static> {
115        lexicon_doc_sh_weaver_edit_diff()
116    }
117    fn validate(&self) -> Result<(), ConstraintError> {
118        if let Some(ref value) = self.snapshot {
119            {
120                let size = value.blob().size;
121                if size > 3000000usize {
122                    return Err(ConstraintError::BlobTooLarge {
123                        path: ValidationPath::from_field("snapshot"),
124                        max: 3000000usize,
125                        actual: size,
126                    });
127                }
128            }
129        }
130        if let Some(ref value) = self.snapshot {
131            {
132                let mime = value.blob().mime_type.as_str();
133                let accepted: &[&str] = &["*/*"];
134                let matched = accepted
135                    .iter()
136                    .any(|pattern| {
137                        if *pattern == "*/*" {
138                            true
139                        } else if pattern.ends_with("/*") {
140                            let prefix = &pattern[..pattern.len() - 2];
141                            mime.starts_with(prefix)
142                                && mime.as_bytes().get(prefix.len()) == Some(&b'/')
143                        } else {
144                            mime == *pattern
145                        }
146                    });
147                if !matched {
148                    return Err(ConstraintError::BlobMimeTypeNotAccepted {
149                        path: ValidationPath::from_field("snapshot"),
150                        accepted: vec!["*/*".to_string()],
151                        actual: mime.to_string(),
152                    });
153                }
154            }
155        }
156        Ok(())
157    }
158}
159
160pub mod diff_state {
161
162    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
163    #[allow(unused)]
164    use ::core::marker::PhantomData;
165    mod sealed {
166        pub trait Sealed {}
167    }
168    /// State trait tracking which required fields have been set
169    pub trait State: sealed::Sealed {
170        type Root;
171        type Doc;
172    }
173    /// Empty state - all required fields are unset
174    pub struct Empty(());
175    impl sealed::Sealed for Empty {}
176    impl State for Empty {
177        type Root = Unset;
178        type Doc = Unset;
179    }
180    ///State transition - sets the `root` field to Set
181    pub struct SetRoot<S: State = Empty>(PhantomData<fn() -> S>);
182    impl<S: State> sealed::Sealed for SetRoot<S> {}
183    impl<S: State> State for SetRoot<S> {
184        type Root = Set<members::root>;
185        type Doc = S::Doc;
186    }
187    ///State transition - sets the `doc` field to Set
188    pub struct SetDoc<S: State = Empty>(PhantomData<fn() -> S>);
189    impl<S: State> sealed::Sealed for SetDoc<S> {}
190    impl<S: State> State for SetDoc<S> {
191        type Root = S::Root;
192        type Doc = Set<members::doc>;
193    }
194    /// Marker types for field names
195    #[allow(non_camel_case_types)]
196    pub mod members {
197        ///Marker type for the `root` field
198        pub struct root(());
199        ///Marker type for the `doc` field
200        pub struct doc(());
201    }
202}
203
204/// Builder for constructing an instance of this type
205pub struct DiffBuilder<'a, S: diff_state::State> {
206    _state: PhantomData<fn() -> S>,
207    _fields: (
208        Option<Datetime>,
209        Option<DocRef<'a>>,
210        Option<Bytes>,
211        Option<StrongRef<'a>>,
212        Option<StrongRef<'a>>,
213        Option<BlobRef<'a>>,
214    ),
215    _lifetime: PhantomData<&'a ()>,
216}
217
218impl<'a> Diff<'a> {
219    /// Create a new builder for this type
220    pub fn new() -> DiffBuilder<'a, diff_state::Empty> {
221        DiffBuilder::new()
222    }
223}
224
225impl<'a> DiffBuilder<'a, diff_state::Empty> {
226    /// Create a new builder with all fields unset
227    pub fn new() -> Self {
228        DiffBuilder {
229            _state: PhantomData,
230            _fields: (None, None, None, None, None, None),
231            _lifetime: PhantomData,
232        }
233    }
234}
235
236impl<'a, S: diff_state::State> DiffBuilder<'a, S> {
237    /// Set the `createdAt` field (optional)
238    pub fn created_at(mut self, value: impl Into<Option<Datetime>>) -> Self {
239        self._fields.0 = value.into();
240        self
241    }
242    /// Set the `createdAt` field to an Option value (optional)
243    pub fn maybe_created_at(mut self, value: Option<Datetime>) -> Self {
244        self._fields.0 = value;
245        self
246    }
247}
248
249impl<'a, S> DiffBuilder<'a, S>
250where
251    S: diff_state::State,
252    S::Doc: diff_state::IsUnset,
253{
254    /// Set the `doc` field (required)
255    pub fn doc(
256        mut self,
257        value: impl Into<DocRef<'a>>,
258    ) -> DiffBuilder<'a, diff_state::SetDoc<S>> {
259        self._fields.1 = Option::Some(value.into());
260        DiffBuilder {
261            _state: PhantomData,
262            _fields: self._fields,
263            _lifetime: PhantomData,
264        }
265    }
266}
267
268impl<'a, S: diff_state::State> DiffBuilder<'a, S> {
269    /// Set the `inlineDiff` field (optional)
270    pub fn inline_diff(mut self, value: impl Into<Option<Bytes>>) -> Self {
271        self._fields.2 = value.into();
272        self
273    }
274    /// Set the `inlineDiff` field to an Option value (optional)
275    pub fn maybe_inline_diff(mut self, value: Option<Bytes>) -> Self {
276        self._fields.2 = value;
277        self
278    }
279}
280
281impl<'a, S: diff_state::State> DiffBuilder<'a, S> {
282    /// Set the `prev` field (optional)
283    pub fn prev(mut self, value: impl Into<Option<StrongRef<'a>>>) -> Self {
284        self._fields.3 = value.into();
285        self
286    }
287    /// Set the `prev` field to an Option value (optional)
288    pub fn maybe_prev(mut self, value: Option<StrongRef<'a>>) -> Self {
289        self._fields.3 = value;
290        self
291    }
292}
293
294impl<'a, S> DiffBuilder<'a, S>
295where
296    S: diff_state::State,
297    S::Root: diff_state::IsUnset,
298{
299    /// Set the `root` field (required)
300    pub fn root(
301        mut self,
302        value: impl Into<StrongRef<'a>>,
303    ) -> DiffBuilder<'a, diff_state::SetRoot<S>> {
304        self._fields.4 = Option::Some(value.into());
305        DiffBuilder {
306            _state: PhantomData,
307            _fields: self._fields,
308            _lifetime: PhantomData,
309        }
310    }
311}
312
313impl<'a, S: diff_state::State> DiffBuilder<'a, S> {
314    /// Set the `snapshot` field (optional)
315    pub fn snapshot(mut self, value: impl Into<Option<BlobRef<'a>>>) -> Self {
316        self._fields.5 = value.into();
317        self
318    }
319    /// Set the `snapshot` field to an Option value (optional)
320    pub fn maybe_snapshot(mut self, value: Option<BlobRef<'a>>) -> Self {
321        self._fields.5 = value;
322        self
323    }
324}
325
326impl<'a, S> DiffBuilder<'a, S>
327where
328    S: diff_state::State,
329    S::Root: diff_state::IsSet,
330    S::Doc: diff_state::IsSet,
331{
332    /// Build the final struct
333    pub fn build(self) -> Diff<'a> {
334        Diff {
335            created_at: self._fields.0,
336            doc: self._fields.1.unwrap(),
337            inline_diff: self._fields.2,
338            prev: self._fields.3,
339            root: self._fields.4.unwrap(),
340            snapshot: self._fields.5,
341            extra_data: Default::default(),
342        }
343    }
344    /// Build the final struct with custom extra_data
345    pub fn build_with_data(
346        self,
347        extra_data: BTreeMap<
348            jacquard_common::deps::smol_str::SmolStr,
349            jacquard_common::types::value::Data<'a>,
350        >,
351    ) -> Diff<'a> {
352        Diff {
353            created_at: self._fields.0,
354            doc: self._fields.1.unwrap(),
355            inline_diff: self._fields.2,
356            prev: self._fields.3,
357            root: self._fields.4.unwrap(),
358            snapshot: self._fields.5,
359            extra_data: Some(extra_data),
360        }
361    }
362}
363
364fn lexicon_doc_sh_weaver_edit_diff() -> LexiconDoc<'static> {
365    #[allow(unused_imports)]
366    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
367    use jacquard_lexicon::lexicon::*;
368    use alloc::collections::BTreeMap;
369    LexiconDoc {
370        lexicon: Lexicon::Lexicon1,
371        id: CowStr::new_static("sh.weaver.edit.diff"),
372        defs: {
373            let mut map = BTreeMap::new();
374            map.insert(
375                SmolStr::new_static("main"),
376                LexUserType::Record(LexRecord {
377                    description: Some(
378                        CowStr::new_static("An edit record for a notebook."),
379                    ),
380                    key: Some(CowStr::new_static("tid")),
381                    record: LexRecordRecord::Object(LexObject {
382                        required: Some(
383                            vec![SmolStr::new_static("root"), SmolStr::new_static("doc")],
384                        ),
385                        properties: {
386                            #[allow(unused_mut)]
387                            let mut map = BTreeMap::new();
388                            map.insert(
389                                SmolStr::new_static("createdAt"),
390                                LexObjectProperty::String(LexString {
391                                    format: Some(LexStringFormat::Datetime),
392                                    ..Default::default()
393                                }),
394                            );
395                            map.insert(
396                                SmolStr::new_static("doc"),
397                                LexObjectProperty::Ref(LexRef {
398                                    r#ref: CowStr::new_static("sh.weaver.edit.defs#docRef"),
399                                    ..Default::default()
400                                }),
401                            );
402                            map.insert(
403                                SmolStr::new_static("inlineDiff"),
404                                LexObjectProperty::Bytes(LexBytes {
405                                    max_length: Some(8192usize),
406                                    ..Default::default()
407                                }),
408                            );
409                            map.insert(
410                                SmolStr::new_static("prev"),
411                                LexObjectProperty::Ref(LexRef {
412                                    r#ref: CowStr::new_static("com.atproto.repo.strongRef"),
413                                    ..Default::default()
414                                }),
415                            );
416                            map.insert(
417                                SmolStr::new_static("root"),
418                                LexObjectProperty::Ref(LexRef {
419                                    r#ref: CowStr::new_static("com.atproto.repo.strongRef"),
420                                    ..Default::default()
421                                }),
422                            );
423                            map.insert(
424                                SmolStr::new_static("snapshot"),
425                                LexObjectProperty::Blob(LexBlob { ..Default::default() }),
426                            );
427                            map
428                        },
429                        ..Default::default()
430                    }),
431                    ..Default::default()
432                }),
433            );
434            map
435        },
436        ..Default::default()
437    }
438}