Skip to main content

maincopy_shared/
lib.rs

1//! Wire contracts shared by Maincopy's server and operator client.
2
3pub mod auth;
4pub mod auth_api;
5pub mod posts;
6pub mod profile;
7pub mod profile_api;
8pub mod publication;
9pub mod source;
10
11use serde::{Deserialize, Serialize};
12
13/// Stable path for discovering the private admin contracts supported by a server.
14pub const ADMIN_CAPABILITIES_PATH: &str = "/api/admin/capabilities";
15
16/// Versioned path for discovering the V1 private admin contract.
17pub const CAPABILITIES_PATH: &str = "/api/admin/v1/capabilities";
18
19/// Admin API versions understood by this contract crate.
20#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
21#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
22pub enum AdminApiVersion {
23    #[serde(rename = "v1")]
24    V1,
25}
26
27/// Versions of the currently advertised admin features.
28#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
29#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
30pub struct FeatureVersions {
31    pub capabilities: CapabilityContractVersion,
32}
33
34/// Versions of the capabilities response contract.
35#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
36#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
37pub enum CapabilityContractVersion {
38    #[serde(rename = "v1")]
39    V1,
40}
41
42/// Feature contract versions supported by one running Maincopy server.
43#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
44#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
45pub struct SupportedFeatureContracts {
46    pub capabilities: Vec<CapabilityContractVersion>,
47}
48
49/// Version-neutral discovery contract for one running Maincopy server.
50#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
51#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
52pub struct AdminApiCapabilities {
53    pub api_versions: Vec<AdminApiVersion>,
54    pub feature_contracts: SupportedFeatureContracts,
55}
56
57/// Contract versions supported by one running Maincopy server.
58#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
59#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
60pub struct Capabilities {
61    pub api_version: AdminApiVersion,
62    pub features: FeatureVersions,
63}
64
65#[cfg(test)]
66mod tests {
67    use serde_json::json;
68
69    use super::*;
70
71    #[test]
72    fn admin_api_capabilities_have_a_stable_bidirectional_wire_contract() {
73        let capabilities = AdminApiCapabilities {
74            api_versions: vec![AdminApiVersion::V1],
75            feature_contracts: SupportedFeatureContracts {
76                capabilities: vec![CapabilityContractVersion::V1],
77            },
78        };
79
80        let value = serde_json::to_value(&capabilities).unwrap();
81        assert_eq!(
82            value,
83            json!({
84                "api_versions": ["v1"],
85                "feature_contracts": { "capabilities": ["v1"] }
86            })
87        );
88        assert_eq!(
89            serde_json::from_value::<AdminApiCapabilities>(value).unwrap(),
90            capabilities
91        );
92    }
93
94    #[test]
95    fn capabilities_have_a_stable_bidirectional_wire_contract() {
96        let capabilities = Capabilities {
97            api_version: AdminApiVersion::V1,
98            features: FeatureVersions {
99                capabilities: CapabilityContractVersion::V1,
100            },
101        };
102
103        let value = serde_json::to_value(capabilities).unwrap();
104        assert_eq!(
105            value,
106            json!({
107                "api_version": "v1",
108                "features": { "capabilities": "v1" }
109            })
110        );
111        assert_eq!(
112            serde_json::from_value::<Capabilities>(value).unwrap(),
113            capabilities
114        );
115    }
116}