catcolab_document_types/v0/
api.rs

1use serde::{Deserialize, Serialize};
2use tsify::Tsify;
3
4/// A stable reference to a document in the database.
5///
6/// Such a reference identifies a specific document, possibly at a specific
7/// version. The keys are prefixed with an underscore, e.g. `_id` instead of
8/// `id`, to avoid conflicts with other keys and unambiguously signal that the
9/// data occur at the *database* level, rather than merely the *document* level.
10/// The same convention is used in document databases like CouchDB and MongoDB.
11#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Tsify)]
12#[tsify(into_wasm_abi, from_wasm_abi)]
13#[tsify(missing_as_null)]
14pub struct StableRef {
15    /// Unique identifier of the referenced document.
16    ///
17    /// When using CatColab's official backend, this should be a document ref ID
18    /// (a UUID).
19    #[serde(rename = "_id")]
20    pub id: String,
21
22    /// Version of the document.
23    ///
24    /// If null, refers to the head commit of document. This is the case when
25    /// the referenced document will receive live updates.
26    #[serde(rename = "_version")]
27    pub version: Option<String>,
28
29    /// Server containing the document.
30    ///
31    /// Assuming one of the official deployments is used, this will be either
32    /// `catcolab.org` or `next.catcolab.org`.
33    #[serde(rename = "_server")]
34    pub server: String,
35}
36
37/// A link from one document to another.
38///
39/// The source of the link is the document containing this data and the target
40/// of link is given by the data itself.
41#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Tsify)]
42#[tsify(into_wasm_abi, from_wasm_abi)]
43pub struct Link {
44    #[serde(flatten)]
45    pub stable_ref: StableRef,
46
47    pub r#type: LinkType,
48}
49
50/// Type of link between documents.
51#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Tsify)]
52#[tsify(into_wasm_abi, from_wasm_abi)]
53pub enum LinkType {
54    #[serde(rename = "analysis-of")]
55    AnalysisOf,
56
57    #[serde(rename = "diagram-in")]
58    DiagramIn,
59
60    #[serde(rename = "instantiation")]
61    Instantiation,
62}
63
64/// Arbitrary instances for property-based testing.
65#[cfg(feature = "property-tests")]
66pub(crate) mod arbitrary {
67    use super::*;
68    use proptest::prelude::*;
69
70    impl Arbitrary for LinkType {
71        type Parameters = ();
72        type Strategy = BoxedStrategy<Self>;
73
74        fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
75            proptest::sample::select(&[
76                LinkType::AnalysisOf,
77                LinkType::DiagramIn,
78                LinkType::Instantiation,
79            ])
80            .boxed()
81        }
82    }
83
84    impl Arbitrary for StableRef {
85        type Parameters = ();
86        type Strategy = BoxedStrategy<Self>;
87
88        fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
89            (any::<String>(), proptest::option::of(any::<String>()), any::<String>())
90                .prop_map(|(id, version, server)| StableRef { id, version, server })
91                .boxed()
92        }
93    }
94
95    impl Arbitrary for Link {
96        type Parameters = ();
97        type Strategy = BoxedStrategy<Self>;
98
99        fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
100            (any::<StableRef>(), any::<LinkType>())
101                .prop_map(|(stable_ref, r#type)| Link { stable_ref, r#type })
102                .boxed()
103        }
104    }
105}