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 = "instance-of")]
61    InstanceOf,
62
63    #[serde(rename = "instantiation")]
64    Instantiation,
65}
66
67/// Arbitrary instances for property-based testing.
68#[cfg(feature = "property-tests")]
69pub(crate) mod arbitrary {
70    use super::*;
71    use proptest::prelude::*;
72
73    impl Arbitrary for LinkType {
74        type Parameters = ();
75        type Strategy = BoxedStrategy<Self>;
76
77        fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
78            proptest::sample::select(&[
79                LinkType::AnalysisOf,
80                LinkType::DiagramIn,
81                LinkType::InstanceOf,
82                LinkType::Instantiation,
83            ])
84            .boxed()
85        }
86    }
87
88    impl Arbitrary for StableRef {
89        type Parameters = ();
90        type Strategy = BoxedStrategy<Self>;
91
92        fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
93            (any::<String>(), proptest::option::of(any::<String>()), any::<String>())
94                .prop_map(|(id, version, server)| StableRef { id, version, server })
95                .boxed()
96        }
97    }
98
99    impl Arbitrary for Link {
100        type Parameters = ();
101        type Strategy = BoxedStrategy<Self>;
102
103        fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
104            (any::<StableRef>(), any::<LinkType>())
105                .prop_map(|(stable_ref, r#type)| Link { stable_ref, r#type })
106                .boxed()
107        }
108    }
109}